001: package net.sf.saxon.dom;
002:
003: import net.sf.saxon.event.ContentHandlerProxy;
004: import net.sf.saxon.event.ReceiverOptions;
005: import net.sf.saxon.om.NamespaceConstant;
006: import net.sf.saxon.style.StandardNames;
007: import net.sf.saxon.trans.XPathException;
008: import net.sf.saxon.type.AnySimpleType;
009: import net.sf.saxon.type.AnyType;
010: import net.sf.saxon.type.SchemaType;
011: import org.w3c.dom.TypeInfo;
012:
013: import javax.xml.validation.TypeInfoProvider;
014:
015: /**
016: * This class is an extension of ContentHandlerProxy that provides access to type
017: * information, using the DOM Level 3 TypeInfo interfaces.
018: * The ContentHandlerProxy also acts as a TypeInfoProvider, providing information
019: * about the type of the current element or attribute.
020: */
021:
022: public class TypedContentHandler extends ContentHandlerProxy {
023: private int pendingElementTypeCode;
024:
025: /**
026: * Get a TypeInfoProvider to provide type information for the current element or attribute
027: * event.
028: */
029:
030: public TypeInfoProvider getTypeInfoProvider() {
031: return new TypeInfoProviderImpl();
032: }
033:
034: /**
035: * Notify the start of an element
036: */
037:
038: public void startElement(int nameCode, int typeCode,
039: int locationId, int properties) throws XPathException {
040: pendingElementTypeCode = typeCode;
041: super .startElement(nameCode, typeCode, locationId, properties);
042: }
043:
044: ///////////////////////////////////////////////////////////////////////////////////////////
045: // TypeInfoProvider
046: ///////////////////////////////////////////////////////////////////////////////////////////
047:
048: public class TypeInfoProviderImpl extends TypeInfoProvider {
049:
050: /**
051: * Returns the immutable {@link org.w3c.dom.TypeInfo} object for the current element.
052: *
053: * @return An immutable {@link org.w3c.dom.TypeInfo} object that represents the
054: * type of the current element.
055: * Note that the caller can keep references to the obtained
056: * {@link org.w3c.dom.TypeInfo} longer than the callback scope.
057: * <p/>
058: * Otherwise, this method returns null if the validator is unable to
059: * determine the type of the current element for some reason
060: */
061:
062: public TypeInfo getElementTypeInfo() {
063: if (pendingElementTypeCode == -1) {
064: return new TypeInfoImpl(getConfiguration(), AnyType
065: .getInstance());
066: } else {
067: return new TypeInfoImpl(getConfiguration(),
068: getConfiguration().getSchemaType(
069: pendingElementTypeCode));
070: }
071: }
072:
073: /**
074: * Returns the immutable {@link org.w3c.dom.TypeInfo} object for the specified
075: * attribute of the current element.
076: * <p/>
077: * The method may only be called by the startElement event of
078: * the {@link org.xml.sax.ContentHandler} that the application sets to the
079: * {@link javax.xml.validation.ValidatorHandler}.
080: *
081: * @param index The index of the attribute. The same index for
082: * the {@link org.xml.sax.Attributes} object passed to the
083: * <tt>startElement</tt> callback.
084: * @return An immutable {@link org.w3c.dom.TypeInfo} object that represents the
085: * type of the specified attribute.
086: * Note that the caller can keep references to the obtained
087: * {@link org.w3c.dom.TypeInfo} longer than the callback scope.
088: * <p/>
089: * Otherwise, this method returns null if the validator is unable to
090: * determine the type.
091: * @throws IndexOutOfBoundsException If the index is invalid.
092: * @throws IllegalStateException If this method is called from other {@link org.xml.sax.ContentHandler}
093: * methods.
094: */
095: public TypeInfo getAttributeTypeInfo(int index) {
096: if (index < 0 || index > pendingAttributes.getLength()) {
097: throw new IndexOutOfBoundsException("" + index);
098: }
099: int type = pendingAttributes.getTypeAnnotation(index);
100: if (type == -1) {
101: return new TypeInfoImpl(getConfiguration(),
102: AnySimpleType.getInstance());
103: } else {
104: return new TypeInfoImpl(getConfiguration(),
105: getConfiguration().getSchemaType(type));
106: }
107: }
108:
109: /**
110: * Returns <tt>true</tt> if the specified attribute is determined
111: * to be an ID.
112: * @param index The index of the attribute. The same index for
113: * the {@link org.xml.sax.Attributes} object passed to the
114: * <tt>startElement</tt> callback.
115: * @return true
116: * if the type of the specified attribute is ID.
117: */
118: public boolean isIdAttribute(int index) {
119: int type = pendingAttributes.getTypeAnnotation(index);
120: return (type == StandardNames.XS_ID || getAttributeTypeInfo(
121: index).isDerivedFrom(NamespaceConstant.SCHEMA,
122: "ID", SchemaType.DERIVATION_RESTRICTION));
123: }
124:
125: /**
126: * Returns <tt>false</tt> if the attribute was added by the validator.
127: *
128: * @param index The index of the attribute. The same index for
129: * the {@link org.xml.sax.Attributes} object passed to the
130: * <tt>startElement</tt> callback.
131: * @return <tt>true</tt> if the attribute was present before the validator
132: * processes input. <tt>false</tt> if the attribute was added
133: * by the validator.
134: */
135:
136: public boolean isSpecified(int index) {
137: return (pendingAttributes.getProperties(index) & ReceiverOptions.DEFAULTED_ATTRIBUTE) == 0;
138: }
139:
140: }
141: }
142:
143: //
144: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
145: // you may not use this file except in compliance with the License. You may obtain a copy of the
146: // License at http://www.mozilla.org/MPL/
147: //
148: // Software distributed under the License is distributed on an "AS IS" basis,
149: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
150: // See the License for the specific language governing rights and limitations under the License.
151: //
152: // The Original Code is: all this file.
153: //
154: // The Initial Developer of the Original Code is Michael H. Kay.
155: //
156: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
157: //
158: // Contributor(s): none.
159: //
|