You are viewing a plain text version of this content. The canonical link for it is here.
Posted to adffaces-commits@incubator.apache.org by aw...@apache.org on 2006/10/19 21:05:27 UTC
svn commit: r465884 - in
/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource:
TrTranslationsResourceLoader.java TranslationsResourceLoader.java
Author: awiner
Date: Thu Oct 19 14:05:26 2006
New Revision: 465884
URL: http://svn.apache.org/viewvc?view=rev&rev=465884
Log:
Rewrite translations resource loader to be much more performant, properly support non-ASCII characters, more generic, comply with coding standards, easily subclassed, etc.
Added:
incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TranslationsResourceLoader.java
Modified:
incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TrTranslationsResourceLoader.java
Modified: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TrTranslationsResourceLoader.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TrTranslationsResourceLoader.java?view=diff&rev=465884&r1=465883&r2=465884
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TrTranslationsResourceLoader.java (original)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TrTranslationsResourceLoader.java Thu Oct 19 14:05:26 2006
@@ -15,17 +15,11 @@
*/
package org.apache.myfaces.trinidadinternal.resource;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URL;
+import javax.faces.context.FacesContext;
-import org.apache.myfaces.trinidad.resource.StringContentResourceLoader;
-import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
+import org.apache.myfaces.trinidad.skin.Skin;
-import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.XhtmlUtils;
-
-public class TrTranslationsResourceLoader extends StringContentResourceLoader
+public class TrTranslationsResourceLoader extends TranslationsResourceLoader
{
/**
* Constructs a dynamic resouce loader for this path which serves up translations
@@ -35,116 +29,37 @@
public TrTranslationsResourceLoader(String path)
{
super(path);
- setMap("TrMessageFactory._TRANSLATIONS");
- setBundle("org.apache.myfaces.trinidad.resource.MessageBundle");
}
-
- protected void setMap(String mapName)
+
+
+ @Override
+ protected int getDefaultSize()
{
- this.mapName = mapName;
+ // We're coming in at about 13K for Japanese, which is probably
+ // about as big as this will get
+ return 20000;
}
- protected void setBundle(String bundleName)
+ protected String getJSVarName()
{
- this.bundleName = bundleName;
+ return "TrMessageFactory._TRANSLATIONS";
}
-
- @Override
- protected String getString(String path) throws IOException
+
+ protected String getBundleName()
{
- // its always better to initialize the StringBuffer with size instead of leaving it unset
- StringBuffer bundleMap = new StringBuffer(50000);
- String content = "";
-
- String locale = CoreRenderKitResourceLoader.getLocale();
-
- bundleMap.append(mapName)
- .append(" = ")
- .append("\n{\n");
-
- content += _processBundle(bundleName, locale);
-
- //Remove the last 2 characters( ie, newLine & ',')
- bundleMap.append(content.substring(0, content.length()-2))
- .append("\n};");
-
- return bundleMap.toString();
+ return "org.apache.myfaces.trinidad.resource.MessageBundle";
}
-
+
@Override
- protected String getContentType(String path)
+ protected String getLocaleString(FacesContext context)
{
- return _CONTENT_TYPE;
+ return CoreRenderKitResourceLoader.getLocale();
}
-
+
+ // These translations do not go through the skin
@Override
- protected URL findResource(
- String path) throws IOException
+ protected Skin getSkin(FacesContext context)
{
- return getURL(path);
- }
-
- protected String _processBundle(
- String bundleName,
- String localeName
- ) throws IOException
- {
- StringBuffer transMap = new StringBuffer(50000);
- Object obj = invokeGetContents(bundleName, localeName);
-
- if( obj != null)
- {
- Object entry[] = (Object [])obj;
-
- for(int i=0; i< entry.length; i++)
- {
- transMap.append("'" + ((Object [])entry[i])[0] + "'")
- .append(":")
- .append("'" + XhtmlUtils.escapeJS(((Object [])entry[i])[1].toString(), true) + "',")
- .append("\n");
- }
- }
-
- return transMap.toString();
+ return null;
}
-
- protected Object invokeGetContents(
- String bundleName,
- String localeName
- ) throws IOException
- {
- String className = bundleName + "_" + localeName;
- Object obj = null;
-
- try
- {
- Class<?> clazz;
- try
- {
- clazz = ClassLoaderUtils.loadClass(className);
- }
- catch (ClassNotFoundException e)
- {
- // If there is no bundle specific to locale, use Default locale
- clazz = ClassLoaderUtils.loadClass(bundleName);
- }
-
- //Invoke getContents() method which gives us the Translations
- Method x = clazz.getMethod("getContents", (Class[]) null);
- obj = x.invoke(clazz.newInstance(), (Object[]) null);
-
- } catch (NoSuchMethodException e) { ;
- } catch (InvocationTargetException e) { ;
- } catch (IllegalAccessException e) { ;
- } catch (InstantiationException e) { ;
- } catch (ClassNotFoundException e) { ;
- }
-
- return obj;
- }
-
- protected String mapName;
- protected String bundleName;
-
- private static final String _CONTENT_TYPE = "text/javascript";
}
Added: incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TranslationsResourceLoader.java
URL: http://svn.apache.org/viewvc/incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TranslationsResourceLoader.java?view=auto&rev=465884
==============================================================================
--- incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TranslationsResourceLoader.java (added)
+++ incubator/adffaces/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/resource/TranslationsResourceLoader.java Thu Oct 19 14:05:26 2006
@@ -0,0 +1,222 @@
+/*
+* Copyright 2006 The Apache Software Foundation.
+*
+* 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 org.apache.myfaces.trinidadinternal.resource;
+
+import java.io.IOException;
+
+import java.net.URL;
+
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.trinidad.context.LocaleContext;
+import org.apache.myfaces.trinidad.logging.TrinidadLogger;
+import org.apache.myfaces.trinidad.resource.StringContentResourceLoader;
+import org.apache.myfaces.trinidad.skin.Skin;
+import org.apache.myfaces.trinidad.skin.SkinFactory;
+
+import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.XhtmlUtils;
+import org.apache.myfaces.trinidadinternal.share.nls.LocaleContextImpl;
+import org.apache.myfaces.trinidadinternal.util.nls.LocaleUtils;
+
+abstract public class TranslationsResourceLoader
+ extends StringContentResourceLoader
+{
+ /**
+ * Constructs a dynamic resouce loader for this path which serves up
+ * translations.
+ *
+ * @param path the path of this dynamic resource loader
+ */
+ public TranslationsResourceLoader(String path)
+ {
+ super(path);
+ }
+
+ abstract protected String getJSVarName();
+
+ abstract protected String getBundleName();
+
+ /**
+ * Override to increase the default size of the buffer.
+ */
+ protected int getDefaultSize()
+ {
+ return 10000;
+ }
+
+ protected String getLocaleString(FacesContext context)
+ {
+ Object localeObj = context.getExternalContext().getRequestParameterMap().
+ get("loc");
+ return (localeObj == null || "".equals(localeObj))
+ ? null : localeObj.toString();
+ }
+
+ @Override
+ protected String getContentType(String path)
+ {
+ return _CONTENT_TYPE;
+ }
+
+ @Override
+ protected URL findResource(
+ String path) throws IOException
+ {
+ return getURL(path);
+ }
+
+ @Override
+ protected String getString(String path) throws IOException
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+ String localeStr = getLocaleString(context);
+
+ Locale locale = LocaleUtils.getLocaleForIANAString(localeStr);
+ if (locale == null)
+ locale = Locale.getDefault();
+
+ ResourceBundle bundle;
+ try
+ {
+ bundle = _getResourceBundle(locale);
+ }
+ catch (MissingResourceException mre)
+ {
+ _LOG.severe("Could not find bundle " + getBundleName(), mre);
+ return "/* COULD NOT FIND BUNDLE " + getBundleName() + " */";
+ }
+
+ // FIXME: would be much better to directly stream the contents
+ // rather than using StringContentResourceLoader
+ StringBuilder builder = new StringBuilder(getDefaultSize());
+
+ builder.append(getJSVarName())
+ .append("=")
+ .append("{\n");
+
+ _processBundle(context, builder, bundle, locale);
+
+ builder.append("\n}");
+
+ return builder.toString();
+ }
+
+ private ResourceBundle _getResourceBundle(Locale locale)
+ throws MissingResourceException
+ {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ return ResourceBundle.getBundle(getBundleName(),
+ locale,
+ loader);
+ }
+
+ protected Skin getSkin(FacesContext context)
+ {
+ Skin skin = null;
+ SkinFactory skinFactory = SkinFactory.getFactory();
+ Object skinIdObj = context.getExternalContext().getRequestParameterMap().
+ get("skinId");
+ if (skinIdObj != null)
+ skin = skinFactory.getSkin(context, skinIdObj.toString());
+
+ return skin;
+ }
+
+ private void _processBundle(
+ FacesContext context,
+ StringBuilder builder,
+ ResourceBundle bundle,
+ Locale locale)
+ {
+ Skin skin = getSkin(context);
+ LocaleContext lc = new LocaleContextImpl(locale);
+
+ // We get the keys from the bundle, but try to get the values from
+ // the skin if possible
+ Enumeration<String> keys = bundle.getKeys();
+ boolean writtenOne = false;
+ while (keys.hasMoreElements())
+ {
+ if (writtenOne)
+ builder.append(",\n");
+ else
+ writtenOne = true;
+
+ String key = keys.nextElement();
+ String value;
+ // If we can get it from the skin, that's better, but if not,
+ // go to the bundle
+ if (skin == null)
+ value = bundle.getString(key);
+ else
+ value = skin.getTranslatedString(lc, key);
+
+ builder.append("'");
+ builder.append(key);
+ builder.append("':'");
+ _appendUnicodeString(builder, value);
+ builder.append("'");
+ }
+ }
+
+ private void _appendUnicodeString(
+ StringBuilder builder,
+ String value)
+ {
+ if (value == null)
+ return;
+
+ int length = value.length();
+ for (int i = 0; i < length; i++)
+ {
+ char c = value.charAt(i);
+ if ((c >= 0x20) && (c < 0x80))
+ {
+ if (c == '\'')
+ builder.append("\\'");
+ else if (c == '\\')
+ builder.append("\\\\");
+ else
+ builder.append(c);
+ }
+ else
+ {
+ // Unicode escape any non-ascii characters
+ builder.append("\\u");
+ String hex = Integer.toHexString(c);
+ int hexLen = hex.length();
+ // Javascript is lame, and requires padding Unicode escapes
+ // to four-digits
+ if (hexLen == 1)
+ builder.append("000");
+ else if (hexLen == 2)
+ builder.append("00");
+ else if (hexLen == 3)
+ builder.append("0");
+ builder.append(hex);
+ }
+ }
+ }
+
+ private static final String _CONTENT_TYPE = "text/javascript";
+ private static final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(
+ TranslationsResourceLoader.class);
+}