1 /*
   2  * Copyright (c) 1997, 2013, 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 
  26 package com.sun.tools.internal.ws.wsdl.parser;
  27 
  28 import com.sun.tools.internal.ws.wsdl.document.WSDLConstants;
  29 import com.sun.tools.internal.ws.wsdl.document.jaxws.JAXWSBindingsConstants;
  30 import com.sun.tools.internal.ws.wsdl.document.schema.SchemaConstants;
  31 import com.sun.tools.internal.xjc.util.DOMUtils;
  32 import org.w3c.dom.Element;
  33 import org.w3c.dom.NodeList;
  34 import org.xml.sax.Attributes;
  35 import org.xml.sax.helpers.XMLFilterImpl;
  36 
  37 /**
  38  * @author Vivek Pandey
  39  */
  40 public class WSDLInternalizationLogic implements InternalizationLogic{
  41 
  42     /**
  43      * This filter looks for <xs:import> and <xs:include>
  44      * and parses those documents referenced by them.
  45      */
  46     private static final class ReferenceFinder extends AbstractReferenceFinderImpl {
  47         ReferenceFinder( DOMForest parent) {
  48             super(parent);
  49         }
  50 
  51         @Override
  52         protected String findExternalResource( String nsURI, String localName, Attributes atts) {
  53             if(WSDLConstants.NS_WSDL.equals(nsURI) && "import".equals(localName)){
  54 //                if(parent.isExtensionMode()){
  55 //                    //TODO: add support for importing schema using wsdl:import
  56 //                }
  57                 return atts.getValue("location");
  58             }
  59 
  60             // We don't need to do this anymore, JAXB handles the schema imports, includes etc., but this is useful for the clientJar option in
  61             // fetching  the imported schemas to package in the jar..
  62             if (parent.options.clientjar != null) {
  63                 if (SchemaConstants.NS_XSD.equals(nsURI) && "import".equals(localName)) {
  64                     return atts.getValue("schemaLocation");
  65                 }
  66             }
  67             return null;
  68         }
  69     }
  70     @Override
  71     public XMLFilterImpl createExternalReferenceFinder(DOMForest parent) {
  72         return new ReferenceFinder(parent);
  73     }
  74 
  75     @Override
  76     public boolean checkIfValidTargetNode(DOMForest parent, Element bindings, Element target) {
  77         return false;
  78     }
  79 
  80     @Override
  81     public Element refineSchemaTarget(Element target) {
  82         // look for existing xs:annotation
  83         Element annotation = DOMUtils.getFirstChildElement(target, Constants.NS_XSD, "annotation");
  84         if(annotation==null)
  85             // none exists. need to make one
  86             annotation = insertXMLSchemaElement( target, "annotation" );
  87 
  88         // then look for appinfo
  89         Element appinfo = DOMUtils.getFirstChildElement(annotation, Constants.NS_XSD, "appinfo" );
  90         if(appinfo==null)
  91             // none exists. need to make one
  92             appinfo = insertXMLSchemaElement( annotation, "appinfo" );
  93 
  94         return appinfo;
  95 
  96     }
  97 
  98     @Override
  99     public Element refineWSDLTarget(Element target){
 100         // look for existing xs:annotation
 101         Element JAXWSBindings = DOMUtils.getFirstChildElement(target, JAXWSBindingsConstants.NS_JAXWS_BINDINGS, "bindings");
 102         if(JAXWSBindings==null)
 103             // none exists. need to make one
 104             JAXWSBindings = insertJAXWSBindingsElement(target, "bindings" );
 105         return JAXWSBindings;
 106     }
 107 
 108     private Element insertJAXWSBindingsElement( Element parent, String localName ) {
 109         String qname = "JAXWS:"+localName;
 110 
 111         Element child = parent.getOwnerDocument().createElementNS(JAXWSBindingsConstants.NS_JAXWS_BINDINGS, qname );
 112 
 113         NodeList children = parent.getChildNodes();
 114 
 115         if( children.getLength()==0 )
 116             parent.appendChild(child);
 117         else
 118             parent.insertBefore( child, children.item(0) );
 119 
 120         return child;
 121     }
 122 
 123 
 124     /**
 125      * Creates a new XML Schema element of the given local name
 126      * and insert it as the first child of the given parent node.
 127      *
 128      * @return
 129      *      Newly create element.
 130      */
 131     private Element insertXMLSchemaElement( Element parent, String localName ) {
 132         // use the same prefix as the parent node to avoid modifying
 133         // the namespace binding.
 134         String qname = parent.getTagName();
 135         int idx = qname.indexOf(':');
 136         if(idx==-1)     qname = localName;
 137         else            qname = qname.substring(0,idx+1)+localName;
 138 
 139         Element child = parent.getOwnerDocument().createElementNS( Constants.NS_XSD, qname );
 140 
 141         NodeList children = parent.getChildNodes();
 142 
 143         if( children.getLength()==0 )
 144             parent.appendChild(child);
 145         else
 146             parent.insertBefore( child, children.item(0) );
 147 
 148         return child;
 149     }
 150 
 151 }