001: /*
002: Copyright © 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
003:
004: Contributors:
005: * Stefano Chizzolini (original code developer, http://www.stefanochizzolini.it):
006: contributed code is Copyright © 2006 by Stefano Chizzolini.
007:
008: This file should be part of the source code distribution of "PDF Clown library"
009: (the Program): see the accompanying README files for more info.
010:
011: This Program is free software; you can redistribute it and/or modify it under
012: the terms of the GNU General Public License as published by the Free Software
013: Foundation; either version 2 of the License, or (at your option) any later version.
014:
015: This Program is distributed in the hope that it will be useful, but WITHOUT ANY
016: WARRANTY, either expressed or implied; without even the implied warranty of
017: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
018:
019: You should have received a copy of the GNU General Public License along with this
020: Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
021:
022: Redistribution and use, with or without modification, are permitted provided that such
023: redistributions retain the above copyright notice, license and disclaimer, along with
024: this list of conditions.
025: */
026:
027: package it.stefanochizzolini.clown.objects;
028:
029: import it.stefanochizzolini.clown.files.File;
030: import java.text.SimpleDateFormat;
031: import java.util.Date;
032:
033: /**
034: PDF date object.
035: */
036: public class PdfDate extends PdfAtomicObject<Date> implements
037: IPdfString {
038: /*
039: NOTE: although the spec [PDF:1.6:3.8.3] prescribes that PdfDate IS a
040: PdfLiteral, we chose to treat PdfDate as a type non-derived from
041: PdfLiteral, 'cause its internal representation is definitely unmatchable
042: (could anyone else deal consistently with generic inheritance,
043: matching String-s and Date-s?).
044: IPdfString interface has been added to support its external representation
045: as a string.
046: */
047: // <class>
048: // <static>
049: // <fields>
050: protected static final SimpleDateFormat formatter;
051: // </fields>
052:
053: // <constructors>
054: static {
055: formatter = new SimpleDateFormat("yyyyMMddHHmmssZ");
056: }
057:
058: // </constructors>
059:
060: // <interface>
061: // <public>
062: /**
063: Converts a date value to a PDF-formatted date literal.
064: */
065: public static String toPdf(Date value) {
066: return PdfLiteral.toPdf(format(value));
067: }
068:
069: /**
070: Converts a PDF-formatted date value to a date value.
071: */
072: public static Date toDate(String value) {
073: //TODO:IMPL this code is quite ugly... is there a more elegant solution (regex)?
074: // Normalize datetime value.
075: // Cut leading "D:" tag!
076: value = value.substring(2);
077: int length = value.length();
078: switch (length) {
079: case 8: // Date only.
080: value += "000000+0000";
081: break;
082: case 14: // Datetime without timezone.
083: value += "+0000";
084: break;
085: case 15: // Datetime at UT timezone ("Z" tag).
086: value = value.substring(0, length - 1) + "+0000";
087: break;
088: case 17: // Datetime at non-UT timezone without minutes.
089: value += "00";
090: break;
091: case 21: // Datetime at non-UT full timezone ("'mm'" PDF timezone-minutes format).
092: value = value.substring(0, length - 1).replace("\'", "");
093: break;
094: }
095:
096: try {
097: // Parse datetime value!
098: return formatter.parse(value);
099: } catch (Exception e) {
100: // Propagate the exception!
101: throw new RuntimeException(e);
102: }
103: }
104:
105: // </public>
106:
107: // <protected>
108: /**
109: Formats a date value as a PDF-formatted date value.
110: */
111: protected static String format(Date value) {
112: String formattedValue = formatter.format(value);
113:
114: return ("D:" + formattedValue.substring(0, 17) + '\''
115: + formattedValue.substring(17) + '\'');
116: }
117:
118: // </protected>
119: // </interface>
120: // </static>
121:
122: // <dynamic>
123: // <constructors>
124: public PdfDate() {
125: }
126:
127: public PdfDate(Date value) {
128: setValue(value);
129: }
130:
131: // </constructors>
132:
133: // <interface>
134: // <public>
135: @Override
136: public Object clone(File context) {
137: // Shallow copy.
138: PdfDate clone = (PdfDate) super .clone();
139:
140: // Deep copy.
141: clone.setValue((Date) getValue().clone()); // Date class is mutable.
142:
143: return clone;
144: }
145:
146: @Override
147: public String toPdf() {
148: return PdfDate.toPdf(getValue());
149: }
150:
151: // <IPdfString>
152: public String getStringValue() {
153: return format(getValue());
154: }
155:
156: public void setStringValue(String value) {
157: setValue(toDate(value));
158: }
159: // </IPdfString>
160: // </public>
161: // </interface>
162: // </dynamic>
163: // </class>
164: }
|