/*
* This file is part of the Wayback archival access software
* (http://archive-access.sourceforge.net/projects/wayback/).
*
* Licensed to the Internet Archive (IA) by one or more individual
* contributors.
*
* The IA licenses this file to You 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 org.archive.wayback.util;
import java.text.DateFormat;
import java.text.Format;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.TimeZone;
import org.apache.commons.lang.StringEscapeUtils;
/**
* An class which assists in UI generation, primarily through Locale-aware
* String formatting, and also helps in escaping (hopefully properly) Strings
* for use in HTML.
*
* Note that date formatting done through this class forces all times to the
* UTC timezone - at the moment it appears too confusing to attempt to localize
* times in any other way..
*
* @author brad
* @version $Date$, $Revision$
*/
public class StringFormatter {
private final static TimeZone TZ_UTC = TimeZone.getTimeZone("UTC");
ResourceBundle bundle = null;
Locale locale = null;
Map<String,MessageFormat> formats = null;
/**
* Construct a StringFormatter...
* @param bundle ResourceBundle to lookup patterns for MessageFormat
* objects.
* @param locale to use, where applicable with MessageFormat objects
*/
public StringFormatter(ResourceBundle bundle) {
this(null,Locale.getDefault());
}
/**
* Construct a StringFormatter...
* @param bundle ResourceBundle to lookup patterns for MessageFormat
* objects.
* @param locale to use, where applicable with MessageFormat objects
*/
public StringFormatter(ResourceBundle bundle, Locale locale) {
this.bundle = bundle;
this.locale = locale;
formats = new HashMap<String,MessageFormat>();
}
public MessageFormat getFormat(String pattern) {
MessageFormat format = formats.get(pattern);
if(format == null) {
format = new MessageFormat(pattern,locale);
// lets try to make sure any internal DateFormats use UTC:
Format[] subFormats = format.getFormats();
if(subFormats != null) {
for(Format subFormat : subFormats) {
if(subFormat instanceof DateFormat) {
DateFormat subDateFormat = (DateFormat) subFormat;
subDateFormat.setTimeZone(TZ_UTC);
}
}
}
formats.put(pattern,format);
}
return format;
}
/**
* Access a localized string associated with key from the ResourceBundle,
* likely the UI.properties file.
* @param key to lookup in the ResourceBundle
* @return localized String version of key argument, or key itself if
* something goes wrong...
*/
public String getLocalized(String key) {
if(bundle != null) {
try {
return bundle.getString(key);
// String localized = bundle.getString(key);
// if((localized != null) && (localized.length() > 0)) {
// return localized;
// }
} catch (Exception e) {
}
}
return key;
}
private String formatInner(String key, Object objects[]) {
try {
return getFormat(getLocalized(key)).format(objects);
} catch (Exception e) {
// TODO: log message
//e.printStackTrace();
}
return key;
}
// What gives? This works in the Junit test, but not in jsps...
// /**
// * @param key String property name in UI.properties file to use as the
// * pattern for interpolation
// * @param objects array of things to interpolate within the MessageFormat
// * described by the pattern in UI.properties for key key
// * @return Localized Formatted String for key, interpolated with args
// */
// public String format(String key, Object...objects) {
// return formatInner(key,objects);
// }
/**
* Localize a string key from the UI.properties file
* @param key String property name in UI.properties file to use as the
* pattern for the MessageFormat
* @return Localized String for key
*/
public String format(String key) {
Object args[] = {};
return formatInner(key,args);
}
/**
* @param key String property name in UI.properties file to use as the
* pattern for interpolation
* @param o1 thing1 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @return Localized Formatted String for key, interpolated with argument objects
*/
public String format(String key,Object o1) {
Object args[] = {o1};
return formatInner(key,args);
}
/**
* @param key String property name in UI.properties file to use as the
* pattern for interpolation
* @param o1 thing1 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @param o2 thing2 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @return Localized Formatted String for key, interpolated with argument objects
*/
public String format(String key,Object o1,Object o2) {
Object args[] = {o1,o2};
return formatInner(key,args);
}
/**
* @param key String property name in UI.properties file to use as the
* pattern for interpolation
* @param o1 thing1 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @param o2 thing2 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @param o3 thing3 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @return Localized Formatted String for key, interpolated with argument objects
*/
public String format(String key,Object o1,Object o2,Object o3) {
Object args[] = {o1,o2,o3};
return formatInner(key,args);
}
/**
* @param key String property name in UI.properties file to use as the
* pattern for interpolation
* @param o1 thing1 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @param o2 thing2 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @param o3 thing3 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @param o4 thing4 to interpolate within the MessageFormat
* described by the pattern in UI.properties for key key
* @return Localized Formatted String for key, interpolated with argument objects
*/
public String format(String key,Object o1,Object o2,Object o3,Object o4) {
Object args[] = {o1,o2,o3,o4};
return formatInner(key,args);
}
/**
* handy shortcut to the apache StringEscapeUtils
* @param raw string to be escaped
* @return the string escaped so it's safe for insertion in HTML
*/
public String escapeHtml(String raw) {
return StringEscapeUtils.escapeHtml(raw);
}
/**
* handy shortcut to the apache StringEscapeUtils
* @param raw string to be escaped
* @return the string escaped so it's safe for insertion in Javascript
*/
public String escapeJavaScript(String raw) {
return StringEscapeUtils.escapeJavaScript(raw);
}
/**
* Convert... spaces to
* @param input to replace
* @return with spaces replaced
*/
public String spaceToNBSP(String input) {
return input.replaceAll(" ", " ");
}
public static String join(String delim, String...stuff) {
int max = stuff.length - 1;
int len = delim.length() * max;
for(String s : stuff) {
len += s.length();
}
StringBuilder sb = new StringBuilder(len);
for(int i = 0; i < stuff.length; i++) {
sb.append(stuff[i]);
if(i < max) {
sb.append(delim);
}
}
return sb.toString();
}
}