blob: e1635463a662837b142f5a453ea1453728768504 [file] [log] [blame]
/* $Id$ */
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.apache.manifoldcf.ui.i18n;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.HashMap;
import java.util.Properties;
import java.util.ResourceBundle;
import org.apache.manifoldcf.core.interfaces.IHTTPOutput;
import org.apache.manifoldcf.core.interfaces.ManifoldCFException;
import org.apache.manifoldcf.ui.util.Encoder;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
public class Messages extends org.apache.manifoldcf.core.i18n.Messages
{
public static final String DEFAULT_BUNDLE_NAME="org.apache.manifoldcf.ui.i18n.common";
public static String getString(Locale locale, String messageKey)
{
return getString(DEFAULT_BUNDLE_NAME, locale, messageKey, null);
}
public static String getAttributeString(Locale locale, String messageKey)
{
return getAttributeString(DEFAULT_BUNDLE_NAME, locale, messageKey, null);
}
public static String getBodyString(Locale locale, String messageKey)
{
return getBodyString(DEFAULT_BUNDLE_NAME, locale, messageKey, null);
}
public static String getAttributeJavascriptString(Locale locale, String messageKey)
{
return getAttributeJavascriptString(DEFAULT_BUNDLE_NAME, locale, messageKey, null);
}
public static String getBodyJavascriptString(Locale locale, String messageKey)
{
return getBodyJavascriptString(DEFAULT_BUNDLE_NAME, locale, messageKey, null);
}
public static String getString(Locale locale, String messageKey, Object[] args)
{
return getString(DEFAULT_BUNDLE_NAME, locale, messageKey, args);
}
public static String getAttributeString(Locale locale, String messageKey, Object[] args)
{
return getAttributeString(DEFAULT_BUNDLE_NAME, locale, messageKey, args);
}
public static String getBodyString(Locale locale, String messageKey, Object[] args)
{
return getBodyString(DEFAULT_BUNDLE_NAME, locale, messageKey, args);
}
public static String getAttributeJavascriptString(Locale locale, String messageKey, Object[] args)
{
return getAttributeJavascriptString(DEFAULT_BUNDLE_NAME, locale, messageKey, args);
}
public static String getBodyJavascriptString(Locale locale, String messageKey, Object[] args)
{
return getBodyJavascriptString(DEFAULT_BUNDLE_NAME, locale, messageKey, args);
}
// More general methods which allow bundlenames and class loaders to be specified.
public static String getString(String bundleName, Locale locale, String messageKey, Object[] args)
{
return getString(Messages.class, bundleName, locale, messageKey, args);
}
public static String getAttributeString(String bundleName, Locale locale, String messageKey, Object[] args)
{
return getAttributeString(Messages.class, bundleName, locale, messageKey, args);
}
public static String getBodyString(String bundleName, Locale locale, String messageKey, Object[] args)
{
return getBodyString(Messages.class, bundleName, locale, messageKey, args);
}
public static String getAttributeJavascriptString(String bundleName, Locale locale, String messageKey, Object[] args)
{
return getAttributeJavascriptString(Messages.class, bundleName, locale, messageKey, args);
}
public static String getBodyJavascriptString(String bundleName, Locale locale, String messageKey, Object[] args)
{
return getBodyJavascriptString(Messages.class, bundleName, locale, messageKey, args);
}
/** Constructor - do no instantiate
*/
protected Messages()
{
}
public static void outputResourceWithVelocity(IHTTPOutput output, Class clazz, String bundleName, String pathName,
Locale locale, String resourceKey, Map<String,Object> contextObjects)
throws ManifoldCFException
{
VelocityEngine engine = createVelocityEngine(clazz);
try {
VelocityContext context = new VelocityContext();
// Add utility methods the UI needs
context.put("Encoder",org.apache.manifoldcf.ui.util.Encoder.class);
context.put("Formatter",org.apache.manifoldcf.ui.util.Formatter.class);
context.put("MultilineParser",org.apache.manifoldcf.ui.util.MultilineParser.class);
// Add in the resource bundle
ResourceBundle rb = getResourceBundle(clazz,bundleName,locale);
context.put("ResourceBundle",new ResourceBundleWrapper(rb,bundleName,locale));
if (contextObjects != null)
{
Iterator<String> i = contextObjects.keySet().iterator();
while(i.hasNext())
{
String key = i.next();
Object value = contextObjects.get(key);
context.put(key,value);
}
}
String resourcePath = localizeResourceName(pathName, resourceKey, locale);
Writer outputWriter = new OutputWriter(output);
engine.mergeTemplate(resourcePath, StandardCharsets.UTF_8.name(), context, outputWriter);
outputWriter.flush();
} catch (IOException e) {
throw new ManifoldCFException(e.getMessage(),e);
}
}
/** Write a resource to HTTP output, specifying what to substitute, and more importantly, how.
* $PARAM_NAME will be substituted directly with the value.
* $PARAM_NAME_A will be substituted with HTML attribute-escaped value.
* $PARAM_NAME_B will be substituted with HTML body-escaped value.
* $PARAM_NAME_AJ will be substituted with HTML attribute + Javascript escaped value.
* $PARAM_NAME_BJ will be substituted with HTML body + Javascript escaped value.
*/
public static void outputResourceWithVelocity(IHTTPOutput output, Class clazz, String bundleName, String pathName,
Locale locale, String resourceKey, Map<String,String> substitutionParameters, boolean mapToUpperCase)
throws ManifoldCFException
{
Map<String,Object> contextObjects = null;
if (substitutionParameters != null)
{
contextObjects = new HashMap<String,Object>();
Iterator<String> i = substitutionParameters.keySet().iterator();
while(i.hasNext())
{
String key = i.next();
String value = substitutionParameters.get(key);
if (mapToUpperCase)
key = key.toUpperCase();
if (value == null)
value = "";
contextObjects.put(key,value);
contextObjects.put(key+"_A",Encoder.attributeEscape(value));
contextObjects.put(key+"_B",Encoder.bodyEscape(value));
contextObjects.put(key+"_AJ",Encoder.attributeJavascriptEscape(value));
contextObjects.put(key+"_BJ",Encoder.bodyJavascriptEscape(value));
}
}
outputResourceWithVelocity(output,clazz,bundleName,pathName,locale,resourceKey,contextObjects);
}
private static class OutputWriter extends Writer
{
private IHTTPOutput output;
public OutputWriter(IHTTPOutput output)
{
super();
this.output = output;
}
public void write(char[] cbuf, int off, int len)
throws IOException
{
if (off == 0 && len == cbuf.length)
output.print(cbuf);
else
output.print(new String(cbuf,off,len));
}
public void close()
throws IOException
{
}
public void flush()
throws IOException
{
}
}
private static String localizeResourceName(String pathName, String resourceName, Locale locale)
{
return resourceName;
}
/** Write a resource to HTTP output, specifying what to substitute, and more importantly, how.
* ${PARAM_NAME} will be substituted directly with the value.
* ${PARAM_NAME:A} will be substituted with HTML attribute-escaped value.
* ${PARAM_NAME:B} will be substituted with HTML body-escaped value.
* ${PARAM_NAME:AJ} will be substituted with HTML attribute + Javascript escaped value.
* ${PARAM_NAME:BJ} will be substituted with HTML body + Javascript escaped value.
*/
public static void outputResource(IHTTPOutput output, Class classInstance, String pathName,
Locale locale, String resourceKey, Map<String,String> substitutionParameters, boolean mapToUpperCase)
throws ManifoldCFException
{
try
{
InputStream is = getResourceAsStream(classInstance,pathName,locale,resourceKey);
try
{
BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String line;
while ((line = br.readLine()) != null)
{
if (substitutionParameters != null)
{
Iterator<String> i = substitutionParameters.keySet().iterator();
boolean parsedLine = false;
while(i.hasNext())
{
String key = i.next();
String value = substitutionParameters.get(key);
if (mapToUpperCase)
key = key.toUpperCase();
if (value == null)
value = "";
//System.out.println("Processed key = '"+key+"', processed value = '"+value+"'");
// We replace 4x, with 4 different replacement strings
line = doReplace(line,"${"+key+"}",value);
line = doReplace(line,"${"+key+":A}",Encoder.attributeEscape(value));
line = doReplace(line,"${"+key+":B}",Encoder.bodyEscape(value));
line = doReplace(line,"${"+key+":AJ}",Encoder.attributeJavascriptEscape(value));
line = doReplace(line,"${"+key+":BJ}",Encoder.bodyJavascriptEscape(value));
}
}
output.println(line);
}
}
finally
{
is.close();
}
}
catch (IOException e)
{
throw new ManifoldCFException(e.getMessage(),e);
}
}
private static String doReplace(String line, String key, String value)
{
if (line.indexOf(key) == -1)
{
return line;
}
StringBuilder sb = new StringBuilder();
int index = 0;
while (true)
{
int newIndex = line.indexOf(key,index);
if (newIndex == -1)
{
sb.append(line.substring(index));
break;
}
sb.append(line.substring(index,newIndex)).append(value);
index = newIndex + key.length();
}
return sb.toString();
}
/** Obtain a string given a classloader, bundle, locale, message key, and arguments, and escape it for HTML body context.
*/
public static String getBodyString(Class clazz, String bundleName, Locale locale,
String messageKey, Object[] args)
{
return Encoder.bodyEscape(getString(clazz,bundleName,locale,messageKey,args));
}
/** Obtain a string given a classloader, bundle, locale, message key, and arguments, and escape it for HTML attribute context.
*/
public static String getAttributeString(Class clazz, String bundleName, Locale locale,
String messageKey, Object[] args)
{
return Encoder.attributeEscape(getString(clazz,bundleName,locale,messageKey,args));
}
/** Obtain a string given a classloader, bundle, locale, message key, and arguments, and escape it for HTML attribute/javascript context.
*/
public static String getAttributeJavascriptString(Class clazz, String bundleName, Locale locale,
String messageKey, Object[] args)
{
return Encoder.attributeJavascriptEscape(getString(clazz,bundleName,locale,messageKey,args));
}
/** Obtain a string given a classloader, bundle, locale, message key, and arguments, and escape it for HTML body/javascript context.
*/
public static String getBodyJavascriptString(Class clazz, String bundleName, Locale locale,
String messageKey, Object[] args)
{
return Encoder.bodyJavascriptEscape(getString(clazz,bundleName,locale,messageKey,args));
}
}