Author: andreas
Date: Sun Mar 25 20:58:50 2012
New Revision: 1305128
URL:http://svn.apache.org/viewvc?rev=1305128&view=rev
Log:
Add parameters parse-xml and parse-namespace to the I18nTransformer. Allows to
include XML elements in I18n messages.
Modified:
cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/I18nTransformer.java
Modified:
cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/I18nTransformer.java
URL:http://svn.apache.org/viewvc/cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/I18nTransformer.java?rev=1305128&r1=1305127&r2=1305128&view=diff
==============================================================================
---
cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/I18nTransformer.java
(original)
+++
cocoon/cocoon3/trunk/cocoon-sax/src/main/java/org/apache/cocoon/sax/component/I18nTransformer.java
Sun Mar 25 20:58:50 2012
@@ -33,9 +33,9 @@ import java.util.Map;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
+import java.util.ResourceBundle.Control;
import java.util.Set;
import java.util.StringTokenizer;
-import java.util.ResourceBundle.Control;
import org.apache.cocoon.pipeline.SetupException;
import org.apache.cocoon.pipeline.caching.CacheKey;
@@ -44,6 +44,7 @@ import org.apache.cocoon.pipeline.compon
import org.apache.cocoon.sax.AbstractSAXTransformer;
import org.apache.cocoon.sax.util.VariableExpressionTokenizer;
import org.apache.cocoon.sax.util.VariableExpressionTokenizer.TokenReceiver;
+import org.apache.cocoon.sax.util.XMLUtils;
import org.apache.cocoon.xml.sax.ParamSAXBuffer;
import org.apache.cocoon.xml.sax.SAXBuffer;
import org.slf4j.Logger;
@@ -577,6 +578,16 @@ public class I18nTransformer extends Abs
public static final String DEFAULT_ENCODING = "ISO-8859-1";
/**
+ * If XML inside i18n messages shall be parsed.
+ */
+ public static final String PARAM_PARSE_XML = "parse-xml";
+
+ /**
+ * The default namespace for XML elements inside messages. Defaults
tohttp://www.w3.org/1999/xhtml.
+ */
+ public static final String PARAM_PARSE_NAMESPACE = "parse-namespace";
+
+ /**
* States of the transformer.
*/
private enum TransformerState {
@@ -717,6 +728,12 @@ public class I18nTransformer extends Abs
// Date and number elements and params formatting attributes with values.
private Map<String, String> formattingParams;
+
+ // parse XML inside messages?
+ private boolean parseXml;
+
+ // default namespace for XML inside messages
+ private String parseNamespace;
/**
* Empty constructor, for usage with sitemap.
@@ -806,6 +823,16 @@ public class I18nTransformer extends Abs
final String encoding = (String)
(parameters.containsKey(PARAM_ENCODING)
? parameters.get(PARAM_ENCODING) : DEFAULT_ENCODING);
+
+ this.parseXml = parameters.containsKey(PARAM_PARSE_XML)
+ ? Boolean.parseBoolean((String)
parameters.get(PARAM_PARSE_XML))
+ : false;
+
+ if (this.parseXml) {
+ this.parseNamespace = parameters.containsKey(PARAM_PARSE_NAMESPACE)
+ ? (String) parameters.get(PARAM_PARSE_NAMESPACE)
+ :"http://www.w3.org/1999/xhtml";
+ }
this.init(parseLocale((String) parameters.get(PARAM_LOCALE)),
(String) parameters.get(PARAM_BUNDLE),
@@ -966,7 +993,7 @@ public class I18nTransformer extends Abs
if (currentKey != null) {
final ParamSAXBuffer message =
- getMessage(currentKey, ParamSAXBuffer.class);
+ getMessage(currentKey, FragmentBuffer.class);
translatedTextRecorder = message;
}
} else if (ELEM_TRANSLATE.equals(name)) {
@@ -1898,7 +1925,19 @@ public class I18nTransformer extends Abs
if (message != null&& message.length()> 0) {
try {
buffer = reference.newInstance();
- buffer.characters(message.toCharArray(), 0, message.length());
+ if (this.parseXml) {
+ try {
+ final String xml = "<?xml version='1.0'?><dummy xmlns='" + this.parseNamespace +
"'>" + message +"</dummy>";
+ XMLUtils.toSax(xml, buffer);
+ } catch (Exception e) {
+ LOG.error("Could not parse XML '{}'", message, e);
+ buffer.recycle();
+ buffer.characters(message.toCharArray(), 0,
message.length());
+ }
+ }
+ else {
+ buffer.characters(message.toCharArray(), 0,
message.length());
+ }
} catch (InstantiationException e) {
LOG.error("Could not instantiate {}", reference, e);
} catch (IllegalAccessException e) {
@@ -1908,6 +1947,42 @@ public class I18nTransformer extends Abs
return buffer;
}
+
+ /**
+ * SAX buffer which passes only the content of the document element to the
content handler.
+ * An element with an arbitrary local name can be used the wrapper element.
+ */
+ protected static final class FragmentBuffer extends ParamSAXBuffer {
+
+ private static final long serialVersionUID = -9153292487513611344L;
+
+ private int depth = 0;
+
+ @Override
+ public void startDocument() throws SAXException {}
+
+ @Override
+ public void endDocument() throws SAXException {}
+
+ @Override
+ public void startElement(String namespaceURI, String localName, String
qName,
+ Attributes atts) throws SAXException {
+ if (this.depth> 0) {
+ super.startElement(namespaceURI, localName, qName, atts);
+ }
+ this.depth++;
+ }
+
+ @Override
+ public void endElement(String namespaceURI, String localName, String
qName)
+ throws SAXException {
+ this.depth--;
+ if (this.depth> 0) {
+ super.endElement(namespaceURI, localName, qName);
+ }
+ }
+
+ }
/**
* Helper method to retrieve a message from the current dictionary.
@@ -1922,7 +1997,7 @@ public class I18nTransformer extends Abs
final ParamSAXBuffer defaultValue)
throws SAXException {
- ParamSAXBuffer result = getMessage(key, ParamSAXBuffer.class);
+ ParamSAXBuffer result = getMessage(key, FragmentBuffer.class);
if (result == null) {
result = defaultValue;
}