001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019: package org.openharmonise.swing.datefield;
020:
021: import java.util.ArrayList;
022: import java.util.Calendar;
023: import java.util.HashMap;
024: import java.util.List;
025:
026: /**
027: * Parses date format strings into {@link org.openharmonise.swing.datefield.DateFormatBlock}
028: * objects. The format string is based on the {@link java.text.SimpleDateFormat} one with some
029: * caveats:
030: *
031: * 1) Only numerical representations of dates are allowed, except for the Era
032: * field with can only be represented as "AD" or "BC".
033: *
034: * 2) The format length for each field needs to be the same length as the expected
035: * input. So for a 4 digit year you must use "yyyy", where as the {@link java.text.SimpleDateFormat}
036: * class will accept "yyy" and "yyyyy". The only excpetion to this rule is the Era field
037: * which must be represented as "G".
038: *
039: * @author Matthew Large
040: * @version $Revision: 1.1 $
041: *
042: */
043: public class DateFormatParser {
044:
045: /**
046: * Full date format string.
047: */
048: private String m_sFormat = null;
049:
050: /**
051: * List of {@link DateFormatBlock} objects.
052: */
053: private ArrayList m_formatBlocks = new ArrayList();
054:
055: /**
056: * Map of pattern characters to {@link Calendar} date fields.
057: */
058: private static final HashMap m_mPatternInfo = new HashMap();
059:
060: static {
061: m_mPatternInfo.put("G", new Integer(Calendar.ERA));
062: m_mPatternInfo.put("y", new Integer(Calendar.YEAR));
063: m_mPatternInfo.put("M", new Integer(Calendar.MONTH));
064: m_mPatternInfo.put("w", new Integer(Calendar.WEEK_OF_YEAR));
065: m_mPatternInfo.put("W", new Integer(Calendar.WEEK_OF_MONTH));
066: m_mPatternInfo.put("D", new Integer(Calendar.DAY_OF_YEAR));
067: m_mPatternInfo.put("d", new Integer(Calendar.DAY_OF_MONTH));
068: m_mPatternInfo.put("F", new Integer(
069: Calendar.DAY_OF_WEEK_IN_MONTH));
070: m_mPatternInfo.put("E", new Integer(Calendar.DAY_OF_WEEK));
071: m_mPatternInfo.put("a", new Integer(Calendar.AM_PM));
072: m_mPatternInfo.put("H", new Integer(Calendar.HOUR_OF_DAY));
073: m_mPatternInfo.put("k", new Integer(Calendar.HOUR_OF_DAY));
074: m_mPatternInfo.put("K", new Integer(Calendar.HOUR));
075: m_mPatternInfo.put("h", new Integer(Calendar.HOUR));
076: m_mPatternInfo.put("m", new Integer(Calendar.MINUTE));
077: m_mPatternInfo.put("s", new Integer(Calendar.SECOND));
078: m_mPatternInfo.put("S", new Integer(Calendar.MILLISECOND));
079: m_mPatternInfo.put("z", new Integer(Calendar.ZONE_OFFSET));
080: m_mPatternInfo.put("Z", new Integer(Calendar.ZONE_OFFSET));
081: }
082:
083: /**
084: * Constructs a new date format parser.
085: *
086: * @param sFormat Date format
087: */
088: public DateFormatParser(String sFormat) {
089: super ();
090: this .m_sFormat = sFormat;
091: this .setup();
092: }
093:
094: /**
095: * Configures this date format parser.
096: *
097: */
098: private void setup() {
099: int nPos = 0;
100: int nInputPosition = 0;
101:
102: while (nPos <= this .m_sFormat.length() - 1) {
103: DateFormatBlock block = this .getNextBlock(nPos,
104: nInputPosition);
105: this .m_formatBlocks.add(block);
106: nPos = nPos + block.getFormat().length();
107: nInputPosition = nInputPosition + block.getInputLength();
108: }
109: }
110:
111: /**
112: * Returns the dateformat blocks.
113: *
114: * @return List of {@link DateFormatBlock} objects
115: */
116: public List getFormatBlocks() {
117: return this .m_formatBlocks;
118: }
119:
120: /**
121: * Returns the next date format pattern in the date format string.
122: *
123: * @param nPosition Current position in date format string
124: * @param nInputPosition Current input date value string position
125: * @return Next date format block
126: */
127: private DateFormatBlock getNextBlock(int nPosition,
128: int nInputPosition) {
129: DateFormatBlock block = null;
130: boolean bFetchingActiveBlock = false;
131: String sFormatBlock = new String();
132:
133: int nCurrentPosition = nPosition;
134:
135: String sFirst = this .m_sFormat.substring(nPosition,
136: nPosition + 1);
137: bFetchingActiveBlock = DateFormatParser.m_mPatternInfo.keySet()
138: .contains(sFirst);
139:
140: int nCalendarField = -1;
141: if (bFetchingActiveBlock) {
142: nCalendarField = ((Integer) DateFormatParser.m_mPatternInfo
143: .get(sFirst)).intValue();
144: }
145:
146: String sTemp = sFirst;
147: boolean bEnd = false;
148:
149: while ((bFetchingActiveBlock && DateFormatParser.m_mPatternInfo
150: .keySet().contains(sTemp))
151: || ((!bFetchingActiveBlock && !DateFormatParser.m_mPatternInfo
152: .keySet().contains(sTemp)))) {
153: sFormatBlock = sFormatBlock + sTemp;
154: nCurrentPosition++;
155: if (nCurrentPosition <= this .m_sFormat.length() - 1) {
156: sTemp = this .m_sFormat.substring(nCurrentPosition,
157: nCurrentPosition + 1);
158: } else {
159: break;
160: }
161: }
162:
163: int nInputLength = -1;
164:
165: if (sFormatBlock.equalsIgnoreCase("G")) {
166: nInputLength = 2;
167: } else if (!bFetchingActiveBlock) {
168: String sFormatTemp = sFormatBlock.replaceAll("'", "");
169: nInputLength = sFormatTemp.length();
170: } else {
171: nInputLength = sFormatBlock.length();
172: }
173:
174: String sClearedValue = null;
175: String sEntryValue = null;
176:
177: if (bFetchingActiveBlock) {
178: if (sFormatBlock.equalsIgnoreCase("G")) {
179: sClearedValue = "AD";
180: sEntryValue = "G";
181: } else if (sFormatBlock.equalsIgnoreCase("yyyy")) {
182: nInputLength = 8;
183: sClearedValue = " ccyy";
184: sEntryValue = " ccyy";
185: } else {
186: StringBuffer sBuff = new StringBuffer(sFormatBlock);
187: if (sBuff.length() < nInputLength) {
188: for (int i = sBuff.length(); i < nInputLength; i++) {
189: sBuff.append(" ");
190: }
191: }
192: sClearedValue = sBuff.toString();
193: sEntryValue = sBuff.toString();
194: }
195: } else {
196: sClearedValue = sFormatBlock.replaceAll("'", "");
197: sEntryValue = sFormatBlock.replaceAll("'", "");
198: }
199:
200: block = new DateFormatBlock(sFormatBlock, bFetchingActiveBlock,
201: nInputPosition, nInputLength, sClearedValue,
202: nCalendarField, sEntryValue);
203:
204: return block;
205: }
206:
207: public static void main(String[] args) {
208: DateFormatParser dfp = new DateFormatParser("yyyy-MM-dd G");
209: DateFormatParser dfp2 = new DateFormatParser(
210: "yyyy-MM-dd'T'HH:mm:ss G");
211: }
212:
213: }
|