< prev index next >

src/jdk.xml.bind/share/classes/com/sun/tools/internal/xjc/model/Model.java

Print this page


   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  */
  25 
  26 package com.sun.tools.internal.xjc.model;
  27 
  28 import java.util.Collections;
  29 import java.util.HashMap;
  30 import java.util.HashSet;
  31 import java.util.Iterator;
  32 import java.util.LinkedHashMap;
  33 import java.util.Map;
  34 import java.util.Set;
  35 
  36 import javax.xml.bind.annotation.XmlAttribute;
  37 import javax.xml.bind.annotation.XmlNsForm;
  38 import javax.xml.bind.annotation.XmlTransient;
  39 import javax.xml.namespace.QName;
  40 import javax.xml.transform.Result;
  41 
  42 import com.sun.codemodel.internal.JClass;
  43 import com.sun.codemodel.internal.JCodeModel;
  44 import com.sun.codemodel.internal.JPackage;
  45 import com.sun.tools.internal.xjc.ErrorReceiver;
  46 import com.sun.tools.internal.xjc.Options;
  47 import com.sun.tools.internal.xjc.Plugin;
  48 import com.sun.tools.internal.xjc.api.ClassNameAllocator;
  49 import com.sun.tools.internal.xjc.generator.bean.BeanGenerator;
  50 import com.sun.tools.internal.xjc.generator.bean.ImplStructureStrategy;
  51 import com.sun.tools.internal.xjc.model.nav.NClass;
  52 import com.sun.tools.internal.xjc.model.nav.NType;
  53 import com.sun.tools.internal.xjc.model.nav.NavigatorImpl;
  54 import com.sun.tools.internal.xjc.outline.Outline;
  55 import com.sun.tools.internal.xjc.reader.xmlschema.Messages;
  56 import com.sun.tools.internal.xjc.util.ErrorReceiverFilter;
  57 import com.sun.xml.internal.bind.api.impl.NameConverter;
  58 import com.sun.xml.internal.bind.v2.model.core.Ref;
  59 import com.sun.xml.internal.bind.v2.model.core.TypeInfoSet;
  60 import com.sun.xml.internal.bind.v2.model.nav.Navigator;
  61 import com.sun.xml.internal.bind.v2.util.FlattenIterator;
  62 import com.sun.xml.internal.xsom.XSComponent;
  63 import com.sun.xml.internal.xsom.XSSchemaSet;
  64 
  65 import org.xml.sax.Locator;
  66 import org.xml.sax.SAXException;
  67 import org.xml.sax.helpers.LocatorImpl;
  68 













  69 /**
  70  * Root of the object model that represents the code that needs to be generated.
  71  *
  72  * <p>
  73  * A {@link Model} is a schema language neutral representation of the
  74  * result of a schema parsing. The back-end then works against this model
  75  * to turn this into a series of Java source code.
  76  *
  77  * @author Kohsuke Kawaguchi
  78  */
  79 public final class Model implements TypeInfoSet<NType,NClass,Void,Void>, CCustomizable {
  80 
  81     /**
  82      * Generated beans.
  83      */
  84     private final Map<NClass,CClassInfo> beans = new LinkedHashMap<NClass,CClassInfo>();
  85 
  86     /**
  87      * Generated enums.
  88      */
  89     private final Map<NClass,CEnumLeafInfo> enums = new LinkedHashMap<NClass,CEnumLeafInfo>();
  90 
  91     /**
  92      * The element mappings.
  93      */
  94     private final Map<NClass/*scope*/,Map<QName,CElementInfo>> elementMappings =
  95         new HashMap<NClass,Map<QName,CElementInfo>>();
  96 
  97     private final Iterable<? extends CElementInfo> allElements =
  98         new Iterable<CElementInfo>() {
  99             public Iterator<CElementInfo> iterator() {
 100                 return new FlattenIterator<CElementInfo>(elementMappings.values());
 101             }
 102         };
 103 
 104     /**
 105      * {@link TypeUse}s for all named types.
 106      * <p>
 107      * I really don't want to promote the notion of a 'type' in any place except in the XML Schema code,
 108      * but this needs to be exposed for JAX-RPC. A reference to a named XML type will be converted into
 109      * a reference to a Java type with annotations.
 110      */
 111     private final Map<QName,TypeUse> typeUses = new LinkedHashMap<QName, TypeUse>();
 112 
 113     /**
 114      * {@link NameConverter} to be used.
 115      */
 116     private NameConverter nameConverter;
 117 
 118     /**
 119      * Single linked list that connects all {@link CCustomizations} that belong to this model.
 120      *
 121      * @see CCustomizations#next
 122      */
 123     /*package*/ CCustomizations customizations;
 124 
 125     /**
 126      * This field controls the generation of package level annotations for s2j
 127      */
 128     private boolean packageLevelAnnotations = true;
 129 
 130     /**
 131      * If this model was built from XML Schema, this field
 132      * stores the root object of the parse schema model.
 133      * Otherwise null.
 134      *
 135      * @sine 2.1.1
 136      */
 137     public final XSSchemaSet schemaComponent;
 138 
 139     private CCustomizations gloablCustomizations = new CCustomizations();
 140 
 141     /**
 142      * @param nc
 143      *      Usually this should be set in the constructor, but we do allow this parameter
 144      *      to be initially null, and then set later.
 145      * @param schemaComponent
 146      *      The source schema model, if this is built from XSD.
 147      */
 148     public Model( Options opts, JCodeModel cm, NameConverter nc, ClassNameAllocator allocator, XSSchemaSet schemaComponent ) {
 149         this.options = opts;
 150         this.codeModel = cm;
 151         this.nameConverter = nc;
 152         this.defaultSymbolSpace = new SymbolSpace(codeModel);
 153         defaultSymbolSpace.setType(codeModel.ref(Object.class));
 154 
 155         elementMappings.put(null,new HashMap<QName,CElementInfo>());
 156 
 157         if(opts.automaticNameConflictResolution)
 158             allocator = new AutoClassNameAllocator(allocator);
 159         this.allocator = new ClassNameAllocatorWrapper(allocator);
 160         this.schemaComponent = schemaComponent;
 161         this.gloablCustomizations.setParent(this,this);
 162     }
 163 
 164     public void setNameConverter(NameConverter nameConverter) {
 165         assert this.nameConverter==null;
 166         assert nameConverter!=null;
 167         this.nameConverter = nameConverter;
 168     }
 169 
 170     /**
 171      * Gets the name converter that shall be used to parse XML names into Java names.
 172      */
 173     public final NameConverter getNameConverter() {
 174         return nameConverter;
 175     }
 176 
 177     public boolean isPackageLevelAnnotations() {
 178         return packageLevelAnnotations;
 179     }
 180 
 181     public void setPackageLevelAnnotations(boolean packageLevelAnnotations) {


 303                         Messages.format(
 304                             Messages.ERR_UNACKNOWLEDGED_CUSTOMIZATION_LOCATION));
 305                 }
 306             }
 307         }
 308 
 309         if(ehf.hadError())
 310             o = null;
 311         return o;
 312     }
 313 
 314     /**
 315      * Represents the "top-level binding".
 316      *
 317      * <p>
 318      * This is used to support the use of a schema inside WSDL.
 319      * For XML Schema, the top-level binding is a map from
 320      * global element declarations to its representation class.
 321      *
 322      * <p>
 323      * For other schema languages, it should follow the appendicies in
 324      * WSDL (but in practice no one would use WSDL with a schema language
 325      * other than XML Schema, so it doesn't really matter.)
 326      *
 327      * <p>
 328      * This needs to be filled by the front-end.
 329      */
 330     public final Map<QName,CClassInfo> createTopLevelBindings() {
 331         Map<QName,CClassInfo> r = new HashMap<QName,CClassInfo>();
 332         for( CClassInfo b : beans().values() ) {
 333             if(b.isElement())
 334                 r.put(b.getElementName(),b);
 335         }
 336         return r;
 337     }
 338 
 339     public Navigator<NType,NClass,Void,Void> getNavigator() {
 340         return NavigatorImpl.theInstance;
 341     }
 342 
 343     public CNonElement getTypeInfo(NType type) {


 407      */
 408     public XSComponent getSchemaComponent() {
 409         return null;
 410     }
 411 
 412     /**
 413      * @deprecated
 414      *      No line number available for the "root" component.
 415      */
 416     public Locator getLocator() {
 417         LocatorImpl r = new LocatorImpl();
 418         r.setLineNumber(-1);
 419         r.setColumnNumber(-1);
 420         return r;
 421     }
 422 
 423     /**
 424      * Gets the global customizations.
 425      */
 426     public CCustomizations getCustomizations() {
 427         return gloablCustomizations;
 428     }
 429 
 430     /**
 431      * Not implemented in the compile-time model.
 432      */
 433     public Map<String, String> getXmlNs(String namespaceUri) {
 434         return Collections.emptyMap();
 435     }
 436 
 437     public Map<String, String> getSchemaLocations() {
 438         return Collections.emptyMap();
 439     }
 440 
 441     public XmlNsForm getElementFormDefault(String nsUri) {
 442         throw new UnsupportedOperationException();
 443     }
 444 
 445     public XmlNsForm getAttributeFormDefault(String nsUri) {
 446         throw new UnsupportedOperationException();
 447     }


 449     public void dump(Result out) {
 450         // TODO
 451         throw new UnsupportedOperationException();
 452     }
 453 
 454     /*package*/ void add( CEnumLeafInfo e ) {
 455         enums.put( e.getClazz(), e );
 456     }
 457 
 458     /*package*/ void add( CClassInfo ci ) {
 459         beans.put( ci.getClazz(), ci );
 460     }
 461 
 462     /*package*/ void add( CElementInfo ei ) {
 463         NClass clazz = null;
 464         if(ei.getScope()!=null)
 465             clazz = ei.getScope().getClazz();
 466 
 467         Map<QName,CElementInfo> m = elementMappings.get(clazz);
 468         if(m==null)
 469             elementMappings.put(clazz,m=new HashMap<QName,CElementInfo>());
 470         m.put(ei.getElementName(),ei);
 471     }
 472 
 473 
 474     private final Map<JPackage,CClassInfoParent.Package> cache = new HashMap<JPackage,CClassInfoParent.Package>();
 475 
 476     public CClassInfoParent.Package getPackage(JPackage pkg) {
 477         CClassInfoParent.Package r = cache.get(pkg);
 478         if(r==null)
 479             cache.put(pkg,r=new CClassInfoParent.Package(pkg));
 480         return r;
 481     }
 482 
 483     /*package*/ static final Locator EMPTY_LOCATOR;
 484 
 485     static {
 486         LocatorImpl l = new LocatorImpl();
 487         l.setColumnNumber(-1);
 488         l.setLineNumber(-1);
 489         EMPTY_LOCATOR = l;
   1 /*
   2  * Copyright (c) 1997, 2014, 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.xjc.model;
  27 














  28 import com.sun.codemodel.internal.JClass;
  29 import com.sun.codemodel.internal.JCodeModel;
  30 import com.sun.codemodel.internal.JPackage;
  31 import com.sun.tools.internal.xjc.ErrorReceiver;
  32 import com.sun.tools.internal.xjc.Options;
  33 import com.sun.tools.internal.xjc.Plugin;
  34 import com.sun.tools.internal.xjc.api.ClassNameAllocator;
  35 import com.sun.tools.internal.xjc.generator.bean.BeanGenerator;
  36 import com.sun.tools.internal.xjc.generator.bean.ImplStructureStrategy;
  37 import com.sun.tools.internal.xjc.model.nav.NClass;
  38 import com.sun.tools.internal.xjc.model.nav.NType;
  39 import com.sun.tools.internal.xjc.model.nav.NavigatorImpl;
  40 import com.sun.tools.internal.xjc.outline.Outline;
  41 import com.sun.tools.internal.xjc.reader.xmlschema.Messages;
  42 import com.sun.tools.internal.xjc.util.ErrorReceiverFilter;
  43 import com.sun.xml.internal.bind.api.impl.NameConverter;
  44 import com.sun.xml.internal.bind.v2.model.core.Ref;
  45 import com.sun.xml.internal.bind.v2.model.core.TypeInfoSet;
  46 import com.sun.xml.internal.bind.v2.model.nav.Navigator;
  47 import com.sun.xml.internal.bind.v2.util.FlattenIterator;
  48 import com.sun.xml.internal.xsom.XSComponent;
  49 import com.sun.xml.internal.xsom.XSSchemaSet;

  50 import org.xml.sax.Locator;
  51 import org.xml.sax.SAXException;
  52 import org.xml.sax.helpers.LocatorImpl;
  53 
  54 import javax.xml.bind.annotation.XmlAttribute;
  55 import javax.xml.bind.annotation.XmlNsForm;
  56 import javax.xml.bind.annotation.XmlTransient;
  57 import javax.xml.namespace.QName;
  58 import javax.xml.transform.Result;
  59 import java.util.Collections;
  60 import java.util.HashMap;
  61 import java.util.HashSet;
  62 import java.util.Iterator;
  63 import java.util.LinkedHashMap;
  64 import java.util.Map;
  65 import java.util.Set;
  66 
  67 /**
  68  * Root of the object model that represents the code that needs to be generated.
  69  *
  70  * <p>
  71  * A {@link Model} is a schema language neutral representation of the
  72  * result of a schema parsing. The back-end then works against this model
  73  * to turn this into a series of Java source code.
  74  *
  75  * @author Kohsuke Kawaguchi
  76  */
  77 public final class Model implements TypeInfoSet<NType,NClass,Void,Void>, CCustomizable {
  78 
  79     /**
  80      * Generated beans.
  81      */
  82     private final Map<NClass,CClassInfo> beans = new LinkedHashMap<NClass,CClassInfo>();
  83 
  84     /**
  85      * Generated enums.
  86      */
  87     private final Map<NClass,CEnumLeafInfo> enums = new LinkedHashMap<NClass,CEnumLeafInfo>();
  88 
  89     /**
  90      * The element mappings.
  91      */
  92     private final Map<NClass/*scope*/,Map<QName,CElementInfo>> elementMappings =
  93             new LinkedHashMap<NClass, Map<QName, CElementInfo>>();
  94 
  95     private final Iterable<? extends CElementInfo> allElements =
  96         new Iterable<CElementInfo>() {
  97             public Iterator<CElementInfo> iterator() {
  98                 return new FlattenIterator<CElementInfo>(elementMappings.values());
  99             }
 100         };
 101 
 102     /**
 103      * {@link TypeUse}s for all named types.
 104      * <p>
 105      * I really don't want to promote the notion of a 'type' in any place except in the XML Schema code,
 106      * but this needs to be exposed for JAX-RPC. A reference to a named XML type will be converted into
 107      * a reference to a Java type with annotations.
 108      */
 109     private final Map<QName,TypeUse> typeUses = new LinkedHashMap<QName, TypeUse>();
 110 
 111     /**
 112      * {@link NameConverter} to be used.
 113      */
 114     private NameConverter nameConverter;
 115 
 116     /**
 117      * Single linked list that connects all {@link CCustomizations} that belong to this model.
 118      *
 119      * @see CCustomizations#next
 120      */
 121     /*package*/ CCustomizations customizations;
 122 
 123     /**
 124      * This field controls the generation of package level annotations for s2j
 125      */
 126     private boolean packageLevelAnnotations = true;
 127 
 128     /**
 129      * If this model was built from XML Schema, this field
 130      * stores the root object of the parse schema model.
 131      * Otherwise null.
 132      *
 133      * @since 2.1.1
 134      */
 135     public final XSSchemaSet schemaComponent;
 136 
 137     private CCustomizations globalCustomizations = new CCustomizations();
 138 
 139     /**
 140      * @param nc
 141      *      Usually this should be set in the constructor, but we do allow this parameter
 142      *      to be initially null, and then set later.
 143      * @param schemaComponent
 144      *      The source schema model, if this is built from XSD.
 145      */
 146     public Model( Options opts, JCodeModel cm, NameConverter nc, ClassNameAllocator allocator, XSSchemaSet schemaComponent ) {
 147         this.options = opts;
 148         this.codeModel = cm;
 149         this.nameConverter = nc;
 150         this.defaultSymbolSpace = new SymbolSpace(codeModel);
 151         defaultSymbolSpace.setType(codeModel.ref(Object.class));
 152 
 153         elementMappings.put(null, new LinkedHashMap<QName, CElementInfo>());
 154 
 155         if(opts.automaticNameConflictResolution)
 156             allocator = new AutoClassNameAllocator(allocator);
 157         this.allocator = new ClassNameAllocatorWrapper(allocator);
 158         this.schemaComponent = schemaComponent;
 159         this.globalCustomizations.setParent(this, this);
 160     }
 161 
 162     public void setNameConverter(NameConverter nameConverter) {
 163         assert this.nameConverter==null;
 164         assert nameConverter!=null;
 165         this.nameConverter = nameConverter;
 166     }
 167 
 168     /**
 169      * Gets the name converter that shall be used to parse XML names into Java names.
 170      */
 171     public final NameConverter getNameConverter() {
 172         return nameConverter;
 173     }
 174 
 175     public boolean isPackageLevelAnnotations() {
 176         return packageLevelAnnotations;
 177     }
 178 
 179     public void setPackageLevelAnnotations(boolean packageLevelAnnotations) {


 301                         Messages.format(
 302                             Messages.ERR_UNACKNOWLEDGED_CUSTOMIZATION_LOCATION));
 303                 }
 304             }
 305         }
 306 
 307         if(ehf.hadError())
 308             o = null;
 309         return o;
 310     }
 311 
 312     /**
 313      * Represents the "top-level binding".
 314      *
 315      * <p>
 316      * This is used to support the use of a schema inside WSDL.
 317      * For XML Schema, the top-level binding is a map from
 318      * global element declarations to its representation class.
 319      *
 320      * <p>
 321      * For other schema languages, it should follow the appendices in
 322      * WSDL (but in practice no one would use WSDL with a schema language
 323      * other than XML Schema, so it doesn't really matter.)
 324      *
 325      * <p>
 326      * This needs to be filled by the front-end.
 327      */
 328     public final Map<QName,CClassInfo> createTopLevelBindings() {
 329         Map<QName,CClassInfo> r = new HashMap<QName,CClassInfo>();
 330         for( CClassInfo b : beans().values() ) {
 331             if(b.isElement())
 332                 r.put(b.getElementName(),b);
 333         }
 334         return r;
 335     }
 336 
 337     public Navigator<NType,NClass,Void,Void> getNavigator() {
 338         return NavigatorImpl.theInstance;
 339     }
 340 
 341     public CNonElement getTypeInfo(NType type) {


 405      */
 406     public XSComponent getSchemaComponent() {
 407         return null;
 408     }
 409 
 410     /**
 411      * @deprecated
 412      *      No line number available for the "root" component.
 413      */
 414     public Locator getLocator() {
 415         LocatorImpl r = new LocatorImpl();
 416         r.setLineNumber(-1);
 417         r.setColumnNumber(-1);
 418         return r;
 419     }
 420 
 421     /**
 422      * Gets the global customizations.
 423      */
 424     public CCustomizations getCustomizations() {
 425         return globalCustomizations;
 426     }
 427 
 428     /**
 429      * Not implemented in the compile-time model.
 430      */
 431     public Map<String, String> getXmlNs(String namespaceUri) {
 432         return Collections.emptyMap();
 433     }
 434 
 435     public Map<String, String> getSchemaLocations() {
 436         return Collections.emptyMap();
 437     }
 438 
 439     public XmlNsForm getElementFormDefault(String nsUri) {
 440         throw new UnsupportedOperationException();
 441     }
 442 
 443     public XmlNsForm getAttributeFormDefault(String nsUri) {
 444         throw new UnsupportedOperationException();
 445     }


 447     public void dump(Result out) {
 448         // TODO
 449         throw new UnsupportedOperationException();
 450     }
 451 
 452     /*package*/ void add( CEnumLeafInfo e ) {
 453         enums.put( e.getClazz(), e );
 454     }
 455 
 456     /*package*/ void add( CClassInfo ci ) {
 457         beans.put( ci.getClazz(), ci );
 458     }
 459 
 460     /*package*/ void add( CElementInfo ei ) {
 461         NClass clazz = null;
 462         if(ei.getScope()!=null)
 463             clazz = ei.getScope().getClazz();
 464 
 465         Map<QName,CElementInfo> m = elementMappings.get(clazz);
 466         if(m==null)
 467             elementMappings.put(clazz, m = new LinkedHashMap<QName, CElementInfo>());
 468         m.put(ei.getElementName(),ei);
 469     }
 470 
 471 
 472     private final Map<JPackage,CClassInfoParent.Package> cache = new HashMap<JPackage,CClassInfoParent.Package>();
 473 
 474     public CClassInfoParent.Package getPackage(JPackage pkg) {
 475         CClassInfoParent.Package r = cache.get(pkg);
 476         if(r==null)
 477             cache.put(pkg,r=new CClassInfoParent.Package(pkg));
 478         return r;
 479     }
 480 
 481     /*package*/ static final Locator EMPTY_LOCATOR;
 482 
 483     static {
 484         LocatorImpl l = new LocatorImpl();
 485         l.setColumnNumber(-1);
 486         l.setLineNumber(-1);
 487         EMPTY_LOCATOR = l;
< prev index next >