| /* |
| * 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.cocoon.template.instruction; |
| |
| import java.text.DateFormat; |
| import java.text.SimpleDateFormat; |
| import java.util.Locale; |
| import java.util.Stack; |
| import java.util.TimeZone; |
| |
| import org.apache.cocoon.components.expression.ExpressionContext; |
| import org.apache.cocoon.template.environment.ErrorHolder; |
| import org.apache.cocoon.template.environment.ExecutionContext; |
| import org.apache.cocoon.template.environment.ParsingContext; |
| import org.apache.cocoon.template.expression.JXTExpression; |
| import org.apache.cocoon.template.expression.StringTemplateParser; |
| import org.apache.cocoon.template.script.event.Event; |
| import org.apache.cocoon.template.script.event.StartElement; |
| import org.apache.cocoon.xml.XMLConsumer; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.Locator; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.SAXParseException; |
| |
| /** |
| * @version SVN $Id$ |
| */ |
| public class FormatDate extends LocaleAwareInstruction { |
| private static final String DATE = "date"; |
| private static final String TIME = "time"; |
| private static final String DATETIME = "both"; |
| |
| private JXTExpression var; |
| private JXTExpression value; |
| private JXTExpression type; |
| private JXTExpression pattern; |
| private JXTExpression timeZone; |
| private JXTExpression dateStyle; |
| private JXTExpression timeStyle; |
| public FormatDate(ParsingContext parsingContext, StartElement raw, Attributes attrs, Stack stack) |
| throws SAXException{ |
| super(parsingContext, raw, attrs, stack); |
| |
| Locator locator = getLocation(); |
| |
| StringTemplateParser expressionCompiler = parsingContext.getStringTemplateParser(); |
| this.var = expressionCompiler.compileExpr(attrs.getValue("var"), null, locator); |
| this.value = expressionCompiler.compileExpr(attrs.getValue("value"), null, locator); |
| this.type = expressionCompiler.compileExpr(attrs.getValue("type"), null, locator); |
| this.pattern = expressionCompiler.compileExpr(attrs.getValue("pattern"), null, locator); |
| this.timeZone = expressionCompiler.compileExpr(attrs.getValue("timeZone"), null, locator); |
| this.dateStyle = expressionCompiler.compileExpr(attrs.getValue("dateStyle"), null, locator); |
| this.timeStyle = expressionCompiler.compileExpr(attrs.getValue("timeStyle"), null, locator); |
| } |
| |
| public Event execute(final XMLConsumer consumer, |
| ExpressionContext expressionContext, ExecutionContext executionContext, |
| MacroContext macroContext, Event startEvent, Event endEvent) |
| throws SAXException { |
| try { |
| String result = format(expressionContext); |
| if (result != null) { |
| char[] chars = result.toCharArray(); |
| consumer.characters(chars, 0, chars.length); |
| } |
| } catch (Exception e) { |
| throw new SAXParseException(e.getMessage(), getLocation(), e); |
| } catch (Error err) { |
| throw new SAXParseException(err.getMessage(), getLocation(), new ErrorHolder(err)); |
| } |
| return getNext(); |
| } |
| |
| private String format(ExpressionContext expressionContext) throws Exception { |
| String var = this.var == null ? null : this.var.getStringValue(expressionContext); |
| Object value = this.value == null ? null : this.value.getValue(expressionContext); |
| |
| String pattern = this.pattern == null ? null : this.pattern.getStringValue(expressionContext); |
| Object timeZone = this.timeZone == null ? null : this.timeZone.getValue(expressionContext); |
| |
| String type = this.type == null ? null : this.type.getStringValue(expressionContext); |
| String timeStyle = this.timeStyle == null ? null : this.timeStyle.getStringValue(expressionContext); |
| String dateStyle = this.dateStyle == null ? null : this.dateStyle.getStringValue(expressionContext); |
| |
| String formatted = null; |
| |
| // Create formatter |
| Locale locale = getLocale( expressionContext ); |
| DateFormat formatter = createFormatter(locale, type, dateStyle, |
| timeStyle); |
| // Apply pattern, if present |
| if (pattern != null) { |
| try { |
| ((SimpleDateFormat) formatter).applyPattern(pattern); |
| } catch (ClassCastException cce) { |
| formatter = new SimpleDateFormat(pattern, locale); |
| } |
| } |
| // Set time zone |
| TimeZone tz = null; |
| if ((timeZone instanceof String) && ((String) timeZone).equals("")) { |
| timeZone = null; |
| } |
| if (timeZone != null) { |
| if (timeZone instanceof String) { |
| tz = TimeZone.getTimeZone((String) timeZone); |
| } else if (timeZone instanceof TimeZone) { |
| tz = (TimeZone) timeZone; |
| } else { |
| throw new IllegalArgumentException("Illegal timeZone value: \"" |
| + timeZone + "\""); |
| } |
| } |
| if (tz != null) { |
| formatter.setTimeZone(tz); |
| } |
| formatted = formatter.format(value); |
| if (var != null) { |
| expressionContext.put(var, formatted); |
| return null; |
| } |
| return formatted; |
| } |
| |
| private DateFormat createFormatter(Locale loc, String type, |
| String dateStyle, String timeStyle) throws Exception { |
| DateFormat formatter = null; |
| if ((type == null) || DATE.equalsIgnoreCase(type)) { |
| formatter = DateFormat.getDateInstance(getStyle(dateStyle), loc); |
| } else if (TIME.equalsIgnoreCase(type)) { |
| formatter = DateFormat.getTimeInstance(getStyle(timeStyle), loc); |
| } else if (DATETIME.equalsIgnoreCase(type)) { |
| formatter = DateFormat.getDateTimeInstance(getStyle(dateStyle), |
| getStyle(timeStyle), loc); |
| } else { |
| throw new IllegalArgumentException("Invalid type: \"" + type + "\""); |
| } |
| return formatter; |
| } |
| |
| private static final String DEFAULT = "default"; |
| private static final String SHORT = "short"; |
| private static final String MEDIUM = "medium"; |
| private static final String LONG = "long"; |
| private static final String FULL = "full"; |
| |
| private int getStyle(String style) { |
| int ret = DateFormat.DEFAULT; |
| if (style != null) { |
| if (DEFAULT.equalsIgnoreCase(style)) { |
| ret = DateFormat.DEFAULT; |
| } else if (SHORT.equalsIgnoreCase(style)) { |
| ret = DateFormat.SHORT; |
| } else if (MEDIUM.equalsIgnoreCase(style)) { |
| ret = DateFormat.MEDIUM; |
| } else if (LONG.equalsIgnoreCase(style)) { |
| ret = DateFormat.LONG; |
| } else if (FULL.equalsIgnoreCase(style)) { |
| ret = DateFormat.FULL; |
| } else { |
| throw new IllegalArgumentException( |
| "Invalid style: \"" |
| + style |
| + "\": should be \"default\" or \"short\" or \"medium\" or \"long\" or \"full\""); |
| } |
| } |
| return ret; |
| } |
| } |