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