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.processor.modeler.wsdl;
  27 
  28 import com.sun.tools.internal.ws.processor.model.ModelException;
  29 import com.sun.tools.internal.ws.processor.model.java.JavaSimpleType;
  30 import com.sun.tools.internal.ws.processor.model.java.JavaType;
  31 import com.sun.tools.internal.ws.processor.model.jaxb.JAXBMapping;
  32 import com.sun.tools.internal.ws.processor.model.jaxb.JAXBModel;
  33 import com.sun.tools.internal.ws.processor.model.jaxb.JAXBType;
  34 import com.sun.tools.internal.ws.processor.util.ClassNameCollector;
  35 import com.sun.tools.internal.ws.wscompile.AbortException;
  36 import com.sun.tools.internal.ws.wscompile.ErrorReceiver;
  37 import com.sun.tools.internal.ws.wscompile.WsimportOptions;
  38 import com.sun.tools.internal.ws.wsdl.parser.DOMForestScanner;
  39 import com.sun.tools.internal.ws.wsdl.parser.MetadataFinder;
  40 import com.sun.tools.internal.xjc.api.S2JJAXBModel;
  41 import com.sun.tools.internal.xjc.api.SchemaCompiler;
  42 import com.sun.tools.internal.xjc.api.TypeAndAnnotation;
  43 import org.w3c.dom.Element;
  44 import org.xml.sax.InputSource;
  45 import org.xml.sax.helpers.LocatorImpl;
  46 
  47 import javax.xml.namespace.QName;
  48 
  49 /**
  50  * @author  Vivek Pandey
  51  *
  52  * Uses JAXB XJC apis to build JAXBModel and resolves xml to java type mapping from JAXBModel
  53  */
  54 public class JAXBModelBuilder {
  55 
  56     private final ErrorReceiver errReceiver;
  57     private final WsimportOptions options;
  58     private final MetadataFinder forest;
  59 
  60     public JAXBModelBuilder(WsimportOptions options, ClassNameCollector classNameCollector, MetadataFinder finder, ErrorReceiver errReceiver) {
  61         this._classNameAllocator = new ClassNameAllocatorImpl(classNameCollector);
  62         this.errReceiver = errReceiver;
  63         this.options = options;
  64         this.forest = finder;
  65 
  66         internalBuildJAXBModel();
  67     }
  68 
  69     /**
  70      * Builds model from WSDL document. Model contains abstraction which is used by the
  71      * generators to generate the stub/tie/serializers etc. code.
  72      *
  73      * @see com.sun.tools.internal.ws.processor.modeler.Modeler#buildModel()
  74      */
  75 
  76     private void internalBuildJAXBModel(){
  77         try {
  78             schemaCompiler =  options.getSchemaCompiler();
  79             schemaCompiler.resetSchema();
  80             if(options.entityResolver != null) {
  81                 //set if its not null so as not to override catalog option specified via xjc args
  82                 schemaCompiler.setEntityResolver(options.entityResolver);
  83             }
  84             schemaCompiler.setClassNameAllocator(_classNameAllocator);
  85             schemaCompiler.setErrorListener(errReceiver);
  86             int schemaElementCount = 1;
  87 
  88             for (Element element : forest.getInlinedSchemaElement()) {
  89                 String location = element.getOwnerDocument().getDocumentURI();
  90                 String systemId = location + "#types?schema" + schemaElementCount++;
  91                 if(forest.isMexMetadata)
  92                     schemaCompiler.parseSchema(systemId,element);
  93                 else
  94                     new DOMForestScanner(forest).scan(element,schemaCompiler.getParserHandler(systemId));
  95             }
  96 
  97             //feed external jaxb:bindings file
  98             InputSource[] externalBindings = options.getSchemaBindings();
  99             if(externalBindings != null){
 100                 for(InputSource jaxbBinding : externalBindings){
 101                     schemaCompiler.parseSchema(jaxbBinding);
 102                 }
 103             }
 104         } catch (Exception e) {
 105             throw new ModelException(e);
 106         }
 107     }
 108 
 109     public JAXBType  getJAXBType(QName qname){
 110         JAXBMapping mapping = jaxbModel.get(qname);
 111         if (mapping == null){
 112             return null;
 113         }
 114         JavaType javaType = new JavaSimpleType(mapping.getType());
 115         return new JAXBType(qname, javaType, mapping, jaxbModel);
 116     }
 117 
 118     public TypeAndAnnotation getElementTypeAndAnn(QName qname){
 119         JAXBMapping mapping = jaxbModel.get(qname);
 120         if (mapping == null){
 121             return null;
 122         }
 123         return mapping.getType().getTypeAnn();
 124     }
 125 
 126     protected void bind(){
 127         S2JJAXBModel rawJaxbModel = schemaCompiler.bind();
 128         if(rawJaxbModel == null)
 129             throw new AbortException();
 130         options.setCodeModel(rawJaxbModel.generateCode(null, errReceiver));
 131         jaxbModel = new JAXBModel(rawJaxbModel);
 132         jaxbModel.setGeneratedClassNames(_classNameAllocator.getJaxbGeneratedClasses());
 133     }
 134 
 135     protected SchemaCompiler getJAXBSchemaCompiler(){
 136         return schemaCompiler;
 137     }
 138 
 139     public JAXBModel getJAXBModel(){
 140         return jaxbModel;
 141     }
 142 
 143     private JAXBModel jaxbModel;
 144     private SchemaCompiler schemaCompiler;
 145     private final ClassNameAllocatorImpl _classNameAllocator;
 146     protected static final LocatorImpl NULL_LOCATOR = new LocatorImpl();
 147 
 148 }