/*
* @(#)$Id: DataTypeWithFacet.java,v 1.28 2002/11/07 16:50:03 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 org.relaxng.datatype.*;
import com.sun.msv.datatype.SerializationContext;
/**
* Base implementation of facet-restricted datatype
*
* @author <a href="mailto:kohsuke.kawaguchi@eng.sun.com">Kohsuke KAWAGUCHI</a>
*/
public abstract class DataTypeWithFacet extends XSDatatypeImpl
{
/** immediate base type, which may be a concrete type or DataTypeWithFacet */
public final XSDatatypeImpl baseType;
final public XSDatatype getBaseType() { return baseType; }
/** base concrete type */
protected final ConcreteType concreteType;
/** name of this facet */
public final String facetName;
/** a flag that indicates this type has value-constraint facet.
*
* this value is used to cache this flag.
*/
private final boolean needValueCheckFlag;
/** constructor for facets other than WhiteSpaceFacet */
DataTypeWithFacet( String nsUri, String typeName, XSDatatypeImpl baseType, String facetName, TypeIncubator facets )
throws DatatypeException {
this( nsUri, typeName, baseType, facetName, facets, baseType.whiteSpace );
}
/** constructor for WhiteSpaceFacet */
DataTypeWithFacet( String nsUri, String typeName, XSDatatypeImpl baseType, String facetName, TypeIncubator facets, WhiteSpaceProcessor whiteSpace )
throws DatatypeException {
super(nsUri,typeName, whiteSpace);
this.baseType = baseType;
this.facetName = facetName;
this.concreteType = baseType.getConcreteType();
needValueCheckFlag = baseType.needValueCheck();
int r = baseType.isFacetApplicable(facetName);
switch(r)
{
case APPLICABLE: return; // this facet is applicable to this type. no problem.
case NOT_ALLOWED:
throw new DatatypeException( localize(ERR_NOT_APPLICABLE_FACET, facetName) );
}
}
public boolean isContextDependent() {
return concreteType.isContextDependent();
}
public int getIdType() {
return concreteType.getIdType();
}
public final String displayName() {
if( getName()!=null ) return getName();
else return concreteType.getName()+"-derived";
}
public final int isFacetApplicable( String facetName ) {
return baseType.isFacetApplicable(facetName);
}
protected boolean needValueCheck() { return needValueCheckFlag; }
final public DataTypeWithFacet getFacetObject( String facetName ) {
if(this.facetName.equals(facetName))
return this;
else
return baseType.getFacetObject(facetName);
}
final public ConcreteType getConcreteType() {
return concreteType;
}
final public int getVariety() {
return concreteType.getVariety();
}
final public boolean isFinal( int derivationType ) {
return baseType.isFinal(derivationType);
}
final public String convertToLexicalValue( Object o, SerializationContext context ) {
return concreteType.convertToLexicalValue(o,context);
}
final public Class getJavaObjectType() {
return concreteType.getJavaObjectType();
}
// DatabindableDatatype implementation
final public Object _createJavaObject( String literal, ValidationContext context ) {
// TODO: this can be more efficient
if(isValid(literal,context))
return baseType.createJavaObject(literal,context);
else
return null;
}
public String serializeJavaObject( Object value, SerializationContext context ) {
return baseType.serializeJavaObject( value, context );
}
final protected void _checkValid(String content, ValidationContext context ) throws DatatypeException {
// let the base type complain first.
baseType._checkValid(content,context);
// then see if the facet is satisfied.
diagnoseByFacet(content,context);
}
protected abstract void diagnoseByFacet(String content, ValidationContext context)
throws DatatypeException;
}