001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.xerces.jaxp.validation;
019:
020: import javax.xml.transform.dom.DOMResult;
021:
022: import org.apache.xerces.dom.AttrImpl;
023: import org.apache.xerces.dom.CoreDocumentImpl;
024: import org.apache.xerces.dom.ElementImpl;
025: import org.apache.xerces.dom.ElementNSImpl;
026: import org.apache.xerces.dom.PSVIAttrNSImpl;
027: import org.apache.xerces.dom.PSVIDocumentImpl;
028: import org.apache.xerces.dom.PSVIElementNSImpl;
029: import org.apache.xerces.impl.Constants;
030: import org.apache.xerces.impl.dv.XSSimpleType;
031: import org.apache.xerces.xni.Augmentations;
032: import org.apache.xerces.xni.NamespaceContext;
033: import org.apache.xerces.xni.QName;
034: import org.apache.xerces.xni.XMLAttributes;
035: import org.apache.xerces.xni.XMLLocator;
036: import org.apache.xerces.xni.XMLResourceIdentifier;
037: import org.apache.xerces.xni.XMLString;
038: import org.apache.xerces.xni.XNIException;
039: import org.apache.xerces.xni.parser.XMLDocumentSource;
040: import org.apache.xerces.xs.AttributePSVI;
041: import org.apache.xerces.xs.ElementPSVI;
042: import org.apache.xerces.xs.XSTypeDefinition;
043: import org.w3c.dom.CDATASection;
044: import org.w3c.dom.Comment;
045: import org.w3c.dom.Document;
046: import org.w3c.dom.DocumentType;
047: import org.w3c.dom.Element;
048: import org.w3c.dom.NamedNodeMap;
049: import org.w3c.dom.Node;
050: import org.w3c.dom.ProcessingInstruction;
051: import org.w3c.dom.Text;
052:
053: /**
054: * <p>DOM result augmentor.</p>
055: *
056: * @author Michael Glavassevich, IBM
057: * @version $Id: DOMResultAugmentor.java 542522 2007-05-29 13:59:56Z mrglavas $
058: */
059: final class DOMResultAugmentor implements DOMDocumentHandler {
060:
061: //
062: // Data
063: //
064:
065: private final DOMValidatorHelper fDOMValidatorHelper;
066:
067: private Document fDocument;
068: private CoreDocumentImpl fDocumentImpl;
069: private boolean fStorePSVI;
070:
071: private boolean fIgnoreChars;
072:
073: private final QName fAttributeQName = new QName();
074:
075: public DOMResultAugmentor(DOMValidatorHelper helper) {
076: fDOMValidatorHelper = helper;
077: }
078:
079: public void setDOMResult(DOMResult result) {
080: fIgnoreChars = false;
081: if (result != null) {
082: final Node target = result.getNode();
083: fDocument = (target.getNodeType() == Node.DOCUMENT_NODE) ? (Document) target
084: : target.getOwnerDocument();
085: fDocumentImpl = (fDocument instanceof CoreDocumentImpl) ? (CoreDocumentImpl) fDocument
086: : null;
087: fStorePSVI = (fDocument instanceof PSVIDocumentImpl);
088: return;
089: }
090: fDocument = null;
091: fDocumentImpl = null;
092: fStorePSVI = false;
093: }
094:
095: public void doctypeDecl(DocumentType node) throws XNIException {
096: }
097:
098: public void characters(Text node) throws XNIException {
099: }
100:
101: public void cdata(CDATASection node) throws XNIException {
102: }
103:
104: public void comment(Comment node) throws XNIException {
105: }
106:
107: public void processingInstruction(ProcessingInstruction node)
108: throws XNIException {
109: }
110:
111: public void setIgnoringCharacters(boolean ignore) {
112: fIgnoreChars = ignore;
113: }
114:
115: public void startDocument(XMLLocator locator, String encoding,
116: NamespaceContext namespaceContext, Augmentations augs)
117: throws XNIException {
118: }
119:
120: public void xmlDecl(String version, String encoding,
121: String standalone, Augmentations augs) throws XNIException {
122: }
123:
124: public void doctypeDecl(String rootElement, String publicId,
125: String systemId, Augmentations augs) throws XNIException {
126: }
127:
128: public void comment(XMLString text, Augmentations augs)
129: throws XNIException {
130: }
131:
132: public void processingInstruction(String target, XMLString data,
133: Augmentations augs) throws XNIException {
134: }
135:
136: public void startElement(QName element, XMLAttributes attributes,
137: Augmentations augs) throws XNIException {
138: final Element currentElement = (Element) fDOMValidatorHelper
139: .getCurrentElement();
140: final NamedNodeMap attrMap = currentElement.getAttributes();
141:
142: final int oldLength = attrMap.getLength();
143: // If it's a Xerces DOM store type information for attributes, set idness, etc..
144: if (fDocumentImpl != null) {
145: AttrImpl attr;
146: for (int i = 0; i < oldLength; ++i) {
147: attr = (AttrImpl) attrMap.item(i);
148:
149: // write type information to this attribute
150: AttributePSVI attrPSVI = (AttributePSVI) attributes
151: .getAugmentations(i).getItem(
152: Constants.ATTRIBUTE_PSVI);
153: if (attrPSVI != null) {
154: if (processAttributePSVI(attr, attrPSVI)) {
155: ((ElementImpl) currentElement)
156: .setIdAttributeNode(attr, true);
157: }
158: }
159: }
160: }
161:
162: final int newLength = attributes.getLength();
163: // Add default/fixed attributes
164: if (newLength > oldLength) {
165: if (fDocumentImpl == null) {
166: for (int i = oldLength; i < newLength; ++i) {
167: attributes.getName(i, fAttributeQName);
168: currentElement.setAttributeNS(fAttributeQName.uri,
169: fAttributeQName.rawname, attributes
170: .getValue(i));
171: }
172: }
173: // If it's a Xerces DOM store type information for attributes, set idness, etc..
174: else {
175: for (int i = oldLength; i < newLength; ++i) {
176: attributes.getName(i, fAttributeQName);
177: AttrImpl attr = (AttrImpl) fDocumentImpl
178: .createAttributeNS(fAttributeQName.uri,
179: fAttributeQName.rawname,
180: fAttributeQName.localpart);
181: attr.setValue(attributes.getValue(i));
182: currentElement.setAttributeNodeNS(attr);
183:
184: // write type information to this attribute
185: AttributePSVI attrPSVI = (AttributePSVI) attributes
186: .getAugmentations(i).getItem(
187: Constants.ATTRIBUTE_PSVI);
188: if (attrPSVI != null) {
189: if (processAttributePSVI(attr, attrPSVI)) {
190: ((ElementImpl) currentElement)
191: .setIdAttributeNode(attr, true);
192: }
193: }
194: attr.setSpecified(false);
195: }
196: }
197: }
198: }
199:
200: public void emptyElement(QName element, XMLAttributes attributes,
201: Augmentations augs) throws XNIException {
202: startElement(element, attributes, augs);
203: endElement(element, augs);
204: }
205:
206: public void startGeneralEntity(String name,
207: XMLResourceIdentifier identifier, String encoding,
208: Augmentations augs) throws XNIException {
209: }
210:
211: public void textDecl(String version, String encoding,
212: Augmentations augs) throws XNIException {
213: }
214:
215: public void endGeneralEntity(String name, Augmentations augs)
216: throws XNIException {
217: }
218:
219: public void characters(XMLString text, Augmentations augs)
220: throws XNIException {
221: if (!fIgnoreChars) {
222: final Element currentElement = (Element) fDOMValidatorHelper
223: .getCurrentElement();
224: currentElement.appendChild(fDocument.createTextNode(text
225: .toString()));
226: }
227: }
228:
229: public void ignorableWhitespace(XMLString text, Augmentations augs)
230: throws XNIException {
231: characters(text, augs);
232: }
233:
234: public void endElement(QName element, Augmentations augs)
235: throws XNIException {
236: final Node currentElement = fDOMValidatorHelper
237: .getCurrentElement();
238: // Write type information to this element
239: if (augs != null && fDocumentImpl != null) {
240: ElementPSVI elementPSVI = (ElementPSVI) augs
241: .getItem(Constants.ELEMENT_PSVI);
242: if (elementPSVI != null) {
243: if (fStorePSVI) {
244: ((PSVIElementNSImpl) currentElement)
245: .setPSVI(elementPSVI);
246: }
247: XSTypeDefinition type = elementPSVI
248: .getMemberTypeDefinition();
249: if (type == null) {
250: type = elementPSVI.getTypeDefinition();
251: }
252: ((ElementNSImpl) currentElement).setType(type);
253: }
254: }
255: }
256:
257: public void startCDATA(Augmentations augs) throws XNIException {
258: }
259:
260: public void endCDATA(Augmentations augs) throws XNIException {
261: }
262:
263: public void endDocument(Augmentations augs) throws XNIException {
264: }
265:
266: public void setDocumentSource(XMLDocumentSource source) {
267: }
268:
269: public XMLDocumentSource getDocumentSource() {
270: return null;
271: }
272:
273: /** Returns whether the given attribute is an ID type. **/
274: private boolean processAttributePSVI(AttrImpl attr,
275: AttributePSVI attrPSVI) {
276: if (fStorePSVI) {
277: ((PSVIAttrNSImpl) attr).setPSVI(attrPSVI);
278: }
279: Object type = attrPSVI.getMemberTypeDefinition();
280: if (type == null) {
281: type = attrPSVI.getTypeDefinition();
282: if (type != null) {
283: attr.setType(type);
284: return ((XSSimpleType) type).isIDType();
285: }
286: } else {
287: attr.setType(type);
288: return ((XSSimpleType) type).isIDType();
289: }
290: return false;
291: }
292:
293: } // DOMResultAugmentor
|