1/* 2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.internal.xjc.reader.xmlschema.parser; 27 28import com.sun.tools.internal.xjc.reader.internalizer.AbstractReferenceFinderImpl; 29import com.sun.tools.internal.xjc.reader.internalizer.DOMForest; 30import com.sun.tools.internal.xjc.reader.internalizer.InternalizationLogic; 31import com.sun.tools.internal.xjc.util.DOMUtils; 32import com.sun.xml.internal.bind.v2.WellKnownNamespace; 33 34import org.w3c.dom.Element; 35import org.w3c.dom.NodeList; 36import org.xml.sax.Attributes; 37import org.xml.sax.helpers.XMLFilterImpl; 38 39/** 40 * XML Schema specific internalization logic. 41 * 42 * @author 43 * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) 44 */ 45public class XMLSchemaInternalizationLogic implements InternalizationLogic { 46 47 /** 48 * This filter looks for {@code <xs:import> and <xs:include>} 49 * and parses those documents referenced by them. 50 */ 51 private static final class ReferenceFinder extends AbstractReferenceFinderImpl { 52 ReferenceFinder( DOMForest parent ) { 53 super(parent); 54 } 55 56 protected String findExternalResource( String nsURI, String localName, Attributes atts) { 57 if( WellKnownNamespace.XML_SCHEMA.equals(nsURI) 58 && ("import".equals(localName) || "include".equals(localName) ) ) 59 return atts.getValue("schemaLocation"); 60 else 61 return null; 62 } 63 } 64 65 public XMLFilterImpl createExternalReferenceFinder(DOMForest parent) { 66 return new ReferenceFinder(parent); 67 } 68 69 public boolean checkIfValidTargetNode(DOMForest parent, Element bindings, Element target) { 70 return WellKnownNamespace.XML_SCHEMA.equals(target.getNamespaceURI()); 71 } 72 73 public Element refineTarget(Element target) { 74 // look for existing xs:annotation 75 Element annotation = DOMUtils.getFirstChildElement(target, WellKnownNamespace.XML_SCHEMA, "annotation"); 76 if(annotation==null) 77 // none exists. need to make one 78 annotation = insertXMLSchemaElement( target, "annotation" ); 79 80 // then look for appinfo 81 Element appinfo = DOMUtils.getFirstChildElement(annotation, WellKnownNamespace.XML_SCHEMA, "appinfo" ); 82 if(appinfo==null) 83 // none exists. need to make one 84 appinfo = insertXMLSchemaElement( annotation, "appinfo" ); 85 86 return appinfo; 87 } 88 89 /** 90 * Creates a new XML Schema element of the given local name 91 * and insert it as the first child of the given parent node. 92 * 93 * @return 94 * Newly create element. 95 */ 96 private Element insertXMLSchemaElement( Element parent, String localName ) { 97 // use the same prefix as the parent node to avoid modifying 98 // the namespace binding. 99 String qname = parent.getTagName(); 100 int idx = qname.indexOf(':'); 101 if(idx==-1) qname = localName; 102 else qname = qname.substring(0,idx+1)+localName; 103 104 Element child = parent.getOwnerDocument().createElementNS( WellKnownNamespace.XML_SCHEMA, qname ); 105 106 NodeList children = parent.getChildNodes(); 107 108 if( children.getLength()==0 ) 109 parent.appendChild(child); 110 else 111 parent.insertBefore( child, children.item(0) ); 112 113 return child; 114 } 115} 116