Davanum Srinivas wrote:
>
> Team,
>
> Was out of the loop for a while....Are there any patches that need to get in? There
>was one from
> Tom for SQLTransformer (that tom said still needs some work before it can get in).
>Anything other
> than that, please repost the patch with "cvs diff" from the latest CVS.
>
> Thanks,
> dims
>
> =====
> Davanum Srinivas, JNI-FAQ Manager
> http://www.jGuru.com/faq/JNI
At 07 Aug 2001 I posted patches for
src/org/apache/cocoon/transformation/I18nTransformer.java
and
xdocs/i18n-transformer.xml
I have no access to cvs, thats why I post an ordinary diff -u
before changes:
version of xdocs/i18n-transformer.xml: 1.6
version of src/org/apache/cocoon/transformation/I18nTransformer.java:
1.14
Regards,
Michael
--- i18n-transformer.xml.orig Tue Aug 7 14:28:16 2001
+++ i18n-transformer.xml Tue Aug 7 14:32:56 2001
@@ -28,11 +28,14 @@
<code>I18nTransformer</code>
</link>
, it uses XML dictionaries for all the i18n data. The
namespace of i18n is defined as follows:
-
<code>xmlns:i18n="http://apache.org/cocoon/i18n/2.0"</code>
+
+<code>xmlns:i18n="http://apache.org/cocoon/i18n/2.1"</code>
</p>
<p>
First implementation was developed by <link
href="mailto:[EMAIL PROTECTED]">Lassi Immonen</link>. In this implementation
syntax was changed according to the <link
href="http://www.infozone-group.org">Infozone Group's</link> i18n proposal (with a
little difference) and some new features were implemented.
</p>
+ <p>
+ Enhancements for number, date and time have been
+contributed by <link href="mailto:[EMAIL PROTECTED]">Michael
+Enke</link>.
+ </p>
<ul>
<li>Name : i18n</li>
<li>Class:
org.apache.cocoon.transformation.I18nTransformer</li>
@@ -168,10 +171,19 @@
</p>
</s2>
<s2 title="Date, time and number formatting">
- <p>To format dates and time according to the current
locale use <code><![CDATA[<i18n:date src-pattern="dd/MM/yyyy" pattern="dd:MMM:yyyy"
value="01/01/2001" />]]></code>. The <code>'src-pattern'</code> attribute will be used
to parse the <code>'value'</code>, then the date will be formatted according to the
current locale using the format specified by <code>'pattern'</code> attribute.
+ <p>To format dates according to the current locale use
+<code><![CDATA[<i18n:date src-pattern="dd/MM/yyyy" pattern="dd:MMM:yyyy"
+value="01/01/2001" />]]></code>. The <code>'src-pattern'</code> attribute will be
+used to parse the <code>'value'</code>, then the date will be formatted according to
+the current locale using the format specified by <code>'pattern'</code> attribute.
+ </p>
+ <p>To format time for a locale (e.g. de_DE) use
+<code><![CDATA[<i18n:time src-pattern="dd/MM/yyyy" locale="de_DE" value="01/01/2001"
+/>]]></code>. The <code>'src-pattern'</code> and <code>'pattern'</code> attribute may
+also contain <code>'short'</code>, <code>'medium'</code>, <code>'long'</code> or
+<code>'full'</code>. The date will be formatted according to this format.
+ </p>
+ <p>To format date and time use
+<code><![CDATA[<i18n:date-time />]]></code>.
+ </p>
+ <p>It is also possible to specify a src-locale:
+<code><![CDATA[<i18n:date src-pattern="short" src-locale="en_US" locale="de_DE">
+12/24/01 </i18n:date> ]]></code> will result in 24.12.2001
+ </p>
+ <p>
+ A given real <code>pattern</code> and
+<code>src-pattern</code> (not short, medium, long, full) overwrites the
+<code>locale</code> and <code>src-locale</code>.
</p>
<p>
- If no pattern was specified then the date will
be formatted with the <code>DateFormat.DEFAULT</code> format (both date and time). If
no value for the date is specified then the current date will be used. E.g.:
<code><![CDATA[<i18n:date ]]></code> will result in the current date and time,
formatted with default localized pattern.
+ If no pattern was specified then the date will
+be formatted with the <code>DateFormat.DEFAULT</code> format (both date and time). If
+no value for the date is specified then the current date will be used. E.g.:
+<code><![CDATA[<i18n:date/> ]]></code> will result in the current date, formatted
+with default localized pattern.
</p>
<p>To format numbers in locale sensitive manner use
<code><![CDATA[<i18n:number pattern="0.##" value="2.0" />]]></code>. This will be
useful for Arabic, Indian, etc. number formatting. Additionally, currencies and
percent formatting can be used. E.g.:
</p>
--- I18nTransformer.java.orig Tue Aug 7 12:36:07 2001
+++ I18nTransformer.java Tue Aug 7 14:34:11 2001
@@ -176,6 +176,27 @@
* </map:match>
* </pre>
*
+ * <p/>
+ * <ul>
+ * <li><strong><i18n:date/></strong> gives now only the date.</li>
+ * <li><strong><i18n:date-time/></strong> gives the date and time.</li>
+ * <li><strong><i18n:time/></strong> gives the time.</li>
+ * <li>For date, date-time and time the pattern and src-pattern attribute
+ * may have also values of: "short", "medium",
+ * "long" or "full".</li>
+ * </ul>
+ * <p/>
+ * <ul>
+ * <li>for date, date-time, time and number a different locale and
+ * source-locale can be specified:
+ * <i18n:date src-pattern="short" src-locale="en_US" locale="de_DE">
+ * 12/24/01
+ * </i18n:date>
+ * will result in 24.12.2001</li>
+ * <li>A given real pattern and src-pattern (not short, medium, long, full)
+ * overwrites the locale and src-locale</li>
+ * </ul>
+ * <p/>
* Future work coming:
*
* <ul>
@@ -186,6 +207,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Marcus Crafter</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Konstantin Piroumian</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Lassi Immonen</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Michael Enke</a>
*/
public class I18nTransformer extends AbstractTransformer
implements Composable, Poolable, Configurable {
@@ -193,10 +215,10 @@
protected ComponentManager manager;
/**
- * The namespace for i18n is "http://apache.org/cocoon/i18n/2.0"
+ * The namespace for i18n is "http://apache.org/cocoon/i18n/2.1"
*/
public static final String I18N_NAMESPACE_URI =
- "http://apache.org/cocoon/i18n/2.0";
+ "http://apache.org/cocoon/i18n/2.1";
//
// Dictionary elements and attributes
@@ -216,12 +238,16 @@
public static final String I18N_TRANSLATE_ELEMENT = "translate";
public static final String I18N_PARAM_ELEMENT = "param";
public static final String I18N_DATE_ELEMENT = "date";
+ public static final String I18N_DATE_TIME_ELEMENT = "date-time";
+ public static final String I18N_TIME_ELEMENT = "time";
public static final String I18N_NUMBER_ELEMENT = "number";
// number and date formatting attributes
public static final String I18N_SRC_PATTERN_ATTRIBUTE = "src-pattern";
public static final String I18N_PATTERN_ATTRIBUTE = "pattern";
public static final String I18N_VALUE_ATTRIBUTE = "value";
+ public static final String I18N_LOCALE_ATTRIBUTE = "locale";
+ public static final String I18N_SRC_LOCALE_ATTRIBUTE = "src-locale";
// configuration parameters
public static final String I18N_CATALOGUE_NAME = "catalogue-name";
@@ -253,7 +279,9 @@
private static final int STATE_TRANSLATE_KEY = 5;
private static final int STATE_TRANSLATE_TEXT_KEY = 6;
private static final int STATE_INSIDE_DATE = 7;
- private static final int STATE_INSIDE_NUMBER = 8;
+ private static final int STATE_INSIDE_DATE_TIME = 8;
+ private static final int STATE_INSIDE_TIME = 9;
+ private static final int STATE_INSIDE_NUMBER = 10;
/**
* Current state of the transformer.
@@ -316,7 +344,7 @@
/**
* Locale setting.
*/
- private Locale locale;
+ private Locale locale, loc, srcLoc;
/**
* Date element attributes and their values.
@@ -534,6 +562,24 @@
setFormattingParams(attr);
current_state = STATE_INSIDE_DATE;
+ } else if (I18N_DATE_TIME_ELEMENT.equals(name)) {
+ if (current_state != STATE_OUTSIDE) {
+ throw new SAXException(this.getClass().getName()
+ + ": i18n:date-time elements are not
+allowed "
+ + "inside of other i18n elements.");
+ }
+
+ setFormattingParams(attr);
+ current_state = STATE_INSIDE_DATE_TIME;
+ } else if (I18N_TIME_ELEMENT.equals(name)) {
+ if (current_state != STATE_OUTSIDE) {
+ throw new SAXException(this.getClass().getName()
+ + ": i18n:date elements are not allowed "
+ + "inside of other i18n elements.");
+ }
+
+ setFormattingParams(attr);
+ current_state = STATE_INSIDE_TIME;
} else if (I18N_NUMBER_ELEMENT.equals(name)) {
if (current_state != STATE_OUTSIDE) {
throw new SAXException(this.getClass().getName()
@@ -573,6 +619,16 @@
formattingParams.put(I18N_VALUE_ATTRIBUTE, attr_value);
}
+ attr_value = attr.getValue(I18N_LOCALE_ATTRIBUTE);
+ if (attr_value != null) {
+ formattingParams.put(I18N_LOCALE_ATTRIBUTE, attr_value);
+ }
+
+ attr_value = attr.getValue(I18N_SRC_LOCALE_ATTRIBUTE);
+ if (attr_value != null) {
+ formattingParams.put(I18N_SRC_LOCALE_ATTRIBUTE, attr_value);
+ }
+
attr_value = attr.getValue(I18N_TYPE_ATTRIBUTE);
if (attr_value != null) {
formattingParams.put(I18N_TYPE_ATTRIBUTE, attr_value);
@@ -605,8 +661,10 @@
break;
}
case STATE_INSIDE_DATE:
+ case STATE_INSIDE_DATE_TIME:
+ case STATE_INSIDE_TIME:
{
- endDateElement();
+ endDate_TimeElement();
break;
}
case STATE_INSIDE_NUMBER:
@@ -688,6 +746,9 @@
break;
}
case STATE_INSIDE_DATE:
+ case STATE_INSIDE_DATE_TIME:
+ case STATE_INSIDE_TIME:
+ case STATE_INSIDE_NUMBER:
{
if (formattingParams != null) {
if (formattingParams.get(I18N_VALUE_ATTRIBUTE) == null) {
@@ -699,18 +760,6 @@
}
break;
}
- case STATE_INSIDE_NUMBER:
- {
- if (formattingParams != null) {
- if (formattingParams.get(I18N_PATTERN_ATTRIBUTE) == null) {
- formattingParams.put(I18N_PATTERN_ATTRIBUTE, key);
- } else {
- // how to use the text inside of number element?
- }
-
- }
- break;
- }
default:
{
throw new SAXException(this.getClass().getName()
@@ -812,9 +861,11 @@
debug("Put param value: " + param_value);
formattingParams.put(I18N_VALUE_ATTRIBUTE, param_value);
}
- if ("date".equals(paramType)) {
- debug("Formatting date param: " + formattingParams);
- param_value = formatDate(formattingParams);
+ if ("date".equals(paramType) ||
+ "date-time".equals(paramType) ||
+ "time".equals(paramType)) {
+ debug("Formatting date_time param: " + formattingParams);
+ param_value = formatDate_Time(formattingParams);
} else if ("number".equals(paramType)) {
debug("Formatting number param: " + formattingParams);
param_value = formatNumber(formattingParams);
@@ -848,17 +899,43 @@
current_state = STATE_OUTSIDE;
}
- private void endDateElement() throws SAXException {
- String result = formatDate(formattingParams);
+ private void endDate_TimeElement() throws SAXException {
+ String result = formatDate_Time(formattingParams);
super.contentHandler.characters(result.toCharArray(), 0, result.length());
current_state = STATE_OUTSIDE;
}
- private String formatDate(Map params) throws SAXException {
+ private Locale getLocale(Map params, String attribute) {
+ Locale locale = this.locale;
+ // the specific locale value
+ String lc = (String)params.get(attribute);
+ if(lc != null) try {
+
+ String[] matches = new RE("_").split(lc);
+ String l = matches.length > 0
+ ? matches[0] : Locale.getDefault().getLanguage();
+ String c = matches.length > 1 ? matches[1] : "";
+ String v = matches.length > 2 ? matches[2] : "";
+ locale = new Locale(l, c, v);
+ }
+ catch(Exception e) {}
+ return locale;
+ }
+
+ private String formatDate_Time(Map params) throws SAXException {
+ SimpleDateFormat to_fmt = null, from_fmt;
+ String element = null;
+ int srcStyle = DateFormat.SHORT, style = DateFormat.SHORT;
+ boolean realPattern = false, realSrcPattern = false;
+
if (params == null) {
throw new SAXException(this.getClass().getName()
- + ": i18n:date - error in element attributes.");
+ + ": i18n:"+element+" - error in element
+attributes.");
}
+
+ loc = getLocale(params, I18N_LOCALE_ATTRIBUTE);
+ srcLoc = getLocale(params, I18N_SRC_LOCALE_ATTRIBUTE);
+
// from pattern
String srcPattern = (String)params.get(I18N_SRC_PATTERN_ATTRIBUTE);
// to pattern
@@ -866,19 +943,70 @@
// the date value
String value = (String)params.get(I18N_VALUE_ATTRIBUTE);
+ if(srcPattern == null) {
+ srcStyle = DateFormat.DEFAULT;
+ }
+ else {
+ if(srcPattern.equalsIgnoreCase("short"))
+ srcStyle = DateFormat.SHORT;
+ else if(srcPattern.equalsIgnoreCase("medium"))
+ srcStyle = DateFormat.MEDIUM;
+ else if(srcPattern.equalsIgnoreCase("long"))
+ srcStyle = DateFormat.LONG;
+ else if(srcPattern.equalsIgnoreCase("full"))
+ srcStyle = DateFormat.FULL;
+ /* really a src-pattern */
+ else
+ realSrcPattern = true;
+ }
+ if(pattern == null) {
+ style = DateFormat.DEFAULT;
+ }
+ else {
+ if(pattern.equalsIgnoreCase("short"))
+ style = DateFormat.SHORT;
+ else if(pattern.equalsIgnoreCase("medium"))
+ style = DateFormat.MEDIUM;
+ else if(pattern.equalsIgnoreCase("long"))
+ style = DateFormat.LONG;
+ else if(pattern.equalsIgnoreCase("full"))
+ style = DateFormat.FULL;
+ /* really a pattern */
+ else
+ realPattern = true;
+ }
+
+ if (current_state == STATE_INSIDE_DATE) {
+ element = I18N_DATE_ELEMENT;
+ to_fmt = (SimpleDateFormat)DateFormat.
+ getDateInstance(style, loc);
+ from_fmt = (SimpleDateFormat)DateFormat.
+ getDateInstance(srcStyle, srcLoc);
+ }
+ else if (current_state == STATE_INSIDE_DATE_TIME) {
+ element = I18N_DATE_TIME_ELEMENT;
+ to_fmt = (SimpleDateFormat)DateFormat.
+ getDateTimeInstance(style, style, loc);
+ from_fmt = (SimpleDateFormat)DateFormat.
+ getDateTimeInstance(srcStyle, srcStyle, srcLoc);
+ }
+ else { /* STATE_INSIDE_TIME */
+ element = I18N_TIME_ELEMENT;
+ to_fmt = (SimpleDateFormat)DateFormat.
+ getTimeInstance(style, loc);
+ from_fmt = (SimpleDateFormat)DateFormat.
+ getTimeInstance(srcStyle, srcLoc);
+ }
+
// parsed date object
Date dateValue = null;
- // src format
- SimpleDateFormat from_fmt = (SimpleDateFormat)DateFormat.getInstance();
- if (srcPattern != null) {
+ // pattern overwrites locale format
+ if (realSrcPattern) {
from_fmt.applyPattern(srcPattern);
}
- // result pattern is localized
- SimpleDateFormat to_fmt = (SimpleDateFormat)DateFormat.getDateTimeInstance(
- DateFormat.DEFAULT, DateFormat.DEFAULT, locale);
- if (pattern != null) {
+ if (realPattern) {
to_fmt.applyPattern(pattern);
}
@@ -896,7 +1024,7 @@
// we have all necessary data here: do formatting.
String result = to_fmt.format(dateValue);
- debug("i18n:date result: " + result);
+ debug("i18n:"+element+" result: " + result);
return result;
}
@@ -923,26 +1051,33 @@
// parsed number
Number numberValue = null;
+ // locale, may be switched locale
+ loc = getLocale(params, I18N_LOCALE_ATTRIBUTE);
+ srcLoc = getLocale(params, I18N_SRC_LOCALE_ATTRIBUTE);
+
+
// src format
- DecimalFormat from_fmt = (DecimalFormat)NumberFormat.getInstance();
+ DecimalFormat from_fmt = (DecimalFormat)NumberFormat.getInstance(srcLoc);
+ // src-pattern overwrites locale format
if (srcPattern != null) {
from_fmt.applyPattern(srcPattern);
}
- // result pattern is localized
+ // to format
DecimalFormat to_fmt = null;
if (subType == null) {
- to_fmt = (DecimalFormat)NumberFormat.getInstance(locale);
+ to_fmt = (DecimalFormat)NumberFormat.getInstance(loc);
} else if (subType.equals("currency")) {
- to_fmt = (DecimalFormat)NumberFormat.getCurrencyInstance(locale);
+ to_fmt = (DecimalFormat)NumberFormat.getCurrencyInstance(loc);
} else if (subType.equals("percent")) {
- to_fmt = (DecimalFormat)NumberFormat.getPercentInstance(locale);
+ to_fmt = (DecimalFormat)NumberFormat.getPercentInstance(loc);
}
+
+ // pattern overwrites locale format
if (pattern != null) {
to_fmt.applyPattern(pattern);
}
- // get current date and time by default
if (value == null) {
numberValue = new Long(0);
} else {
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]