001: package net.sf.saxon.value;
002:
003: import net.sf.saxon.expr.XPathContext;
004: import net.sf.saxon.om.FastStringBuffer;
005: import net.sf.saxon.trans.DynamicError;
006: import net.sf.saxon.trans.XPathException;
007: import net.sf.saxon.type.*;
008:
009: import java.util.regex.Matcher;
010: import java.util.regex.Pattern;
011:
012: /**
013: * Implementation of the xs:gMonth data type
014: */
015:
016: public class GMonthValue extends DateValue {
017:
018: private static Pattern regex = Pattern
019: .compile("--([0-9][0-9])(--)?(Z|[+-][0-9][0-9]:[0-9][0-9])?");
020:
021: // this tolerates the bogus format --MM-- which was wrongly permitted by the original schema spec
022:
023: public GMonthValue() {
024: };
025:
026: public GMonthValue(CharSequence value) throws XPathException {
027: Matcher m = regex.matcher(value);
028: if (!m.matches()) {
029: throw new DynamicError("Cannot convert '" + value
030: + "' to a gMonth");
031: }
032: String base = m.group(1);
033: String tz = m.group(3);
034: String date = "2000-" + base + "-01" + (tz == null ? "" : tz);
035: setLexicalValue(date);
036: }
037:
038: protected GMonthValue(byte month, int tz) {
039: this .year = 2000;
040: this .month = month;
041: this .day = 1;
042: setTimezoneInMinutes(tz);
043: }
044:
045: /**
046: * Determine the data type of the expression
047: * @return Type.G_MONTH_TYPE,
048: * @param th
049: */
050:
051: public ItemType getItemType(TypeHierarchy th) {
052: return Type.G_MONTH_TYPE;
053: }
054:
055: /**
056: * Make a copy of this date, time, or dateTime value
057: */
058:
059: public CalendarValue copy() {
060: return new GMonthValue(month, getTimezoneInMinutes());
061: }
062:
063: /**
064: * Convert to target data type
065: * @param requiredType an integer identifying the required atomic type
066: * @param context
067: * @return an AtomicValue, a value of the required type; or an ErrorValue
068: */
069:
070: public AtomicValue convertPrimitive(BuiltInAtomicType requiredType,
071: boolean validate, XPathContext context) {
072: switch (requiredType.getPrimitiveType()) {
073: case Type.G_MONTH:
074: case Type.ANY_ATOMIC:
075: case Type.ITEM:
076: return this ;
077:
078: case Type.STRING:
079: return new StringValue(getStringValueCS());
080: case Type.UNTYPED_ATOMIC:
081: return new UntypedAtomicValue(getStringValueCS());
082: default:
083: ValidationException err = new ValidationException(
084: "Cannot convert gMonth to "
085: + requiredType.getDisplayName());
086: err.setErrorCode("XPTY0004");
087: err.setIsTypeError(true);
088: return new ValidationErrorValue(err);
089: }
090: }
091:
092: public CharSequence getStringValueCS() {
093:
094: FastStringBuffer sb = new FastStringBuffer(16);
095:
096: sb.append("--");
097: appendTwoDigits(sb, month);
098:
099: if (hasTimezone()) {
100: appendTimezone(sb);
101: }
102:
103: return sb;
104:
105: }
106: }
107:
108: //
109: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
110: // you may not use this file except in compliance with the License. You may obtain a copy of the
111: // License at http://www.mozilla.org/MPL/
112: //
113: // Software distributed under the License is distributed on an "AS IS" basis,
114: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
115: // See the License for the specific language governing rights and limitations under the License.
116: //
117: // The Original Code is: all this file.
118: //
119: // The Initial Developer of the Original Code is Saxonica Limited
120: //
121: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
122: //
123: // Contributor(s): none
124: //
|