Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hook <dgh@cryptoworkshop.com>2013-05-31 11:07:45 +0400
committerDavid Hook <dgh@cryptoworkshop.com>2013-05-31 11:07:45 +0400
commit2b976f5364cfdbc37d3086019d93483c983eb80b (patch)
treecb846af3fd1d43f9c2562a1fb2d06b997ad8f229 /core/src/main/java/org/bouncycastle/i18n
parent5f714bd92fbd780d22406f4bc3681be005f6f04a (diff)
initial reshuffle
Diffstat (limited to 'core/src/main/java/org/bouncycastle/i18n')
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/ErrorBundle.java120
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/LocaleString.java24
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/LocalizedException.java49
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/LocalizedMessage.java476
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/MessageBundle.java92
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/MissingEntryException.java73
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/TextBundle.java92
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/filter/Filter.java21
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/filter/HTMLFilter.java68
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/filter/SQLFilter.java69
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/filter/TrustedInput.java23
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/filter/UntrustedInput.java44
-rw-r--r--core/src/main/java/org/bouncycastle/i18n/filter/UntrustedUrlInput.java14
13 files changed, 1165 insertions, 0 deletions
diff --git a/core/src/main/java/org/bouncycastle/i18n/ErrorBundle.java b/core/src/main/java/org/bouncycastle/i18n/ErrorBundle.java
new file mode 100644
index 00000000..415b5e57
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/ErrorBundle.java
@@ -0,0 +1,120 @@
+package org.bouncycastle.i18n;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class ErrorBundle extends MessageBundle
+{
+
+ /**
+ * summary entry key
+ */
+ public static final String SUMMARY_ENTRY = "summary";
+
+ /**
+ * detail entry key
+ */
+ public static final String DETAIL_ENTRY = "details";
+
+ /**
+ * Constructs a new ErrorBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ */
+ public ErrorBundle(String resource, String id) throws NullPointerException
+ {
+ super(resource, id);
+ }
+
+ /**
+ * Constructs a new ErrorBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param encoding the encoding of the resource file
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ */
+ public ErrorBundle(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException
+ {
+ super(resource, id, encoding);
+ }
+
+ /**
+ * Constructs a new ErrorBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param arguments an array containing the arguments for the message
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ */
+ public ErrorBundle(String resource, String id, Object[] arguments) throws NullPointerException
+ {
+ super(resource, id, arguments);
+ }
+
+ /**
+ * Constructs a new ErrorBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param encoding the encoding of the resource file
+ * @param arguments an array containing the arguments for the message
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ */
+ public ErrorBundle(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException
+ {
+ super(resource, id, encoding, arguments);
+ }
+
+ /**
+ * Returns the summary message in the given locale and timezone.
+ * @param loc the {@link Locale}
+ * @param timezone the {@link TimeZone}
+ * @return the summary message.
+ * @throws MissingEntryException if the message is not available
+ */
+ public String getSummary(Locale loc, TimeZone timezone) throws MissingEntryException
+ {
+ return getEntry(SUMMARY_ENTRY,loc,timezone);
+ }
+
+ /**
+ * Returns the summary message in the given locale and the default timezone.
+ * @param loc the {@link Locale}
+ * @return the summary message.
+ * @throws MissingEntryException if the message is not available
+ */
+ public String getSummary(Locale loc) throws MissingEntryException
+ {
+ return getEntry(SUMMARY_ENTRY,loc,TimeZone.getDefault());
+ }
+
+ /**
+ * Returns the detail message in the given locale and timezone.
+ * @param loc the {@link Locale}
+ * @param timezone the {@link TimeZone}
+ * @return the detail message.
+ * @throws MissingEntryException if the message is not available
+ */
+ public String getDetail(Locale loc, TimeZone timezone) throws MissingEntryException
+ {
+ return getEntry(DETAIL_ENTRY,loc,timezone);
+ }
+
+ /**
+ * Returns the detail message in the given locale and the default timezone.
+ * @param loc the {@link Locale}
+ * @return the detail message.
+ * @throws MissingEntryException if the message is not available
+ */
+ public String getDetail(Locale loc) throws MissingEntryException
+ {
+ return getEntry(DETAIL_ENTRY,loc,TimeZone.getDefault());
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/LocaleString.java b/core/src/main/java/org/bouncycastle/i18n/LocaleString.java
new file mode 100644
index 00000000..b9e22320
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/LocaleString.java
@@ -0,0 +1,24 @@
+package org.bouncycastle.i18n;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+
+public class LocaleString extends LocalizedMessage
+{
+
+ public LocaleString(String resource, String id)
+ {
+ super(resource, id);
+ }
+
+ public LocaleString(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException
+ {
+ super(resource, id, encoding);
+ }
+
+ public String getLocaleString(Locale locale)
+ {
+ return this.getEntry(null, locale, null);
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/LocalizedException.java b/core/src/main/java/org/bouncycastle/i18n/LocalizedException.java
new file mode 100644
index 00000000..373fd6ce
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/LocalizedException.java
@@ -0,0 +1,49 @@
+package org.bouncycastle.i18n;
+
+import java.util.Locale;
+
+/**
+ * Base class for all Exceptions with localized messages.
+ */
+public class LocalizedException extends Exception
+{
+
+ protected ErrorBundle message;
+ private Throwable cause;
+
+ /**
+ * Constructs a new LocalizedException with the specified localized message.
+ * @param message the {@link ErrorBundle} that contains the message for the exception
+ */
+ public LocalizedException(ErrorBundle message)
+ {
+ super(message.getText(Locale.getDefault()));
+ this.message = message;
+ }
+
+ /**
+ * Constructs a new LocalizedException with the specified localized message and cause.
+ * @param message the {@link ErrorBundle} that contains the message for the exception
+ * @param throwable the cause
+ */
+ public LocalizedException(ErrorBundle message, Throwable throwable)
+ {
+ super(message.getText(Locale.getDefault()));
+ this.message = message;
+ this.cause = throwable;
+ }
+
+ /**
+ * Returns the localized error message of the exception.
+ * @return the localized error message as {@link ErrorBundle}
+ */
+ public ErrorBundle getErrorMessage()
+ {
+ return message;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/LocalizedMessage.java b/core/src/main/java/org/bouncycastle/i18n/LocalizedMessage.java
new file mode 100644
index 00000000..d88c2291
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/LocalizedMessage.java
@@ -0,0 +1,476 @@
+package org.bouncycastle.i18n;
+
+import org.bouncycastle.i18n.filter.Filter;
+import org.bouncycastle.i18n.filter.TrustedInput;
+import org.bouncycastle.i18n.filter.UntrustedInput;
+import org.bouncycastle.i18n.filter.UntrustedUrlInput;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.text.DateFormat;
+import java.text.Format;
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.TimeZone;
+
+public class LocalizedMessage
+{
+
+ protected final String id;
+ protected final String resource;
+
+ // ISO-8859-1 is the default encoding
+ public static final String DEFAULT_ENCODING = "ISO-8859-1";
+ protected String encoding = DEFAULT_ENCODING;
+
+ protected FilteredArguments arguments;
+ protected FilteredArguments extraArgs = null;
+
+ protected Filter filter = null;
+
+ protected ClassLoader loader = null;
+
+ /**
+ * Constructs a new LocalizedMessage using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ */
+ public LocalizedMessage(String resource,String id) throws NullPointerException
+ {
+ if (resource == null || id == null)
+ {
+ throw new NullPointerException();
+ }
+ this.id = id;
+ this.resource = resource;
+ arguments = new FilteredArguments();
+ }
+
+ /**
+ * Constructs a new LocalizedMessage using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param encoding the encoding of the resource file
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ */
+ public LocalizedMessage(String resource,String id, String encoding) throws NullPointerException, UnsupportedEncodingException
+ {
+ if (resource == null || id == null)
+ {
+ throw new NullPointerException();
+ }
+ this.id = id;
+ this.resource = resource;
+ arguments = new FilteredArguments();
+ if (!Charset.isSupported(encoding))
+ {
+ throw new UnsupportedEncodingException("The encoding \"" + encoding + "\" is not supported.");
+ }
+ this.encoding = encoding;
+ }
+
+ /**
+ * Constructs a new LocalizedMessage using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param arguments an array containing the arguments for the message
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ */
+ public LocalizedMessage(String resource, String id, Object[] arguments) throws NullPointerException
+ {
+ if (resource == null || id == null || arguments == null)
+ {
+ throw new NullPointerException();
+ }
+ this.id = id;
+ this.resource = resource;
+ this.arguments = new FilteredArguments(arguments);
+ }
+
+ /**
+ * Constructs a new LocalizedMessage using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param encoding the encoding of the resource file
+ * @param arguments an array containing the arguments for the message
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ */
+ public LocalizedMessage(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException
+ {
+ if (resource == null || id == null || arguments == null)
+ {
+ throw new NullPointerException();
+ }
+ this.id = id;
+ this.resource = resource;
+ this.arguments = new FilteredArguments(arguments);
+ if (!Charset.isSupported(encoding))
+ {
+ throw new UnsupportedEncodingException("The encoding \"" + encoding + "\" is not supported.");
+ }
+ this.encoding = encoding;
+ }
+
+ /**
+ * Reads the entry <code>id + "." + key</code> from the resource file and returns a
+ * formated message for the given Locale and TimeZone.
+ * @param key second part of the entry id
+ * @param loc the used {@link Locale}
+ * @param timezone the used {@link TimeZone}
+ * @return a Strng containing the localized message
+ * @throws MissingEntryException if the resource file is not available or the entry does not exist.
+ */
+ public String getEntry(String key,Locale loc, TimeZone timezone) throws MissingEntryException
+ {
+ String entry = id;
+ if (key != null)
+ {
+ entry += "." + key;
+ }
+
+ try
+ {
+ ResourceBundle bundle;
+ if (loader == null)
+ {
+ bundle = ResourceBundle.getBundle(resource,loc);
+ }
+ else
+ {
+ bundle = ResourceBundle.getBundle(resource, loc, loader);
+ }
+ String result = bundle.getString(entry);
+ if (!encoding.equals(DEFAULT_ENCODING))
+ {
+ result = new String(result.getBytes(DEFAULT_ENCODING), encoding);
+ }
+ if (!arguments.isEmpty())
+ {
+ result = formatWithTimeZone(result,arguments.getFilteredArgs(loc),loc,timezone);
+ }
+ result = addExtraArgs(result, loc);
+ return result;
+ }
+ catch (MissingResourceException mre)
+ {
+ throw new MissingEntryException("Can't find entry " + entry + " in resource file " + resource + ".",
+ resource,
+ entry,
+ loc,
+ loader != null ? loader : this.getClassLoader());
+ }
+ catch (UnsupportedEncodingException use)
+ {
+ // should never occur - cause we already test this in the constructor
+ throw new RuntimeException(use);
+ }
+ }
+
+ protected String formatWithTimeZone(
+ String template,
+ Object[] arguments,
+ Locale locale,
+ TimeZone timezone)
+ {
+ MessageFormat mf = new MessageFormat(" ");
+ mf.setLocale(locale);
+ mf.applyPattern(template);
+ if (!timezone.equals(TimeZone.getDefault()))
+ {
+ Format[] formats = mf.getFormats();
+ for (int i = 0; i < formats.length; i++)
+ {
+ if (formats[i] instanceof DateFormat)
+ {
+ DateFormat temp = (DateFormat) formats[i];
+ temp.setTimeZone(timezone);
+ mf.setFormat(i,temp);
+ }
+ }
+ }
+ return mf.format(arguments);
+ }
+
+ protected String addExtraArgs(String msg, Locale locale)
+ {
+ if (extraArgs != null)
+ {
+ StringBuffer sb = new StringBuffer(msg);
+ Object[] filteredArgs = extraArgs.getFilteredArgs(locale);
+ for (int i = 0; i < filteredArgs.length; i++)
+ {
+ sb.append(filteredArgs[i]);
+ }
+ msg = sb.toString();
+ }
+ return msg;
+ }
+
+ /**
+ * Sets the {@link Filter} that is used to filter the arguments of this message
+ * @param filter the {@link Filter} to use. <code>null</code> to disable filtering.
+ */
+ public void setFilter(Filter filter)
+ {
+ arguments.setFilter(filter);
+ if (extraArgs != null)
+ {
+ extraArgs.setFilter(filter);
+ }
+ this.filter = filter;
+ }
+
+ /**
+ * Returns the current filter.
+ * @return the current filter
+ */
+ public Filter getFilter()
+ {
+ return filter;
+ }
+
+ /**
+ * Set the {@link ClassLoader} which loads the resource files. If it is set to <code>null</code>
+ * then the default {@link ClassLoader} is used.
+ * @param loader the {@link ClassLoader} which loads the resource files
+ */
+ public void setClassLoader(ClassLoader loader)
+ {
+ this.loader = loader;
+ }
+
+ /**
+ * Returns the {@link ClassLoader} which loads the resource files or <code>null</code>
+ * if the default ClassLoader is used.
+ * @return the {@link ClassLoader} which loads the resource files
+ */
+ public ClassLoader getClassLoader()
+ {
+ return loader;
+ }
+
+ /**
+ * Returns the id of the message in the resource bundle.
+ * @return the id of the message
+ */
+ public String getId()
+ {
+ return id;
+ }
+
+ /**
+ * Returns the name of the resource bundle for this message
+ * @return name of the resource file
+ */
+ public String getResource()
+ {
+ return resource;
+ }
+
+ /**
+ * Returns an <code>Object[]</code> containing the message arguments.
+ * @return the message arguments
+ */
+ public Object[] getArguments()
+ {
+ return arguments.getArguments();
+ }
+
+ /**
+ *
+ * @param extraArg
+ */
+ public void setExtraArgument(Object extraArg)
+ {
+ setExtraArguments(new Object[] {extraArg});
+ }
+
+ /**
+ *
+ * @param extraArgs
+ */
+ public void setExtraArguments(Object[] extraArgs)
+ {
+ if (extraArgs != null)
+ {
+ this.extraArgs = new FilteredArguments(extraArgs);
+ this.extraArgs.setFilter(filter);
+ }
+ else
+ {
+ this.extraArgs = null;
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ public Object[] getExtraArgs()
+ {
+ return (extraArgs == null) ? null : extraArgs.getArguments();
+ }
+
+ protected class FilteredArguments
+ {
+ protected static final int NO_FILTER = 0;
+ protected static final int FILTER = 1;
+ protected static final int FILTER_URL = 2;
+
+ protected Filter filter = null;
+
+ protected boolean[] isLocaleSpecific;
+ protected int[] argFilterType;
+ protected Object[] arguments;
+ protected Object[] unpackedArgs;
+ protected Object[] filteredArgs;
+
+ FilteredArguments()
+ {
+ this(new Object[0]);
+ }
+
+ FilteredArguments(Object[] args)
+ {
+ this.arguments = args;
+ this.unpackedArgs = new Object[args.length];
+ this.filteredArgs = new Object[args.length];
+ this.isLocaleSpecific = new boolean[args.length];
+ this.argFilterType = new int[args.length];
+ for (int i = 0; i < args.length; i++)
+ {
+ if (args[i] instanceof TrustedInput)
+ {
+ this.unpackedArgs[i] = ((TrustedInput) args[i]).getInput();
+ argFilterType[i] = NO_FILTER;
+ }
+ else if (args[i] instanceof UntrustedInput)
+ {
+ this.unpackedArgs[i] = ((UntrustedInput) args[i]).getInput();
+ if (args[i] instanceof UntrustedUrlInput)
+ {
+ argFilterType[i] = FILTER_URL;
+ }
+ else
+ {
+ argFilterType[i] = FILTER;
+ }
+ }
+ else
+ {
+ this.unpackedArgs[i] = args[i];
+ argFilterType[i] = FILTER;
+ }
+
+ // locale specific
+ this.isLocaleSpecific[i] = (this.unpackedArgs[i] instanceof LocaleString);
+ }
+ }
+
+ public boolean isEmpty()
+ {
+ return unpackedArgs.length == 0;
+ }
+
+ public Object[] getArguments()
+ {
+ return arguments;
+ }
+
+ public Object[] getFilteredArgs(Locale locale)
+ {
+ Object[] result = new Object[unpackedArgs.length];
+ for (int i = 0; i < unpackedArgs.length; i++)
+ {
+ Object arg;
+ if (filteredArgs[i] != null)
+ {
+ arg = filteredArgs[i];
+ }
+ else
+ {
+ arg = unpackedArgs[i];
+ if (isLocaleSpecific[i])
+ {
+ // get locale
+ arg = ((LocaleString) arg).getLocaleString(locale);
+ arg = filter(argFilterType[i], arg);
+ }
+ else
+ {
+ arg = filter(argFilterType[i], arg);
+ filteredArgs[i] = arg;
+ }
+ }
+ result[i] = arg;
+ }
+ return result;
+ }
+
+ private Object filter(int type, Object obj)
+ {
+ if (filter != null)
+ {
+ Object o = (null == obj) ? "null" : obj;
+ switch (type)
+ {
+ case NO_FILTER:
+ return o;
+ case FILTER:
+ return filter.doFilter(o.toString());
+ case FILTER_URL:
+ return filter.doFilterUrl(o.toString());
+ default:
+ return null;
+ }
+ }
+ else
+ {
+ return obj;
+ }
+ }
+
+ public Filter getFilter()
+ {
+ return filter;
+ }
+
+ public void setFilter(Filter filter)
+ {
+ if (filter != this.filter)
+ {
+ for (int i = 0; i < unpackedArgs.length; i++)
+ {
+ filteredArgs[i] = null;
+ }
+ }
+ this.filter = filter;
+ }
+
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Resource: \"").append(resource);
+ sb.append("\" Id: \"").append(id).append("\"");
+ sb.append(" Arguments: ").append(arguments.getArguments().length).append(" normal");
+ if (extraArgs != null && extraArgs.getArguments().length > 0)
+ {
+ sb.append(", ").append(extraArgs.getArguments().length).append(" extra");
+ }
+ sb.append(" Encoding: ").append(encoding);
+ sb.append(" ClassLoader: ").append(loader);
+ return sb.toString();
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/MessageBundle.java b/core/src/main/java/org/bouncycastle/i18n/MessageBundle.java
new file mode 100644
index 00000000..de931fce
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/MessageBundle.java
@@ -0,0 +1,92 @@
+package org.bouncycastle.i18n;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class MessageBundle extends TextBundle
+{
+
+ /**
+ * title entry key
+ */
+ public static final String TITLE_ENTRY = "title";
+
+ /**
+ * Constructs a new MessageBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ */
+ public MessageBundle(String resource, String id) throws NullPointerException
+ {
+ super(resource, id);
+ }
+
+ /**
+ * Constructs a new MessageBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param encoding the encoding of the resource file
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ */
+ public MessageBundle(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException
+ {
+ super(resource, id, encoding);
+ }
+
+ /**
+ * Constructs a new MessageBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param arguments an array containing the arguments for the message
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ */
+ public MessageBundle(String resource, String id, Object[] arguments) throws NullPointerException
+ {
+ super(resource, id, arguments);
+ }
+
+ /**
+ * Constructs a new MessageBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param encoding the encoding of the resource file
+ * @param arguments an array containing the arguments for the message
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ */
+ public MessageBundle(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException
+ {
+ super(resource, id, encoding, arguments);
+ }
+
+ /**
+ * Returns the title message in the given locale and timezone.
+ * @param loc the {@link Locale}
+ * @param timezone the {@link TimeZone}
+ * @return the title message.
+ * @throws MissingEntryException if the message is not available
+ */
+ public String getTitle(Locale loc,TimeZone timezone) throws MissingEntryException
+ {
+ return getEntry(TITLE_ENTRY,loc,timezone);
+ }
+
+ /**
+ * Returns the title message in the given locale and the default timezone.
+ * @param loc the {@link Locale}
+ * @return the title message.
+ * @throws MissingEntryException if the message is not available
+ */
+ public String getTitle(Locale loc) throws MissingEntryException
+ {
+ return getEntry(TITLE_ENTRY,loc,TimeZone.getDefault());
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/MissingEntryException.java b/core/src/main/java/org/bouncycastle/i18n/MissingEntryException.java
new file mode 100644
index 00000000..ffd4d543
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/MissingEntryException.java
@@ -0,0 +1,73 @@
+package org.bouncycastle.i18n;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Locale;
+
+public class MissingEntryException extends RuntimeException
+{
+
+ protected final String resource;
+ protected final String key;
+ protected final ClassLoader loader;
+ protected final Locale locale;
+
+ private String debugMsg;
+
+ public MissingEntryException(String message, String resource, String key, Locale locale, ClassLoader loader)
+ {
+ super(message);
+ this.resource = resource;
+ this.key = key;
+ this.locale = locale;
+ this.loader = loader;
+ }
+
+ public MissingEntryException(String message, Throwable cause, String resource, String key, Locale locale, ClassLoader loader)
+ {
+ super(message, cause);
+ this.resource = resource;
+ this.key = key;
+ this.locale = locale;
+ this.loader = loader;
+ }
+
+ public String getKey()
+ {
+ return key;
+ }
+
+ public String getResource()
+ {
+ return resource;
+ }
+
+ public ClassLoader getClassLoader()
+ {
+ return loader;
+ }
+
+ public Locale getLocale()
+ {
+ return locale;
+ }
+
+ public String getDebugMsg()
+ {
+ if (debugMsg == null)
+ {
+ debugMsg = "Can not find entry " + key + " in resource file " + resource + " for the locale " + locale + ".";
+ if (loader instanceof URLClassLoader)
+ {
+ URL[] urls = ((URLClassLoader) loader).getURLs();
+ debugMsg += " The following entries in the classpath were searched: ";
+ for (int i = 0; i != urls.length; i++)
+ {
+ debugMsg += urls[i] + " ";
+ }
+ }
+ }
+ return debugMsg;
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/TextBundle.java b/core/src/main/java/org/bouncycastle/i18n/TextBundle.java
new file mode 100644
index 00000000..d77e8417
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/TextBundle.java
@@ -0,0 +1,92 @@
+package org.bouncycastle.i18n;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public class TextBundle extends LocalizedMessage
+{
+
+ /**
+ * text entry key
+ */
+ public static final String TEXT_ENTRY = "text";
+
+ /**
+ * Constructs a new TextBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ */
+ public TextBundle(String resource, String id) throws NullPointerException
+ {
+ super(resource, id);
+ }
+
+ /**
+ * Constructs a new TextBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param encoding the encoding of the resource file
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ */
+ public TextBundle(String resource, String id, String encoding) throws NullPointerException, UnsupportedEncodingException
+ {
+ super(resource, id, encoding);
+ }
+
+ /**
+ * Constructs a new TextBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param arguments an array containing the arguments for the message
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ */
+ public TextBundle(String resource, String id, Object[] arguments) throws NullPointerException
+ {
+ super(resource, id, arguments);
+ }
+
+ /**
+ * Constructs a new TextBundle using <code>resource</code> as the base name for the
+ * RessourceBundle and <code>id</code> as the message bundle id the resource file.
+ * @param resource base name of the resource file
+ * @param id the id of the corresponding bundle in the resource file
+ * @param encoding the encoding of the resource file
+ * @param arguments an array containing the arguments for the message
+ * @throws NullPointerException if <code>resource</code> or <code>id</code> is <code>null</code>
+ * @throws UnsupportedEncodingException if the encoding is not supported
+ */
+ public TextBundle(String resource, String id, String encoding, Object[] arguments) throws NullPointerException, UnsupportedEncodingException
+ {
+ super(resource, id, encoding, arguments);
+ }
+
+ /**
+ * Returns the text message in the given locale and timezone.
+ * @param loc the {@link Locale}
+ * @param timezone the {@link TimeZone}
+ * @return the text message.
+ * @throws MissingEntryException if the message is not available
+ */
+ public String getText(Locale loc, TimeZone timezone) throws MissingEntryException
+ {
+ return getEntry(TEXT_ENTRY,loc,timezone);
+ }
+
+ /**
+ * Returns the text message in the given locale and the defaut timezone.
+ * @param loc the {@link Locale}
+ * @return the text message.
+ * @throws MissingEntryException if the message is not available
+ */
+ public String getText(Locale loc) throws MissingEntryException
+ {
+ return getEntry(TEXT_ENTRY,loc,TimeZone.getDefault());
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/filter/Filter.java b/core/src/main/java/org/bouncycastle/i18n/filter/Filter.java
new file mode 100644
index 00000000..fc86aaa4
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/filter/Filter.java
@@ -0,0 +1,21 @@
+
+package org.bouncycastle.i18n.filter;
+
+public interface Filter
+{
+
+ /**
+ * Runs the filter on the input String and returns the filtered String
+ * @param input input String
+ * @return filtered String
+ */
+ public String doFilter(String input);
+
+ /**
+ * Runs the filter on the input url and returns the filtered String
+ * @param input input url String
+ * @return filtered String
+ */
+ public String doFilterUrl(String input);
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/filter/HTMLFilter.java b/core/src/main/java/org/bouncycastle/i18n/filter/HTMLFilter.java
new file mode 100644
index 00000000..b9904bc7
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/filter/HTMLFilter.java
@@ -0,0 +1,68 @@
+
+package org.bouncycastle.i18n.filter;
+
+/**
+ * HTML Filter
+ */
+public class HTMLFilter implements Filter
+{
+
+ public String doFilter(String input)
+ {
+ StringBuffer buf = new StringBuffer(input);
+ int i = 0;
+ while (i < buf.length())
+ {
+ char ch = buf.charAt(i);
+ switch (ch)
+ {
+ case '<':
+ buf.replace(i,i+1,"&#60");
+ break;
+ case '>':
+ buf.replace(i,i+1,"&#62");
+ break;
+ case '(':
+ buf.replace(i,i+1,"&#40");
+ break;
+ case ')':
+ buf.replace(i,i+1,"&#41");
+ break;
+ case '#':
+ buf.replace(i,i+1,"&#35");
+ break;
+ case '&':
+ buf.replace(i,i+1,"&#38");
+ break;
+ case '\"':
+ buf.replace(i,i+1,"&#34");
+ break;
+ case '\'':
+ buf.replace(i,i+1,"&#39");
+ break;
+ case '%':
+ buf.replace(i,i+1,"&#37");
+ break;
+ case ';':
+ buf.replace(i,i+1,"&#59");
+ break;
+ case '+':
+ buf.replace(i,i+1,"&#43");
+ break;
+ case '-':
+ buf.replace(i,i+1,"&#45");
+ break;
+ default:
+ i -= 3;
+ }
+ i += 4;
+ }
+ return buf.toString();
+ }
+
+ public String doFilterUrl(String input)
+ {
+ return doFilter(input);
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/filter/SQLFilter.java b/core/src/main/java/org/bouncycastle/i18n/filter/SQLFilter.java
new file mode 100644
index 00000000..d55610b6
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/filter/SQLFilter.java
@@ -0,0 +1,69 @@
+
+package org.bouncycastle.i18n.filter;
+
+/**
+ * Filter for strings to store in a SQL table.
+ *
+ * escapes ' " = - / \ ; \r \n
+ */
+public class SQLFilter implements Filter
+{
+
+ public String doFilter(String input)
+ {
+ StringBuffer buf = new StringBuffer(input);
+ int i = 0;
+ while (i < buf.length())
+ {
+ char ch = buf.charAt(i);
+ switch (ch)
+ {
+ case '\'':
+ buf.replace(i,i+1,"\\\'");
+ i += 1;
+ break;
+ case '\"':
+ buf.replace(i,i+1,"\\\"");
+ i += 1;
+ break;
+ case '=':
+ buf.replace(i,i+1,"\\=");
+ i += 1;
+ break;
+ case '-':
+ buf.replace(i,i+1,"\\-");
+ i += 1;
+ break;
+ case '/':
+ buf.replace(i,i+1,"\\/");
+ i += 1;
+ break;
+ case '\\':
+ buf.replace(i,i+1,"\\\\");
+ i += 1;
+ break;
+ case ';':
+ buf.replace(i,i+1,"\\;");
+ i += 1;
+ break;
+ case '\r':
+ buf.replace(i,i+1,"\\r");
+ i += 1;
+ break;
+ case '\n':
+ buf.replace(i,i+1,"\\n");
+ i += 1;
+ break;
+ default:
+ }
+ i++;
+ }
+ return buf.toString();
+ }
+
+ public String doFilterUrl(String input)
+ {
+ return doFilter(input);
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/filter/TrustedInput.java b/core/src/main/java/org/bouncycastle/i18n/filter/TrustedInput.java
new file mode 100644
index 00000000..0feeeea7
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/filter/TrustedInput.java
@@ -0,0 +1,23 @@
+package org.bouncycastle.i18n.filter;
+
+public class TrustedInput
+{
+
+ protected Object input;
+
+ public TrustedInput(Object input)
+ {
+ this.input = input;
+ }
+
+ public Object getInput()
+ {
+ return input;
+ }
+
+ public String toString()
+ {
+ return input.toString();
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/filter/UntrustedInput.java b/core/src/main/java/org/bouncycastle/i18n/filter/UntrustedInput.java
new file mode 100644
index 00000000..cc69ac49
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/filter/UntrustedInput.java
@@ -0,0 +1,44 @@
+
+package org.bouncycastle.i18n.filter;
+
+/**
+ * Wrapper class to mark untrusted input.
+ */
+public class UntrustedInput
+{
+
+ protected Object input;
+
+ /**
+ * Construct a new UntrustedInput instance.
+ * @param input the untrusted input Object
+ */
+ public UntrustedInput(Object input)
+ {
+ this.input = input;
+ }
+
+ /**
+ * Returns the untrusted input as Object.
+ * @return the <code>input</code> as Object
+ */
+ public Object getInput()
+ {
+ return input;
+ }
+
+ /**
+ * Returns the untrusted input convertet to a String.
+ * @return the <code>input</code> as String
+ */
+ public String getString()
+ {
+ return input.toString();
+ }
+
+ public String toString()
+ {
+ return input.toString();
+ }
+
+}
diff --git a/core/src/main/java/org/bouncycastle/i18n/filter/UntrustedUrlInput.java b/core/src/main/java/org/bouncycastle/i18n/filter/UntrustedUrlInput.java
new file mode 100644
index 00000000..98ee1e72
--- /dev/null
+++ b/core/src/main/java/org/bouncycastle/i18n/filter/UntrustedUrlInput.java
@@ -0,0 +1,14 @@
+package org.bouncycastle.i18n.filter;
+
+/**
+ *
+ * Wrapper class to mark an untrusted Url
+ */
+public class UntrustedUrlInput extends UntrustedInput
+{
+ public UntrustedUrlInput(Object url)
+ {
+ super(url);
+ }
+
+}