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:
018: package org.apache.xerces.impl.dv.xs;
019:
020: import javax.xml.datatype.DatatypeConstants;
021: import javax.xml.datatype.XMLGregorianCalendar;
022:
023: import org.apache.xerces.impl.dv.InvalidDatatypeValueException;
024: import org.apache.xerces.impl.dv.ValidationContext;
025:
026: /**
027: * Validator for <gMonth> datatype (W3C Schema Datatypes)
028: *
029: * @xerces.internal
030: *
031: * @author Elena Litani
032: * @author Gopal Sharma, SUN Microsystem Inc.
033: *
034: * @version $Id: MonthDV.java 446745 2006-09-15 21:43:58Z mrglavas $
035: */
036:
037: public class MonthDV extends AbstractDateTimeDV {
038:
039: /**
040: * Convert a string to a compiled form
041: *
042: * @param content The lexical representation of gMonth
043: * @return a valid and normalized gMonth object
044: */
045: public Object getActualValue(String content,
046: ValidationContext context)
047: throws InvalidDatatypeValueException {
048: try {
049: return parse(content);
050: } catch (Exception ex) {
051: throw new InvalidDatatypeValueException(
052: "cvc-datatype-valid.1.2.1", new Object[] { content,
053: "gMonth" });
054: }
055: }
056:
057: /**
058: * Parses, validates and computes normalized version of gMonth object
059: *
060: * @param str The lexical representation of gMonth object --MM
061: * with possible time zone Z or (-),(+)hh:mm
062: * @return normalized date representation
063: * @exception SchemaDateTimeException Invalid lexical representation
064: */
065: protected DateTimeData parse(String str)
066: throws SchemaDateTimeException {
067: DateTimeData date = new DateTimeData(str, this );
068: int len = str.length();
069:
070: //set constants
071: date.year = YEAR;
072: date.day = DAY;
073: if (str.charAt(0) != '-' || str.charAt(1) != '-') {
074: throw new SchemaDateTimeException(
075: "Invalid format for gMonth: " + str);
076: }
077: int stop = 4;
078: date.month = parseInt(str, 2, stop);
079:
080: // REVISIT: allow both --MM and --MM-- now.
081: // need to remove the following 4 lines to disallow --MM--
082: // when the errata is offically in the rec.
083: if (str.length() >= stop + 2 && str.charAt(stop) == '-'
084: && str.charAt(stop + 1) == '-') {
085: stop += 2;
086: }
087: if (stop < len) {
088: if (!isNextCharUTCSign(str, stop, len)) {
089: throw new SchemaDateTimeException(
090: "Error in month parsing: " + str);
091: } else {
092: getTimeZone(str, date, stop, len);
093: }
094: }
095: //validate and normalize
096: validateDateTime(date);
097:
098: //save unnormalized values
099: saveUnnormalized(date);
100:
101: if (date.utc != 0 && date.utc != 'Z') {
102: normalize(date);
103: }
104: date.position = 1;
105: return date;
106: }
107:
108: /**
109: * Overwrite compare algorithm to optimize month comparison
110: *
111: * REVISIT: this one is lack of the third parameter: boolean strict, so it
112: * doesn't override the method in the base. But maybe this method
113: * is not correctly implemented, and I did encounter errors when
114: * trying to add the extra parameter. I'm leaving it as is. -SG
115: *
116: * @param date1
117: * @param date2
118: * @return less, greater, equal, indeterminate
119: */
120: /*protected short compareDates(DateTimeData date1, DateTimeData date2) {
121:
122: if ( date1.utc==date2.utc ) {
123: return (short)((date1.month>=date2.month)?(date1.month>date2.month)?1:0:-1);
124: }
125:
126: if ( date1.utc=='Z' || date2.utc=='Z' ) {
127:
128: if ( date1.month==date2.month ) {
129: //--05--Z and --05--
130: return INDETERMINATE;
131: }
132: if ( (date1.month+1 == date2.month || date1.month-1 == date2.month) ) {
133: //--05--Z and (--04-- or --05--)
134: //REVISIT: should this case be less than or equal?
135: // maxExclusive should fail but what about maxInclusive
136: //
137: return INDETERMINATE;
138: }
139: }
140:
141: if ( date1.month<date2.month ) {
142: return -1;
143: }
144: else {
145: return 1;
146: }
147:
148: }*/
149:
150: /**
151: * Converts month object representation to String
152: *
153: * @param date month object
154: * @return lexical representation of month: --MM with an optional time zone sign
155: */
156: protected String dateToString(DateTimeData date) {
157: StringBuffer message = new StringBuffer(5);
158: message.append('-');
159: message.append('-');
160: append(message, date.month, 2);
161: append(message, (char) date.utc, 0);
162: return message.toString();
163: }
164:
165: protected XMLGregorianCalendar getXMLGregorianCalendar(
166: DateTimeData date) {
167: return factory.newXMLGregorianCalendar(
168: DatatypeConstants.FIELD_UNDEFINED, date.unNormMonth,
169: DatatypeConstants.FIELD_UNDEFINED,
170: DatatypeConstants.FIELD_UNDEFINED,
171: DatatypeConstants.FIELD_UNDEFINED,
172: DatatypeConstants.FIELD_UNDEFINED,
173: DatatypeConstants.FIELD_UNDEFINED, date.timezoneHr * 60
174: + date.timezoneMin);
175: }
176: }
|