/*
* @(#)$Id: XSDatatypeImpl.java 1650 2005-03-31 23:19:14Z kohsuke $
*
* 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 org.relaxng.datatype.DatatypeException;
import org.relaxng.datatype.DatatypeStreamingValidator;
import org.relaxng.datatype.ValidationContext;
import org.relaxng.datatype.helpers.StreamingValidatorImpl;
import java.util.Vector;
/**
* base implementaion for XSDatatype interface.
*
* <p>
* This class should be considered as the implementation-detail, and
* applications should not access this class.
*
* @author <a href="mailto:kohsuke.kawaguchi@eng.sun.com">Kohsuke KAWAGUCHI</a>
*/
public abstract class XSDatatypeImpl implements XSDatatype {
private final String namespaceUri;
public String getNamespaceUri() { return namespaceUri; }
private final String typeName;
public String getName() { return typeName; }
/** this field characterizes how this datatype treats white space. */
public final WhiteSpaceProcessor whiteSpace;
protected XSDatatypeImpl( String uri, String typeName, WhiteSpaceProcessor whiteSpace ) {
this.namespaceUri = uri;
this.typeName = typeName;
this.whiteSpace = whiteSpace;
}
final public Object createValue( String lexicalValue, ValidationContext context ) {
return _createValue(whiteSpace.process(lexicalValue),context);
}
/**
* converts a whitespace-processed lexical value into the corresponding value object
*/
abstract protected Object _createValue( String content, ValidationContext context );
final public void checkValid(String content, ValidationContext context) throws DatatypeException {
_checkValid(whiteSpace.process(content),context);
}
/** actual 'meat' of the checkValid method */
abstract protected void _checkValid(String content, ValidationContext context) throws DatatypeException;
final public Object createJavaObject( String literal, ValidationContext context ) {
return _createJavaObject(whiteSpace.process(literal),context);
}
abstract protected Object _createJavaObject( String literal, ValidationContext context );
final public boolean isValid( String literal, ValidationContext context ) {
// step.1 white space processing
literal = whiteSpace.process(literal);
if( needValueCheck() )
// constraint facet that needs computation of value is specified.
return _createValue(literal,context)!=null;
else
// lexical validation is enough.
return checkFormat(literal,context);
}
// default implementation
public boolean isAlwaysValid() { return false; }
public DatatypeStreamingValidator createStreamingValidator( ValidationContext context ) {
return new StreamingValidatorImpl(this,context);
}
abstract protected boolean checkFormat( String literal, ValidationContext context );
protected boolean needValueCheck() { return false; }
/**
* gets the facet object that restricts the specified facet
*
* @return null
* if no such facet object exists.
*/
public DataTypeWithFacet getFacetObject( String facetName ) {
XSDatatype dt = getBaseType();
if(dt!=null) return dt.getFacetObject(facetName);
else return null;
}
public String[] getApplicableFacetNames() {
Vector vec = new Vector();
String[] facetNames = new String[]{
FACET_ENUMERATION,
FACET_FRACTIONDIGITS,FACET_TOTALDIGITS,
FACET_LENGTH,FACET_MINLENGTH,FACET_MAXLENGTH,
FACET_MAXEXCLUSIVE,FACET_MINEXCLUSIVE,
FACET_MAXINCLUSIVE,FACET_MININCLUSIVE,
FACET_PATTERN,
FACET_WHITESPACE};
for( int i=0; i<facetNames.length; i++ )
if(isFacetApplicable(facetNames[i])==APPLICABLE)
vec.add(facetNames[i]);
return (String[])vec.toArray(new String[vec.size()]);
}
/**
* gets the concrete type object of the restriction chain.
*/
abstract public ConcreteType getConcreteType();
public final boolean sameValue( Object o1, Object o2 ) {
if(o1==null || o2==null) return false;
return o1.equals(o2);
}
public final int valueHashCode( Object o ) {
return o.hashCode();
}
public final boolean isDerivedTypeOf( XSDatatype baseType, boolean restrictionAllowed ) {
return isDerivedTypeOf(baseType,this,restrictionAllowed);
}
/**
* an implementation of
* <a href="http://www.w3.org/TR/xmlschema-1/#cos-st-derived-ok">"Type Derivation OK (Simple)"</a>
* of the spec.
*
* @see #isDerivedTypeOf(XSDatatype,boolean)
*/
public static boolean isDerivedTypeOf( XSDatatype base, XSDatatype derived, boolean restrictionAllowed ) {
if( base==derived ) return true;
if( !restrictionAllowed ) return false;
if( base==SimpleURType.theInstance ) return true;
if( base.getVariety()==VARIETY_UNION ) {
// if the base type is an union variety,
// type derivation is OK if "derived" is derived from one of member types.
XSDatatype t = base;
while(!(t instanceof UnionType))
t = t.getBaseType();
XSDatatypeImpl[] memberTypes = ((UnionType)t).memberTypes;
for( int i=0; i<memberTypes.length; i++ )
if( isDerivedTypeOf( memberTypes[i], derived, restrictionAllowed ) )
return true;
}
while( derived!=SimpleURType.theInstance ) {
if( base==derived )
return true;
derived = derived.getBaseType();
}
return false;
}
public XSDatatype getAncestorBuiltinType() {
XSDatatype dt = this;
while( !XMLSCHEMA_NSURI.equals(dt.getNamespaceUri()) )
dt = dt.getBaseType();
return dt;
}
/**
* A property for RELAX NG DTD compatibility datatypes.
* <code>ID_TYPE_NULL</code> is returned by default.
*/
public int getIdType() {
return ID_TYPE_NULL;
}
/**
* A property for RELAX NG DTD compatibility datatypes.
* Context-independent by default.
*/
public boolean isContextDependent() {
return false;
}
protected static final ValidationContext serializedValueChecker =
new ValidationContext(){
public boolean isNotation( String s ) { return true; }
public boolean isUnparsedEntity( String s ) { return true; }
public String resolveNamespacePrefix( String ns ) { return "abc"; }
public String getBaseUri() { return null; }
};
public static String localize( String prop, Object[] args ) {
return java.text.MessageFormat.format(
java.util.ResourceBundle.getBundle("com.sun.msv.datatype.xsd.Messages").getString(prop),
args );
}
public static String localize( String prop ) {
return localize( prop, null );
}
public static String localize( String prop, Object arg1 ) {
return localize( prop, new Object[]{arg1} );
}
public static String localize( String prop, Object arg1, Object arg2 ) {
return localize( prop, new Object[]{arg1,arg2} );
}
public static String localize( String prop, Object arg1, Object arg2, Object arg3 ) {
return localize( prop, new Object[]{arg1,arg2,arg3} );
}
public static final String ERR_INAPPROPRIATE_FOR_TYPE =
"DataTypeErrorDiagnosis.InappropriateForType";
public static final String ERR_TOO_MUCH_PRECISION =
"DataTypeErrorDiagnosis.TooMuchPrecision";
public static final String ERR_TOO_MUCH_SCALE =
"DataTypeErrorDiagnosis.TooMuchScale";
public static final String ERR_ENUMERATION =
"DataTypeErrorDiagnosis.Enumeration";
public static final String ERR_ENUMERATION_WITH_ARG =
"DataTypeErrorDiagnosis.Enumeration.Arg";
public static final String ERR_OUT_OF_RANGE =
"DataTypeErrorDiagnosis.OutOfRange";
public static final String ERR_LENGTH =
"DataTypeErrorDiagnosis.Length";
public static final String ERR_MINLENGTH =
"DataTypeErrorDiagnosis.MinLength";
public static final String ERR_MAXLENGTH =
"DataTypeErrorDiagnosis.MaxLength";
public static final String ERR_PATTERN_1 =
"DataTypeErrorDiagnosis.Pattern.1";
public static final String ERR_PATTERN_MANY =
"DataTypeErrorDiagnosis.Pattern.Many";
public static final String ERR_INVALID_ITEMTYPE =
"BadTypeException.InvalidItemType";
public static final String ERR_INVALID_MEMBER_TYPE =
"BadTypeException.InvalidMemberType";
public static final String ERR_INVALID_BASE_TYPE =
"BadTypeException.InvalidBaseType";
public static final String ERR_INVALID_WHITESPACE_VALUE =
"WhiteSpaceProcessor.InvalidWhiteSpaceValue";
public static final String ERR_PARSE_ERROR = "PatternFacet.ParseError";
public static final String ERR_INVALID_VALUE_FOR_THIS_TYPE =
"EnumerationFacet.InvalidValueForThisType";
public final static String ERR_FACET_MUST_BE_NON_NEGATIVE_INTEGER =
"BadTypeException.FacetMustBeNonNegativeInteger";
public final static String ERR_FACET_MUST_BE_POSITIVE_INTEGER =
"BadTypeException.FacetMustBePositiveInteger";
public final static String ERR_OVERRIDING_FIXED_FACET =
"BadTypeException.OverridingFixedFacet";
public final static String ERR_INCONSISTENT_FACETS_1 =
"InconsistentFacets.1";
public final static String ERR_INCONSISTENT_FACETS_2 =
"InconsistentFacets.2";
public final static String ERR_X_AND_Y_ARE_EXCLUSIVE =
"XAndYAreExclusive";
public final static String ERR_LOOSENED_FACET =
"LoosenedFacet";
public final static String ERR_SCALE_IS_GREATER_THAN_PRECISION =
"PrecisionScaleFacet.ScaleIsGraterThanPrecision";
public static final String ERR_DUPLICATE_FACET =
"BadTypeException.DuplicateFacet";
public static final String ERR_NOT_APPLICABLE_FACET =
"BadTypeException.NotApplicableFacet";
public static final String ERR_EMPTY_UNION =
"BadTypeException.EmptyUnion";
// serialization support
private static final long serialVersionUID = 1;
}