1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2005 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.xerces.internal.jaxp.validation;
  22 
  23 import javax.xml.transform.dom.DOMResult;
  24 
  25 import com.sun.org.apache.xerces.internal.dom.AttrImpl;
  26 import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl;
  27 import com.sun.org.apache.xerces.internal.dom.ElementImpl;
  28 import com.sun.org.apache.xerces.internal.dom.ElementNSImpl;
  29 import com.sun.org.apache.xerces.internal.dom.PSVIAttrNSImpl;
  30 import com.sun.org.apache.xerces.internal.dom.PSVIDocumentImpl;
  31 import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
  32 import com.sun.org.apache.xerces.internal.impl.Constants;
  33 import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
  34 import com.sun.org.apache.xerces.internal.xni.Augmentations;
  35 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
  36 import com.sun.org.apache.xerces.internal.xni.QName;
  37 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
  38 import com.sun.org.apache.xerces.internal.xni.XMLLocator;
  39 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
  40 import com.sun.org.apache.xerces.internal.xni.XMLString;
  41 import com.sun.org.apache.xerces.internal.xni.XNIException;
  42 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
  43 import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
  44 import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
  45 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
  46 import org.w3c.dom.CDATASection;
  47 import org.w3c.dom.Comment;
  48 import org.w3c.dom.Document;
  49 import org.w3c.dom.DocumentType;
  50 import org.w3c.dom.Element;
  51 import org.w3c.dom.NamedNodeMap;
  52 import org.w3c.dom.Node;
  53 import org.w3c.dom.ProcessingInstruction;
  54 import org.w3c.dom.Text;
  55 
  56 /**
  57  * <p>DOM result augmentor.</p>
  58  *
  59  * @author Michael Glavassevich, IBM
  60  */
  61 final class DOMResultAugmentor implements DOMDocumentHandler {
  62 
  63     //
  64     // Data
  65     //
  66 
  67     private DOMValidatorHelper fDOMValidatorHelper;
  68 
  69     private Document fDocument;
  70     private CoreDocumentImpl fDocumentImpl;
  71     private boolean fStorePSVI;
  72 
  73     private boolean fIgnoreChars;
  74 
  75     private final QName fAttributeQName = new QName();
  76 
  77     public DOMResultAugmentor(DOMValidatorHelper helper) {
  78         fDOMValidatorHelper = helper;
  79     }
  80 
  81     public void setDOMResult(DOMResult result) {
  82         fIgnoreChars = false;
  83         if (result != null) {
  84             final Node target = result.getNode();
  85             fDocument = (target.getNodeType() == Node.DOCUMENT_NODE) ? (Document) target : target.getOwnerDocument();
  86             fDocumentImpl = (fDocument instanceof CoreDocumentImpl) ? (CoreDocumentImpl) fDocument : null;
  87             fStorePSVI = (fDocument instanceof PSVIDocumentImpl);
  88             return;
  89         }
  90         fDocument = null;
  91         fDocumentImpl = null;
  92         fStorePSVI = false;
  93     }
  94 
  95     public void doctypeDecl(DocumentType node) throws XNIException {}
  96 
  97     public void characters(Text node) throws XNIException {}
  98 
  99     public void cdata(CDATASection node) throws XNIException {}
 100 
 101     public void comment(Comment node) throws XNIException {}
 102 
 103     public void processingInstruction(ProcessingInstruction node)
 104             throws XNIException {}
 105 
 106     public void setIgnoringCharacters(boolean ignore) {
 107         fIgnoreChars = ignore;
 108     }
 109 
 110     public void startDocument(XMLLocator locator, String encoding,
 111             NamespaceContext namespaceContext, Augmentations augs)
 112             throws XNIException {}
 113 
 114     public void xmlDecl(String version, String encoding, String standalone,
 115             Augmentations augs) throws XNIException {}
 116 
 117     public void doctypeDecl(String rootElement, String publicId,
 118             String systemId, Augmentations augs) throws XNIException {}
 119 
 120     public void comment(XMLString text, Augmentations augs) throws XNIException {}
 121 
 122     public void processingInstruction(String target, XMLString data,
 123             Augmentations augs) throws XNIException {}
 124 
 125     public void startElement(QName element, XMLAttributes attributes,
 126             Augmentations augs) throws XNIException {
 127         final Element currentElement = (Element) fDOMValidatorHelper.getCurrentElement();
 128         final NamedNodeMap attrMap = currentElement.getAttributes();
 129 
 130         final int oldLength = attrMap.getLength();
 131         // If it's a Xerces DOM store type information for attributes, set idness, etc..
 132         if (fDocumentImpl != null) {
 133             AttrImpl attr;
 134             for (int i = 0; i < oldLength; ++i) {
 135                 attr = (AttrImpl) attrMap.item(i);
 136 
 137                 // write type information to this attribute
 138                 AttributePSVI attrPSVI = (AttributePSVI) attributes.getAugmentations(i).getItem (Constants.ATTRIBUTE_PSVI);
 139                 if (attrPSVI != null) {
 140                     if (processAttributePSVI(attr, attrPSVI)) {
 141                         ((ElementImpl) currentElement).setIdAttributeNode (attr, true);
 142                     }
 143                 }
 144             }
 145         }
 146 
 147         final int newLength = attributes.getLength();
 148         // Add default/fixed attributes
 149         if (newLength > oldLength) {
 150             if (fDocumentImpl == null) {
 151                 for (int i = oldLength; i < newLength; ++i) {
 152                     attributes.getName(i, fAttributeQName);
 153                     currentElement.setAttributeNS(fAttributeQName.uri, fAttributeQName.rawname, attributes.getValue(i));
 154                 }
 155             }
 156             // If it's a Xerces DOM store type information for attributes, set idness, etc..
 157             else {
 158                 for (int i = oldLength; i < newLength; ++i) {
 159                     attributes.getName(i, fAttributeQName);
 160                     AttrImpl attr = (AttrImpl) fDocumentImpl.createAttributeNS(fAttributeQName.uri,
 161                             fAttributeQName.rawname, fAttributeQName.localpart);
 162                     attr.setValue(attributes.getValue(i));
 163 
 164                     // write type information to this attribute
 165                     AttributePSVI attrPSVI = (AttributePSVI) attributes.getAugmentations(i).getItem (Constants.ATTRIBUTE_PSVI);
 166                     if (attrPSVI != null) {
 167                         if (processAttributePSVI(attr, attrPSVI)) {
 168                             ((ElementImpl) currentElement).setIdAttributeNode (attr, true);
 169                         }
 170                     }
 171                     attr.setSpecified(false);
 172                     currentElement.setAttributeNode(attr);
 173                 }
 174             }
 175         }
 176     }
 177 
 178     public void emptyElement(QName element, XMLAttributes attributes,
 179             Augmentations augs) throws XNIException {
 180         startElement(element, attributes, augs);
 181         endElement(element, augs);
 182     }
 183 
 184     public void startGeneralEntity(String name,
 185             XMLResourceIdentifier identifier, String encoding,
 186             Augmentations augs) throws XNIException {}
 187 
 188     public void textDecl(String version, String encoding, Augmentations augs)
 189             throws XNIException {}
 190 
 191     public void endGeneralEntity(String name, Augmentations augs)
 192             throws XNIException {}
 193 
 194     public void characters(XMLString text, Augmentations augs)
 195             throws XNIException {
 196         if (!fIgnoreChars) {
 197             final Element currentElement = (Element) fDOMValidatorHelper.getCurrentElement();
 198             currentElement.appendChild(fDocument.createTextNode(text.toString()));
 199         }
 200     }
 201 
 202     public void ignorableWhitespace(XMLString text, Augmentations augs)
 203             throws XNIException {
 204         characters(text, augs);
 205     }
 206 
 207     public void endElement(QName element, Augmentations augs)
 208             throws XNIException {
 209         final Node currentElement = fDOMValidatorHelper.getCurrentElement();
 210         // Write type information to this element
 211         if (augs != null && fDocumentImpl != null) {
 212             ElementPSVI elementPSVI = (ElementPSVI)augs.getItem(Constants.ELEMENT_PSVI);
 213             if (elementPSVI != null) {
 214                 if (fStorePSVI) {
 215                     ((PSVIElementNSImpl) currentElement).setPSVI(elementPSVI);
 216                 }
 217                 XSTypeDefinition type = elementPSVI.getMemberTypeDefinition();
 218                 if (type == null) {
 219                     type = elementPSVI.getTypeDefinition();
 220                 }
 221                 ((ElementNSImpl) currentElement).setType(type);
 222             }
 223         }
 224     }
 225 
 226     public void startCDATA(Augmentations augs) throws XNIException {}
 227 
 228     public void endCDATA(Augmentations augs) throws XNIException {}
 229 
 230     public void endDocument(Augmentations augs) throws XNIException {}
 231 
 232     public void setDocumentSource(XMLDocumentSource source) {}
 233 
 234     public XMLDocumentSource getDocumentSource() {
 235         return null;
 236     }
 237 
 238     /** Returns whether the given attribute is an ID type. **/
 239     private boolean processAttributePSVI(AttrImpl attr, AttributePSVI attrPSVI) {
 240         if (fStorePSVI) {
 241             ((PSVIAttrNSImpl) attr).setPSVI (attrPSVI);
 242         }
 243         Object type = attrPSVI.getMemberTypeDefinition ();
 244         if (type == null) {
 245             type = attrPSVI.getTypeDefinition ();
 246             if (type != null) {
 247                 attr.setType(type);
 248                 return ((XSSimpleType) type).isIDType();
 249             }
 250         }
 251         else {
 252             attr.setType(type);
 253             return ((XSSimpleType) type).isIDType();
 254         }
 255         return false;
 256     }
 257 
 258 } // DOMResultAugmentor