001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.template.instruction;
018:
019: import java.text.DateFormat;
020: import java.text.SimpleDateFormat;
021: import java.util.Locale;
022: import java.util.Stack;
023: import java.util.TimeZone;
024:
025: import org.apache.cocoon.components.expression.ExpressionContext;
026: import org.apache.cocoon.template.environment.ErrorHolder;
027: import org.apache.cocoon.template.environment.ExecutionContext;
028: import org.apache.cocoon.template.environment.ParsingContext;
029: import org.apache.cocoon.template.expression.JXTExpression;
030: import org.apache.cocoon.template.expression.StringTemplateParser;
031: import org.apache.cocoon.template.script.event.Event;
032: import org.apache.cocoon.template.script.event.StartElement;
033: import org.apache.cocoon.xml.XMLConsumer;
034: import org.xml.sax.Attributes;
035: import org.xml.sax.Locator;
036: import org.xml.sax.SAXException;
037: import org.xml.sax.SAXParseException;
038:
039: /**
040: * @version SVN $Id: FormatDate.java 449189 2006-09-23 06:52:29Z crossley $
041: */
042: public class FormatDate extends LocaleAwareInstruction {
043: private static final String DATE = "date";
044: private static final String TIME = "time";
045: private static final String DATETIME = "both";
046:
047: private JXTExpression var;
048: private JXTExpression value;
049: private JXTExpression type;
050: private JXTExpression pattern;
051: private JXTExpression timeZone;
052: private JXTExpression dateStyle;
053: private JXTExpression timeStyle;
054:
055: public FormatDate(ParsingContext parsingContext, StartElement raw,
056: Attributes attrs, Stack stack) throws SAXException {
057: super (parsingContext, raw, attrs, stack);
058:
059: Locator locator = getLocation();
060:
061: StringTemplateParser expressionCompiler = parsingContext
062: .getStringTemplateParser();
063: this .var = expressionCompiler.compileExpr(
064: attrs.getValue("var"), null, locator);
065: this .value = expressionCompiler.compileExpr(attrs
066: .getValue("value"), null, locator);
067: this .type = expressionCompiler.compileExpr(attrs
068: .getValue("type"), null, locator);
069: this .pattern = expressionCompiler.compileExpr(attrs
070: .getValue("pattern"), null, locator);
071: this .timeZone = expressionCompiler.compileExpr(attrs
072: .getValue("timeZone"), null, locator);
073: this .dateStyle = expressionCompiler.compileExpr(attrs
074: .getValue("dateStyle"), null, locator);
075: this .timeStyle = expressionCompiler.compileExpr(attrs
076: .getValue("timeStyle"), null, locator);
077: }
078:
079: public Event execute(final XMLConsumer consumer,
080: ExpressionContext expressionContext,
081: ExecutionContext executionContext,
082: MacroContext macroContext, Event startEvent, Event endEvent)
083: throws SAXException {
084: try {
085: String result = format(expressionContext);
086: if (result != null) {
087: char[] chars = result.toCharArray();
088: consumer.characters(chars, 0, chars.length);
089: }
090: } catch (Exception e) {
091: throw new SAXParseException(e.getMessage(), getLocation(),
092: e);
093: } catch (Error err) {
094: throw new SAXParseException(err.getMessage(),
095: getLocation(), new ErrorHolder(err));
096: }
097: return getNext();
098: }
099:
100: private String format(ExpressionContext expressionContext)
101: throws Exception {
102: String var = this .var == null ? null : this .var
103: .getStringValue(expressionContext);
104: Object value = this .value == null ? null : this .value
105: .getValue(expressionContext);
106:
107: String pattern = this .pattern == null ? null : this .pattern
108: .getStringValue(expressionContext);
109: Object timeZone = this .timeZone == null ? null : this .timeZone
110: .getValue(expressionContext);
111:
112: String type = this .type == null ? null : this .type
113: .getStringValue(expressionContext);
114: String timeStyle = this .timeStyle == null ? null
115: : this .timeStyle.getStringValue(expressionContext);
116: String dateStyle = this .dateStyle == null ? null
117: : this .dateStyle.getStringValue(expressionContext);
118:
119: String formatted = null;
120:
121: // Create formatter
122: Locale locale = getLocale(expressionContext);
123: DateFormat formatter = createFormatter(locale, type, dateStyle,
124: timeStyle);
125: // Apply pattern, if present
126: if (pattern != null) {
127: try {
128: ((SimpleDateFormat) formatter).applyPattern(pattern);
129: } catch (ClassCastException cce) {
130: formatter = new SimpleDateFormat(pattern, locale);
131: }
132: }
133: // Set time zone
134: TimeZone tz = null;
135: if ((timeZone instanceof String)
136: && ((String) timeZone).equals("")) {
137: timeZone = null;
138: }
139: if (timeZone != null) {
140: if (timeZone instanceof String) {
141: tz = TimeZone.getTimeZone((String) timeZone);
142: } else if (timeZone instanceof TimeZone) {
143: tz = (TimeZone) timeZone;
144: } else {
145: throw new IllegalArgumentException(
146: "Illegal timeZone value: \"" + timeZone + "\"");
147: }
148: }
149: if (tz != null) {
150: formatter.setTimeZone(tz);
151: }
152: formatted = formatter.format(value);
153: if (var != null) {
154: expressionContext.put(var, formatted);
155: return null;
156: }
157: return formatted;
158: }
159:
160: private DateFormat createFormatter(Locale loc, String type,
161: String dateStyle, String timeStyle) throws Exception {
162: DateFormat formatter = null;
163: if ((type == null) || DATE.equalsIgnoreCase(type)) {
164: formatter = DateFormat.getDateInstance(getStyle(dateStyle),
165: loc);
166: } else if (TIME.equalsIgnoreCase(type)) {
167: formatter = DateFormat.getTimeInstance(getStyle(timeStyle),
168: loc);
169: } else if (DATETIME.equalsIgnoreCase(type)) {
170: formatter = DateFormat.getDateTimeInstance(
171: getStyle(dateStyle), getStyle(timeStyle), loc);
172: } else {
173: throw new IllegalArgumentException("Invalid type: \""
174: + type + "\"");
175: }
176: return formatter;
177: }
178:
179: private static final String DEFAULT = "default";
180: private static final String SHORT = "short";
181: private static final String MEDIUM = "medium";
182: private static final String LONG = "long";
183: private static final String FULL = "full";
184:
185: private int getStyle(String style) {
186: int ret = DateFormat.DEFAULT;
187: if (style != null) {
188: if (DEFAULT.equalsIgnoreCase(style)) {
189: ret = DateFormat.DEFAULT;
190: } else if (SHORT.equalsIgnoreCase(style)) {
191: ret = DateFormat.SHORT;
192: } else if (MEDIUM.equalsIgnoreCase(style)) {
193: ret = DateFormat.MEDIUM;
194: } else if (LONG.equalsIgnoreCase(style)) {
195: ret = DateFormat.LONG;
196: } else if (FULL.equalsIgnoreCase(style)) {
197: ret = DateFormat.FULL;
198: } else {
199: throw new IllegalArgumentException(
200: "Invalid style: \""
201: + style
202: + "\": should be \"default\" or \"short\" or \"medium\" or \"long\" or \"full\"");
203: }
204: }
205: return ret;
206: }
207: }
|