src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/dtd/bindinfo/BindInfo.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2012, 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  */
    26 package com.sun.tools.internal.xjc.reader.dtd.bindinfo;
    28 import java.io.IOException;
    29 import java.util.Collection;
    30 import java.util.HashMap;
    31 import java.util.Map;
    33 import javax.xml.parsers.ParserConfigurationException;
    34 import javax.xml.parsers.SAXParserFactory;
    35 import javax.xml.validation.ValidatorHandler;
    37 import com.sun.codemodel.internal.ClassType;
    38 import com.sun.codemodel.internal.JClass;
    39 import com.sun.codemodel.internal.JClassAlreadyExistsException;
    40 import com.sun.codemodel.internal.JCodeModel;
    41 import com.sun.codemodel.internal.JDefinedClass;
    42 import com.sun.codemodel.internal.JPackage;
    43 import com.sun.istack.internal.SAXParseException2;
    44 import com.sun.tools.internal.xjc.AbortException;
    45 import com.sun.tools.internal.xjc.ErrorReceiver;
    46 import com.sun.tools.internal.xjc.SchemaCache;
    47 import com.sun.tools.internal.xjc.model.CCustomizations;
    48 import com.sun.tools.internal.xjc.model.CPluginCustomization;
    49 import com.sun.tools.internal.xjc.model.Model;
    50 import com.sun.tools.internal.xjc.reader.Const;
    51 import com.sun.tools.internal.xjc.util.CodeModelClassFactory;
    52 import com.sun.tools.internal.xjc.util.ErrorReceiverFilter;
    53 import com.sun.tools.internal.xjc.util.ForkContentHandler;
    55 import com.sun.xml.internal.bind.v2.util.XmlFactory;
    56 import javax.xml.parsers.DocumentBuilderFactory;
    57 import org.w3c.dom.Document;
    58 import org.w3c.dom.Element;
    59 import org.xml.sax.InputSource;
    60 import org.xml.sax.SAXException;
    61 import org.xml.sax.XMLReader;
    63 /**
    64  * Root of the binding information.
    65  */
    66 public class BindInfo
    67 {
    68     /** Controller object that can be used to report errors. */
    69     protected final ErrorReceiver errorReceiver;
    71     /*package*/ final Model model;
    73     /**
    74      * The -p option that should control the default Java package that
    75      * will contain the generated code. Null if unspecified. This takes
    76      * precedence over the value specified in the binding file.
    77      */
    78     private final String defaultPackage;
    80     public BindInfo(Model model, InputSource source, ErrorReceiver _errorReceiver) throws AbortException {
    81         this( model, parse(model,source,_errorReceiver), _errorReceiver);
    82     }
    84     public BindInfo(Model model, Document _dom, ErrorReceiver _errorReceiver) {
    85         this.model = model;
    86         this.dom = _dom.getDocumentElement();
    87         this.codeModel = model.codeModel;
    88         this.errorReceiver = _errorReceiver;
    89         this.classFactory = new CodeModelClassFactory(_errorReceiver);
    90         // TODO: decide name converter from the binding file
    92         this.defaultPackage = model.options.defaultPackage;
    94         // copy global customizations to the model
    95         model.getCustomizations().addAll(getGlobalCustomizations());
    97         // process element declarations
    98         for( Element ele : DOMUtil.getChildElements(dom,"element")) {
    99             BIElement e = new BIElement(this,ele);
   100             elements.put(e.name(),e);
   101         }
   103         // add built-in conversions
   104         BIUserConversion.addBuiltinConversions(this,conversions);
   106         // process conversion declarations
   107         for( Element cnv : DOMUtil.getChildElements(dom,"conversion")) {
   108             BIConversion c = new BIUserConversion(this,cnv);
   109             conversions.put(c.name(),c);
   110         }
   111         for( Element en : DOMUtil.getChildElements(dom,"enumeration")) {
   112             BIConversion c = BIEnumeration.create( en, this );
   113             conversions.put(c.name(),c);
   114         }
   115         // TODO: check the uniquness of conversion name
   118         // process interface definitions
   119         for( Element itf : DOMUtil.getChildElements(dom,"interface")) {
   120             BIInterface c = new BIInterface(itf);
   121             interfaces.put(c.name(),c);
   122         }
   123     }
   126     /** CodeModel object that is used by this binding file. */
   127     final JCodeModel codeModel;
   129     /** Wrap the codeModel object and automate error reporting. */
   130     final CodeModelClassFactory classFactory;
   132     /** DOM tree that represents binding info. */
   133     private final Element dom;
   135     /** Conversion declarations. */
   136     private final Map<String,BIConversion> conversions = new HashMap<String,BIConversion>();
   138     /** Element declarations keyed by names. */
   139     private final Map<String,BIElement> elements = new HashMap<String,BIElement>();
   141     /** interface declarations keyed by names. */
   142     private final Map<String,BIInterface> interfaces = new HashMap<String,BIInterface>();
   145     /** XJC extension namespace. */
   146     private static final String XJC_NS = Const.XJC_EXTENSION_URI;
   148 //
   149 //
   150 //    Exposed public methods
   151 //
   152 //
   153     /** Gets the serialVersionUID if it's turned on. */
   154     public Long getSerialVersionUID() {
   155         Element serial = DOMUtil.getElement(dom,XJC_NS,"serializable");
   156         if(serial==null)    return null;
   158         String v = DOMUtil.getAttribute(serial,"uid");
   159         if(v==null) v="1";
   160         return new Long(v);
   161     }
   163     /** Gets the xjc:superClass customization if it's turned on. */
   164     public JClass getSuperClass() {
   165         Element sc = DOMUtil.getElement(dom,XJC_NS,"superClass");
   166         if (sc == null) return null;
   168         JDefinedClass c;
   170         try {
   171             String v = DOMUtil.getAttribute(sc,"name");
   172             if(v==null)     return null;
   173             c = codeModel._class(v);
   174             c.hide();
   175         } catch (JClassAlreadyExistsException e) {
   176             c = e.getExistingClass();
   177         }
   179         return c;
   180     }
   182     /** Gets the xjc:superInterface customization if it's turned on. */
   183     public JClass getSuperInterface() {
   184         Element sc = DOMUtil.getElement(dom,XJC_NS,"superInterface");
   185         if (sc == null) return null;
   187         String name = DOMUtil.getAttribute(sc,"name");
   188         if (name == null) return null;
   190         JDefinedClass c;
   192         try {
   193             c = codeModel._class(name, ClassType.INTERFACE);
   194             c.hide();
   195         } catch (JClassAlreadyExistsException e) {
   196             c = e.getExistingClass();
   197         }
   199         return c;
   200     }
   202     /**
   203      * Gets the specified package name (options/@package).
   204      */
   205     public JPackage getTargetPackage() {
   206         if(model.options.defaultPackage!=null)
   207             // "-p" takes precedence over everything else
   208             return codeModel._package(model.options.defaultPackage);
   210         String p;
   211         if( defaultPackage!=null )
   212             p = defaultPackage;
   213         else
   214             p = getOption("package", "");
   215         return codeModel._package(p);
   216     }
   218     /**
   219      * Gets the conversion declaration from the binding info.
   220      *
   221      * @return
   222      *        A non-null valid BIConversion object.
   223      */
   224     public BIConversion conversion(String name) {
   225         BIConversion r = conversions.get(name);
   226         if (r == null)
   227             throw new AssertionError("undefined conversion name: this should be checked by the validator before we read it");
   228         return r;
   229     }
   231     /**
   232      * Gets the element declaration from the binding info.
   233      *
   234      * @return
   235      *        If there is no declaration with a given name,
   236      *        this method returns null.
   237      */
   238     public BIElement element( String name ) {
   239         return elements.get(name);
   240     }
   241     /** Iterates all {@link BIElement}s in a read-only set. */
   242     public Collection<BIElement> elements() {
   243         return elements.values();
   244     }
   246     /** Returns all {@link BIInterface}s in a read-only set. */
   247     public Collection<BIInterface> interfaces() {
   248         return interfaces.values();
   249     }
   251     /**
   252      * Gets the list of top-level {@link CPluginCustomization}s.
   253      */
   254     private CCustomizations getGlobalCustomizations() {
   255         CCustomizations r=null;
   256         for( Element e : DOMUtil.getChildElements(dom) ) {
   257             if(!model.options.pluginURIs.contains(e.getNamespaceURI()))
   258                 continue;   // this isn't a plugin customization
   259             if(r==null)
   260                 r = new CCustomizations();
   261             r.add(new CPluginCustomization(e, DOMLocator.getLocationInfo(e)));
   262         }
   264         if(r==null)     r = CCustomizations.EMPTY;
   265         return new CCustomizations(r);
   266     }
   271 //
   272 //
   273 //    Internal utility methods
   274 //
   275 //
   278     /** Gets the value from the option element. */
   279     private String getOption(String attName, String defaultValue) {
   280         Element opt = DOMUtil.getElement(dom,"options");
   281         if (opt != null) {
   282             String s = DOMUtil.getAttribute(opt,attName);
   283             if (s != null)
   284                 return s;
   285         }
   286         return defaultValue;
   287     }
   289     /**
   290      * Lazily parsed schema for the binding file.
   291      */
   292     private static SchemaCache bindingFileSchema = new SchemaCache(BindInfo.class.getResource("bindingfile.xsd"));
   294     /**
   295      * Parses an InputSource into dom4j Document.
   296      * Returns null in case of an exception.
   297      */
   298     private static Document parse( Model model, InputSource is, ErrorReceiver receiver ) throws AbortException {
   299         try {
   300             ValidatorHandler validator = bindingFileSchema.newValidator();
   302             // set up the pipe line as :
   303             //              /-> extensionChecker -> validator
   304             //   parser-> -<
   305             //              \-> DOM builder
   306             SAXParserFactory pf = XmlFactory.createParserFactory(model.options.disableXmlSecurity);
   307             DocumentBuilderFactory domFactory = XmlFactory.createDocumentBuilderFactory(model.options.disableXmlSecurity);
   308             DOMBuilder builder = new DOMBuilder(domFactory);
   310             ErrorReceiverFilter controller = new ErrorReceiverFilter(receiver);
   311             validator.setErrorHandler(controller);
   312             XMLReader reader = pf.newSAXParser().getXMLReader();
   313             reader.setErrorHandler(controller);
   315             DTDExtensionBindingChecker checker = new DTDExtensionBindingChecker("", model.options, controller);
   316             checker.setContentHandler(validator);
   318             reader.setContentHandler(new ForkContentHandler(checker,builder));
   320             reader.parse(is);
   322             if(controller.hadError())   throw new AbortException();
   323             return (Document)builder.getDOM();
   324         } catch( IOException e ) {
   325             receiver.error( new SAXParseException2(e.getMessage(),null,e) );
   326         } catch( SAXException e ) {
   327             receiver.error( new SAXParseException2(e.getMessage(),null,e) );
   328         } catch( ParserConfigurationException e ) {
   329             receiver.error( new SAXParseException2(e.getMessage(),null,e) );
   330         }
   332         throw new AbortException();
   333     }
   334 }

mercurial