package client.net.sf.saxon.ce.value; import client.net.sf.saxon.ce.om.StandardNames; import client.net.sf.saxon.ce.trans.XPathException; import client.net.sf.saxon.ce.tree.util.FastStringBuffer; import client.net.sf.saxon.ce.type.AtomicType; import client.net.sf.saxon.ce.type.BuiltInAtomicType; import client.net.sf.saxon.ce.type.ConversionResult; import client.net.sf.saxon.ce.type.ValidationFailure; import com.google.gwt.regexp.shared.MatchResult; import com.google.gwt.regexp.shared.RegExp; /** * Implementation of the xs:gYearMonth data type */ public class GYearMonthValue extends GDateValue { private static RegExp regex = RegExp.compile("(-?[0-9]+-[0-9][0-9])(Z|[+-][0-9][0-9]:[0-9][0-9])?"); private GYearMonthValue(){} public static ConversionResult makeGYearMonthValue(CharSequence value) { MatchResult m = regex.exec(Whitespace.trimWhitespace(value).toString()); if (m == null) { return new ValidationFailure("Cannot convert '" + value + "' to a gYearMonth"); } GYearMonthValue g = new GYearMonthValue(); String base = m.getGroup(1); String tz = m.getGroup(2); String date = (base==null ? "" : base) + "-01" + (tz==null ? "" : tz); g.typeLabel = BuiltInAtomicType.G_YEAR_MONTH; return setLexicalValue(g, date); } public GYearMonthValue(int year, int month, int tz) { this(year, month, tz, BuiltInAtomicType.G_YEAR_MONTH); } public GYearMonthValue(int year, int month, int tz, AtomicType type) { this.year = year; this.month = month; day = 1; setTimezoneInMinutes(tz); typeLabel = type; } /** * Make a copy of this date, time, or dateTime value */ public AtomicValue copy() { GYearMonthValue v = new GYearMonthValue(year, month, getTimezoneInMinutes()); v.typeLabel = typeLabel; return v; } /** * Determine the primitive type of the value. This delivers the same answer as * getItemType().getPrimitiveItemType(). The primitive types are * the 19 primitive types of XML Schema, plus xs:integer, xs:dayTimeDuration and xs:yearMonthDuration, * and xs:untypedAtomic. For external objects, the result is AnyAtomicType. */ public BuiltInAtomicType getPrimitiveType() { return BuiltInAtomicType.G_YEAR_MONTH; } /** * Convert to target data type * @param requiredType an integer identifying the required atomic type * @return an AtomicValue, a value of the required type; or an ErrorValue */ public ConversionResult convertPrimitive(BuiltInAtomicType requiredType, boolean validate) { switch(requiredType.getPrimitiveType()) { case StandardNames.XS_G_YEAR_MONTH: case StandardNames.XS_ANY_ATOMIC_TYPE: return this; case StandardNames.XS_STRING: return new StringValue(getStringValueCS()); case StandardNames.XS_UNTYPED_ATOMIC: return new UntypedAtomicValue(getStringValueCS()); default: ValidationFailure err = new ValidationFailure("Cannot convert gYearMonth to " + requiredType.getDisplayName()); err.setErrorCode("XPTY0004"); return err; } } public CharSequence getPrimitiveStringValue() { FastStringBuffer sb = new FastStringBuffer(FastStringBuffer.TINY); int yr = year; if (year <= 0) { yr = -yr + 1; // no year zero in lexical space for XSD 1.0 if(yr!=0){ sb.append('-'); } } appendString(sb, yr, (yr>9999 ? (yr+"").length() : 4)); sb.append('-'); appendTwoDigits(sb, month); if (hasTimezone()) { appendTimezone(sb); } return sb; } /** * Add a duration to this date/time value * * @param duration the duration to be added (which might be negative) * @return a new date/time value representing the result of adding the duration. The original * object is not modified. * @throws client.net.sf.saxon.ce.trans.XPathException * */ public CalendarValue add(DurationValue duration) throws XPathException { XPathException err = new XPathException("Cannot add a duration to an xs:gYearMonth"); err.setErrorCode("XPTY0004"); throw err; } /** * Return a new date, time, or dateTime with the same normalized value, but * in a different timezone * * @param tz the new timezone, in minutes * @return the date/time in the new timezone */ public CalendarValue adjustTimezone(int tz) { DateTimeValue dt = (DateTimeValue)toDateTime().adjustTimezone(tz); return new GYearMonthValue(dt.getYear(), dt.getMonth(), dt.getTimezoneInMinutes()); } } // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.