/*
* Copyright 2012 Anton Van Zyl. http://code.google.com/p/java-swiss-knife/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* under the License.
*/
package com.knife.String;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CodingErrorAction;
import java.text.DecimalFormat;
import com.knife.Math.Math;
import com.knife.Math.exception.InvalidDataException;
/**
* Utility of String conversion functions.
*
* <br/>
* <br/>
* Please visit <a
* href="http://code.google.com/p/java-swiss-knife/">Java-Swiss-Knife</a> and
* comment, rate, contribute or raise a issue/enhancement for my library. <br/>
*
* @author Anton Van Zyl
*/
public final class StringConverterUtil {
/**
* Filter out all non-7-bit characters.
*
* @param inString
* @return filtered string
*/
public static String filterNonAscii(final String inString) throws CharacterCodingException {
// Create the encoder and decoder for the character encoding
Charset charset = Charset.forName("US-ASCII");
CharsetDecoder decoder = charset.newDecoder();
CharsetEncoder encoder = charset.newEncoder();
// This line is the key to removing "unmappable" characters.
encoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
String result = inString;
// Convert a string to bytes in a ByteBuffer
ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(inString));
// Convert bytes in a ByteBuffer to a character ByteBuffer and then to a
// string.
CharBuffer cbuf = decoder.decode(bbuf);
result = cbuf.toString();
return result;
}
/**
* Format cellphone number to the MSISDN format. If the international code
* is not specified ZA's a user entered country Code will be used.
*
* @param cellphoneNr
* @return MSISDN cellphone number format
*/
public static String cellphoneToMSISDNString(final String cellphoneNr, final String countryCode) {
String msisdn = cellphoneNr.replaceAll(" ", "");
if (msisdn.startsWith("+"))
msisdn = msisdn.substring(1);
else if (msisdn.startsWith("0")) {
msisdn = countryCode + msisdn.substring(1);
}
return msisdn;
}
/**
* Convert string to an HTML complaint string.
*
* @param input
* to convert
* @return the converted string
*/
public static String stringToHTMLString(final String input) throws NullPointerException {
if (input == null)
throw new NullPointerException("stringToHTMLString: input string is NULL");
StringBuilder sb = new StringBuilder();
int len = input.length();
char c;
for (int i = 0; i < len; i++) {
c = input.charAt(i);
// HTML Special Chars
if (c == '"')
sb.append(""");
else if (c == '&')
sb.append("&");
else if (c == '<')
sb.append("<");
else if (c == '>')
sb.append(">");
else {
int ci = 0xffff & c;
if (ci < 160)
// nothing special only 7 Bit
sb.append(c);
else {
// Not 7 Bit use the unicode system
System.out.println("Remove unicode character [value=" + String.valueOf(ci) + "]");
}
}
}
return sb.toString();
}
private static final String[] tensNames = { "", " Ten", " Twenty", " Thirty", " Forty", " Fifty", " Sixty", " Seventy", " Eighty", " Ninety" };
private static final String[] numNames = { "", " One", " Two", " Three", " Four", " Five", " Six", " Seven", " Eight", " Nine", " Ten", " Eleven", " Twelve", " Thirteen",
" Fourteen", " Fifteen", " Sixteen", " Seventeen", " Eighteen", " Nineteen" };
private static String convertLessThanOneThousand(int number, boolean addAndWord) {
String soFar;
if (number % 100 < 20) {
soFar = numNames[number % 100];
number /= 100;
} else {
soFar = numNames[number % 10];
number /= 10;
soFar = tensNames[number % 10] + soFar;
number /= 10;
}
if (number == 0 && addAndWord)
return "And" + soFar;
else if (number == 0)
return soFar;
if (addAndWord)
return numNames[number] + " Hundred And" + soFar;
else
return numNames[number] + " Hundred " + soFar;
}
/**
* This will convert a basic <code>long</code> to a English word. The
* algorithm allows a number range -999 999 999 999 to 999 999 999 999.
*
* @param number
* @return A word for a number
* @throws InvalidDataException
*/
public static String convertNUmberToWords(long number) throws InvalidDataException {
if (number == 0) {
return "Zero";
}
StringBuilder builder = new StringBuilder();
if (number < 0) {
number = Math.invertNumber(number);
builder.append("Minus");
}
String snumber = String.valueOf(number);
// pad with "0"
String mask = "000000000000";
DecimalFormat df = new DecimalFormat(mask);
snumber = df.format(number);
// XXXnnnnnnnnn
int billions = Integer.parseInt(snumber.substring(0, 3));
// nnnXXXnnnnnn
int millions = Integer.parseInt(snumber.substring(3, 6));
// nnnnnnXXXnnn
int hundredThousands = Integer.parseInt(snumber.substring(6, 9));
// nnnnnnnnnXXX
int thousands = Integer.parseInt(snumber.substring(9, 12));
// nnnnnnnnnnXX
int hundred = Integer.parseInt(snumber.substring(10, 12));
String tradBillions;
switch (billions) {
case 0:
tradBillions = "";
break;
case 1:
tradBillions = convertLessThanOneThousand(billions, false) + " Billion ";
break;
default:
tradBillions = convertLessThanOneThousand(billions, false) + " Billion ";
}
builder.append(tradBillions);
String tradMillions;
switch (millions) {
case 0:
tradMillions = "";
break;
case 1:
tradMillions = convertLessThanOneThousand(millions, false) + " Million ";
break;
default:
tradMillions = convertLessThanOneThousand(millions, false) + " Million ";
}
builder.append(tradMillions);
String tradHundredThousands;
switch (hundredThousands) {
case 0:
tradHundredThousands = "";
break;
case 1:
tradHundredThousands = "One Thousand ";
break;
default:
tradHundredThousands = convertLessThanOneThousand(hundredThousands, false) + " Thousand ";
}
builder.append(tradHundredThousands);
String tradThousand;
if (number > 100 && hundred > 0)
tradThousand = convertLessThanOneThousand(thousands, true);
else
tradThousand = convertLessThanOneThousand(thousands, false);
builder.append(tradThousand);
// remove extra spaces!
return builder.toString().replaceAll("^\\s+", "").replaceAll("\\b\\s{2,}\\b", " ");
}
}