/*
* StringUtil.java
*
* Copyright (C) 2005-2009 Tommi Laukkanen
* http://www.substanceofcode.com
*
* 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.
*/
package com.substanceofcode.utils;
import java.util.Vector;
import javax.microedition.lcdui.Font;
/**
*
* @author Tommi Laukkanen (tlaukkanen at gmail dot com)
*/
public class StringUtil {
/** Creates a new instance of StringUtil */
private StringUtil() {
}
/**
* Split string into multiple strings
* @param original Original string
* @param separator Separator string in original string
* @return Splitted string array
*/
public static String[] split(String original, String separator) {
Vector nodes = new Vector();
// Parse nodes into vector
int index = original.indexOf(separator);
while (index >= 0) {
nodes.addElement(original.substring(0, index));
original = original.substring(index + separator.length());
index = original.indexOf(separator);
}
// Get the last node
nodes.addElement(original);
// Create splitted string array
String[] result = new String[nodes.size()];
if (nodes.size() > 0) {
for (int loop = 0; loop < nodes.size(); loop++) {
result[loop] = (String) nodes.elementAt(loop);
}
}
return result;
}
/* Replace all instances of a String in a String.
* @param s String to alter.
* @param f String to look for.
* @param r String to replace it with, or null to just remove it.
*/
public static String replace(String s, String f, String r) {
if (s == null) {
return s;
}
if (f == null) {
return s;
}
if (r == null) {
r = "";
}
int index01 = s.indexOf(f);
while (index01 != -1) {
s = s.substring(0, index01) + r + s.substring(index01 + f.length());
index01 += r.length();
index01 = s.indexOf(f, index01);
}
return s;
}
/**
* Method removes HTML tags from given string.
*
* @param text Input parameter containing HTML tags (eg. <b>cat</b>)
* @return String without HTML tags (eg. cat)
*/
public static String removeHtml(String text) {
try {
int idx = text.indexOf("<");
if (idx == -1) {
text = decodeEntities(text);
return text;
}
String plainText = "";
String htmlText = text;
int htmlStartIndex = htmlText.indexOf("<", 0);
if (htmlStartIndex == -1) {
return text;
}
htmlText = StringUtil.replace(htmlText, "</p>", "\r\n");
htmlText = StringUtil.replace(htmlText, "<br/>", "\r\n");
htmlText = StringUtil.replace(htmlText, "<br>", "\r\n");
while (htmlStartIndex >= 0) {
plainText += htmlText.substring(0, htmlStartIndex);
int htmlEndIndex = htmlText.indexOf(">", htmlStartIndex);
htmlText = htmlText.substring(htmlEndIndex + 1);
htmlStartIndex = htmlText.indexOf("<", 0);
}
plainText = plainText.trim();
plainText = decodeEntities(plainText);
return plainText;
} catch (Exception e) {
Log.error("Error while removing HTML: " + e.toString());
return text;
}
}
private static String decodeEntities(String html) {
String result = StringUtil.replace(html, "<", "<");
result = StringUtil.replace(result, ">", ">");
result = StringUtil.replace(result, " ", " ");
result = StringUtil.replace(result, "&", "&");
result = StringUtil.replace(result, "ä", "ä");
result = StringUtil.replace(result, "ö", "ö");
result = StringUtil.replace(result, """, "'");
result = StringUtil.replace(result, "
", "\r");
return result;
}
/**
* <p>
* Takes an array of messages and a 'Screen-width' and returns the same
* messages, but any string in that that is wider than 'width' will be
* split up into 2 or more Strings that will fit on the screen
* </p>
*
* 'Spliting' up a String is done on the basis of Words, so if a single
* WORD is longer than 'width' it will be on a Line on it's own, but
* that line WILL be WIDER than 'width'
*
* @param message
* @param width
* the maximum width a string may be before being split
* up.
* @return
*/
public static String[] formatMessage(String[] message, int width, Font font) {
Vector result = new Vector(message.length);
for (int i = 0; i < message.length; i++) {
if (font.stringWidth(message[i]) <= width) {
result.addElement(message[i]);
} else {
String[] splitUp = StringUtil.chopStrings(message[i], " ", font, width);
for (int j = 0; j < splitUp.length; j++) {
result.addElement(splitUp[j]);
}
}
}
String[] finalResult = new String[result.size()];
for (int i = 0; i < finalResult.length; i++) {
finalResult[i] = (String) result.elementAt(i);
}
return finalResult;
}
/**
* Chops up the 'original' string into 1 or more strings which have a width <= 'width' when
* rasterized with the specified Font.
*
* The exception is if a single WORD is wider than 'width' in which case that word will be on its
* own, but it WILL still be longer than 'width'
*
* @param original The original String which is to be chopped up
* @param separator The delimiter for seperating words, this will usuall be the string " "(i.e. 1 space)
* @param font The font to use to determine the width of the words/Strings.
* @param width The maximum width a single string can be. (inclusive)
* @return The chopped up Strings, each smaller than 'width'
*/
public static String[] chopStrings(String origional, String separator, Font font, int width) {
final String[] words = split(origional, separator);
final Vector result = new Vector();
final StringBuffer currentLine = new StringBuffer();
String currentToken;
String sub1;
String sub2;
int currentWidth = 0;
for (int i = 0; i < words.length; i++) {
currentToken = words[i];
if (currentWidth == 0 || currentWidth + font.stringWidth(" " + currentToken) <= width) {
if (currentWidth == 0) {
if(font.stringWidth(currentToken)>width) {
/** Chop lines longer then screen width */
sub1 = currentToken;
System.out.println("oversize: " + sub1);
while(sub1.length()>0) {
for(int j=sub1.length()-1; j>=0; j--) {
sub2 = sub1.substring(0, j+1);
if(font.stringWidth(sub2)<=width) {
System.out.println("Add: " + sub2);
result.addElement(sub2);
sub1 = sub1.substring(j+1);
break;
}
}
}
} else {
currentLine.append(currentToken);
currentWidth += font.stringWidth(currentToken);
}
} else {
currentLine.append(' ').append(currentToken);
currentWidth += font.stringWidth(" " + currentToken);
}
} else {
result.addElement(currentLine.toString());
currentLine.delete(0, currentLine.length());
if(font.stringWidth(" " + currentToken)>width) {
/** Chop lines longer then screen width */
sub1 = currentToken;
//System.out.println("oversize: " + sub1);
while(sub1.length()>0) {
for(int j=sub1.length()-1; j>=0; j--) {
sub2 = sub1.substring(0, j+1);
if(font.stringWidth(sub2 + " ")<=width) {
//System.out.println("Add: " + sub2);
result.addElement(sub2);
sub1 = sub1.substring(j+1);
break;
}
}
}
} else {
currentLine.append(currentToken);
currentWidth = font.stringWidth(currentToken);
}
}
}
if (currentLine.length() != 0) {
String[] lines = split(currentLine.toString(), "\n");
for (int line = 0; line < lines.length; line++) {
result.addElement(lines[line]);
}
}
String[] finalResult = new String[result.size()];
for (int i = 0; i < finalResult.length; i++) {
finalResult[i] = (String) result.elementAt(i);
}
return finalResult;
}
/** URL encode given string */
public static String urlEncode(String s) {
if (s != null) {
StringBuffer tmp = new StringBuffer();
int i = 0;
try {
while (true) {
int b = (int) s.charAt(i++);
if ((b >= 0x30 && b <= 0x39) || (b >= 0x41 && b <= 0x5A) || (b >= 0x61 && b <= 0x7A)) {
tmp.append((char) b);
} else {
tmp.append("%");
if (b <= 0xf) {
tmp.append("0");
}
tmp.append(Integer.toHexString(b).toUpperCase());
}
}
} catch (Exception e) {
}
return tmp.toString();
}
return null;
}
}