dims        01/08/14 04:46:08

  Modified:    src/org/apache/cocoon/transformation I18nTransformer.java
               xdocs    i18n-transformer.xml
  Log:
  Patch from Enke Michael <[EMAIL PROTECTED]> for
  "Enhancements for number, date and time in i18n-transformer"
  
  Revision  Changes    Path
  1.15      +171 -36   
xml-cocoon2/src/org/apache/cocoon/transformation/I18nTransformer.java
  
  Index: I18nTransformer.java
  ===================================================================
  RCS file: 
/home/cvs/xml-cocoon2/src/org/apache/cocoon/transformation/I18nTransformer.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- I18nTransformer.java      2001/07/19 11:22:21     1.14
  +++ I18nTransformer.java      2001/08/14 11:46:08     1.15
  @@ -176,6 +176,27 @@
    * &lt;/map:match&gt;
    * </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 {
  @@ -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 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;
   
  -    private String formatDate(Map params) throws SAXException {
           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 {
  
  
  
  1.7       +14 -2     xml-cocoon2/xdocs/i18n-transformer.xml
  
  Index: i18n-transformer.xml
  ===================================================================
  RCS file: /home/cvs/xml-cocoon2/xdocs/i18n-transformer.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- i18n-transformer.xml      2001/07/28 03:42:25     1.6
  +++ i18n-transformer.xml      2001/08/14 11:46:08     1.7
  @@ -33,6 +33,9 @@
                                <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>
  
  
  

----------------------------------------------------------------------
In case of troubles, e-mail:     [EMAIL PROTECTED]
To unsubscribe, e-mail:          [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to