/* * @(#)$Id: DateTimeBaseType.java,v 1.24 2002/10/08 22:01:27 kk122374 Exp $ * * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. * * This software is the proprietary information of Sun Microsystems, Inc. * Use is subject to license terms. * */ package com.sun.msv.datatype.xsd; import com.sun.msv.datatype.SerializationContext; import com.sun.msv.datatype.xsd.datetime.ISO8601Parser; import com.sun.msv.datatype.xsd.datetime.IDateTimeValueType; import com.sun.msv.datatype.xsd.datetime.BigDateTimeValueType; import com.sun.msv.datatype.xsd.datetime.TimeZone; import org.relaxng.datatype.ValidationContext; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.util.Calendar; import java.util.SimpleTimeZone; /** * base implementation of dateTime and dateTime-truncated types. * this class uses IDateTimeValueType as the value object. * * @author <a href="mailto:kohsuke.kawaguchi@eng.sun.com">Kohsuke KAWAGUCHI</a> */ abstract class DateTimeBaseType extends BuiltinAtomicType implements Comparator { protected DateTimeBaseType(String typeName) { super(typeName); } final public XSDatatype getBaseType() { return SimpleURType.theInstance; } private static final ISO8601Parser getParser( String content ) throws Exception { return new ISO8601Parser( new ByteArrayInputStream( content.getBytes("UTF8") ) ); } protected final boolean checkFormat( String content, ValidationContext context ) { // string derived types should use _createValue method to check its validity try { runParserL(getParser(content)); return true; } catch( Throwable e ) { return false; } } /** invokes the appropriate lexical parse method to check lexical format */ abstract protected void runParserL( ISO8601Parser p ) throws Exception; public final Object _createValue( String content, ValidationContext context ) { // for string, lexical space is value space by itself try { return runParserV(getParser(content)); } catch( Throwable e ) { return null; } } /** invokes the appropriate value creation method to obtain value object */ abstract protected IDateTimeValueType runParserV( ISO8601Parser p ) throws Exception; /** compare two DateTimeValueType */ public int compare( Object lhs, Object rhs ) { return ((IDateTimeValueType)lhs).compare((IDateTimeValueType)rhs); } public final int isFacetApplicable( String facetName ) { if( facetName.equals(FACET_PATTERN) || facetName.equals(FACET_ENUMERATION) || facetName.equals(FACET_WHITESPACE) || facetName.equals(FACET_MAXINCLUSIVE) || facetName.equals(FACET_MAXEXCLUSIVE) || facetName.equals(FACET_MININCLUSIVE) || facetName.equals(FACET_MINEXCLUSIVE) ) return APPLICABLE; else return NOT_ALLOWED; } /** * formats an integer into the year representation. * That is, at least four digits and no year 0. */ protected String formatYear( int year ) { String s; if( year<=0 ) // negative value s = Integer.toString(1-year); else // positive value s = Integer.toString(year); while(s.length()<4) s = "0"+s; if( year<=0 ) s = "-"+s; return s; } /** * formats BigInteger into year representation. * * That is, at least four digits and no year 0. */ protected String formatYear( BigInteger year ) { String s; if( year.signum()<=0 ) // negative value s = year.negate().add(BigInteger.ONE).toString(); else // positive value s = year.toString(); while(s.length()<4) s = "0"+s; if( year.signum()<=0 ) s = "-"+s; return s; } protected String formatTwoDigits( Integer v ) { return formatTwoDigits(v,0); } /** formats Integer into two-character-wide string. */ protected String formatTwoDigits( Integer v, int offset ) { if(v==null) return "00"; return formatTwoDigits(v.intValue()+offset); } protected String formatTwoDigits( int n ) { // n is always non-negative. if(n<10) return "0"+n; else return Integer.toString(n); } /** formats BigDecimal into two- -wide string. */ protected String formatSeconds( java.math.BigDecimal dec ) { if(dec==null) return "00"; String s = dec.toString(); if( dec.compareTo( new java.math.BigDecimal("10") ) < 0 ) s = "0"+s; return s; } protected String formatSeconds( Calendar cal ) { StringBuffer result = new StringBuffer(); result.append(formatTwoDigits(cal.get(cal.SECOND))); if( cal.isSet(cal.MILLISECOND) ) {// milliseconds String ms = Integer.toString(cal.get(cal.MILLISECOND)); while(ms.length()<3) ms = "0"+ms; // left 0 paddings. result.append('.'); result.append(ms); } return result.toString(); } /** formats time zone specifier. */ protected String formatTimeZone( TimeZone tz ) { if(tz==null) return ""; // no time zone if(tz.minutes==0) return "Z"; // GMT return (tz.minutes<0?"-":"+")+ formatTwoDigits(new Integer(Math.abs(tz.minutes/60)))+":"+ formatTwoDigits(new Integer(Math.abs(tz.minutes)%60)); } /** formats time zone specifier. */ protected String formatTimeZone( Calendar cal ) { // TODO: is it possible for the getTimeZone method to return null? if( cal.getTimeZone()==null ) return ""; StringBuffer result = new StringBuffer(); int offset = cal.getTimeZone().getRawOffset(); if(offset>=0) result.append('+'); else { result.append('-'); offset *= -1; } offset /= 60*1000; // offset is in milli-seconds result.append(formatTwoDigits(offset/60)); result.append(':'); result.append(formatTwoDigits(offset%60)); return result.toString(); } /** converts Number to integer. null object is considered as 0 */ protected static int nullAsZero( Number n ) { if(n==null) return 0; else return n.intValue(); } /** converts our DateTimeValueType to a java-friendly Date type. */ public final Object _createJavaObject( String literal, ValidationContext context ) { IDateTimeValueType v = (IDateTimeValueType)createValue(literal,context); if(v==null) return null; else return v.toCalendar(); } // since we've overrided the createJavaObject method, the serializeJavaObject method // needs to be overrided, too. public abstract String serializeJavaObject( Object value, SerializationContext context ); public Class getJavaObjectType() { return Calendar.class; } }