< prev index next >

jaxws/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/schemagen/XmlSchemaGenerator.java

Print this page


   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


  93 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.LocalAttribute;
  94 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.LocalElement;
  95 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Schema;
  96 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.SimpleExtension;
  97 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.SimpleRestrictionModel;
  98 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.SimpleType;
  99 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.SimpleTypeHost;
 100 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.TopLevelAttribute;
 101 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.TopLevelElement;
 102 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.TypeHost;
 103 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.ContentModelContainer;
 104 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.TypeDefParticle;
 105 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.AttributeType;
 106 import com.sun.xml.internal.bind.v2.schemagen.episode.Bindings;
 107 import com.sun.xml.internal.txw2.TXW;
 108 import com.sun.xml.internal.txw2.TxwException;
 109 import com.sun.xml.internal.txw2.TypedXmlWriter;
 110 import com.sun.xml.internal.txw2.output.ResultFactory;
 111 import com.sun.xml.internal.txw2.output.XmlSerializer;
 112 import java.util.Collection;

 113 import org.xml.sax.SAXParseException;
 114 
 115 /**
 116  * Generates a set of W3C XML Schema documents from a set of Java classes.
 117  *
 118  * <p>
 119  * A client must invoke methods in the following order:
 120  * <ol>
 121  *  <li>Create a new {@link XmlSchemaGenerator}
 122  *  <li>Invoke {@link #add} methods, multiple times if necessary.
 123  *  <li>Invoke {@link #write}
 124  *  <li>Discard the {@link XmlSchemaGenerator}.
 125  * </ol>
 126  *
 127  * @author Ryan Shoemaker
 128  * @author Kohsuke Kawaguchi (kk@kohsuke.org)
 129  */
 130 public final class XmlSchemaGenerator<T,C,F,M> {
 131 
 132     private static final Logger logger = Util.getClassLogger();


 419                 Bindings child = group.bindings();
 420                 child.scd('~'+prefix+en.getTypeName().getLocalPart());
 421                 child.klass().ref(navigator.getClassName(en.getClazz()));
 422             }
 423 
 424             group.commit(true);
 425         }
 426 
 427         root.commit();
 428     }
 429 
 430     /**
 431      * Write out the schema documents.
 432      */
 433     public void write(SchemaOutputResolver resolver, ErrorListener errorListener) throws IOException {
 434         if(resolver==null)
 435             throw new IllegalArgumentException();
 436 
 437         if(logger.isLoggable(Level.FINE)) {
 438             // debug logging to see what's going on.
 439             logger.log(Level.FINE,"Wrigin XML Schema for "+toString(),new StackRecorder());
 440         }
 441 
 442         // make it fool-proof
 443         resolver = new FoolProofResolver(resolver);
 444         this.errorListener = errorListener;
 445 
 446         Map<String, String> schemaLocations = types.getSchemaLocations();
 447 
 448         Map<Namespace,Result> out = new HashMap<Namespace,Result>();
 449         Map<Namespace,String> systemIds = new HashMap<Namespace,String>();
 450 
 451         // we create a Namespace object for the XML Schema namespace
 452         // as a side-effect, but we don't want to generate it.
 453         namespaces.remove(WellKnownNamespace.XML_SCHEMA);
 454 
 455         // first create the outputs for all so that we can resolve references among
 456         // schema files when we write
 457         for( Namespace n : namespaces.values() ) {
 458             String schemaLocation = schemaLocations.get(n.uri);
 459             if(schemaLocation!=null) {
 460                 systemIds.put(n,schemaLocation);
 461             } else {
 462                 Result output = resolver.createOutput(n.uri,"schema"+(out.size()+1)+".xsd");
 463                 if(output!=null) {  // null result means no schema for that namespace
 464                     out.put(n,output);
 465                     systemIds.put(n,output.getSystemId());
 466                 }
 467             }


 468         }
 469 
 470         // then write'em all
 471         for( Map.Entry<Namespace,Result> e : out.entrySet() ) {
 472             Result result = e.getValue();
 473             e.getKey().writeTo( result, systemIds );
 474             if(result instanceof StreamResult) {
 475                 OutputStream outputStream = ((StreamResult)result).getOutputStream();
 476                 if(outputStream != null) {
 477                     outputStream.close(); // fix for bugid: 6291301
 478                 } else {
 479                     final Writer writer = ((StreamResult)result).getWriter();
 480                     if(writer != null) writer.close();
 481                 }
 482             }
 483         }
 484     }
 485 
 486 
 487 


 525          * Global element declarations to be written, keyed by their local names.
 526          */
 527         private final MultiMap<String,ElementDeclaration> elementDecls =
 528                 new MultiMap<String,ElementDeclaration>(new ElementWithType(true,anyType));
 529 
 530         private Form attributeFormDefault;
 531         private Form elementFormDefault;
 532 
 533         /**
 534          * Does schema in this namespace uses swaRef? If so, we need to generate import
 535          * statement.
 536          */
 537         private boolean useSwaRef;
 538 
 539         /**
 540          * Import for mime namespace needs to be generated.
 541          * See #856
 542          */
 543         private boolean useMimeNs;
 544 





 545         public Namespace(String uri) {
 546             this.uri = uri;
 547             assert !XmlSchemaGenerator.this.namespaces.containsKey(uri);
 548             XmlSchemaGenerator.this.namespaces.put(uri,this);
 549         }
 550 
 551         /**







 552          * Process the given PropertyInfo looking for references to namespaces that
 553          * are foreign to the given namespace.  Any foreign namespace references
 554          * found are added to the given namespaces dependency list and an &lt;import>
 555          * is generated for it.
 556          *
 557          * @param p the PropertyInfo
 558          */
 559         private void processForeignNamespaces(PropertyInfo<T, C> p, int processingDepth) {
 560             for (TypeInfo<T, C> t : p.ref()) {
 561                 if ((t instanceof ClassInfo) && (processingDepth > 0)) {
 562                     java.util.List<PropertyInfo> l = ((ClassInfo) t).getProperties();
 563                     for (PropertyInfo subp : l) {
 564                         processForeignNamespaces(subp, --processingDepth);
 565                     }
 566                 }
 567                 if (t instanceof Element) {
 568                     addDependencyTo(((Element) t).getElementName());
 569                 }
 570                 if (t instanceof NonElement) {
 571                     addDependencyTo(((NonElement) t).getTypeName());


 836         private void writeEnum(EnumLeafInfo<T, C> e, SimpleTypeHost th) {
 837             SimpleType st = th.simpleType();
 838             writeName(e,st);
 839 
 840             SimpleRestrictionModel base = st.restriction();
 841             writeTypeRef(base, e.getBaseType(), "base");
 842 
 843             for (EnumConstant c : e.getConstants()) {
 844                 base.enumeration().value(c.getLexicalValue());
 845             }
 846             st.commit();
 847         }
 848 
 849         /**
 850          * Writes the schema definition for the specified class to the schema writer.
 851          *
 852          * @param c the class info
 853          * @param parent the writer of the parent element into which the type will be defined
 854          */
 855         private void writeClass(ClassInfo<T,C> c, TypeHost parent) {




 856             // special handling for value properties
 857             if (containsValueProp(c)) {
 858                 if (c.getProperties().size() == 1) {
 859                     // [RESULT 2 - simpleType if the value prop is the only prop]
 860                     //
 861                     // <simpleType name="foo">
 862                     //   <xs:restriction base="xs:int"/>
 863                     // </>
 864                     ValuePropertyInfo<T,C> vp = (ValuePropertyInfo<T,C>)c.getProperties().get(0);
 865                     SimpleType st = ((SimpleTypeHost)parent).simpleType();
 866                     writeName(c, st);
 867                     if(vp.isCollection()) {
 868                         writeTypeRef(st.list(),vp.getTarget(),"itemType");
 869                     } else {
 870                         writeTypeRef(st.restriction(),vp.getTarget(),"base");
 871                     }
 872                     return;
 873                 } else {
 874                     // [RESULT 1 - complexType with simpleContent]
 875                     //


   1 /*
   2  * Copyright (c) 1997, 2016, 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


  93 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.LocalAttribute;
  94 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.LocalElement;
  95 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.Schema;
  96 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.SimpleExtension;
  97 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.SimpleRestrictionModel;
  98 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.SimpleType;
  99 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.SimpleTypeHost;
 100 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.TopLevelAttribute;
 101 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.TopLevelElement;
 102 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.TypeHost;
 103 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.ContentModelContainer;
 104 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.TypeDefParticle;
 105 import com.sun.xml.internal.bind.v2.schemagen.xmlschema.AttributeType;
 106 import com.sun.xml.internal.bind.v2.schemagen.episode.Bindings;
 107 import com.sun.xml.internal.txw2.TXW;
 108 import com.sun.xml.internal.txw2.TxwException;
 109 import com.sun.xml.internal.txw2.TypedXmlWriter;
 110 import com.sun.xml.internal.txw2.output.ResultFactory;
 111 import com.sun.xml.internal.txw2.output.XmlSerializer;
 112 import java.util.Collection;
 113 import java.util.HashSet;
 114 import org.xml.sax.SAXParseException;
 115 
 116 /**
 117  * Generates a set of W3C XML Schema documents from a set of Java classes.
 118  *
 119  * <p>
 120  * A client must invoke methods in the following order:
 121  * <ol>
 122  *  <li>Create a new {@link XmlSchemaGenerator}
 123  *  <li>Invoke {@link #add} methods, multiple times if necessary.
 124  *  <li>Invoke {@link #write}
 125  *  <li>Discard the {@link XmlSchemaGenerator}.
 126  * </ol>
 127  *
 128  * @author Ryan Shoemaker
 129  * @author Kohsuke Kawaguchi (kk@kohsuke.org)
 130  */
 131 public final class XmlSchemaGenerator<T,C,F,M> {
 132 
 133     private static final Logger logger = Util.getClassLogger();


 420                 Bindings child = group.bindings();
 421                 child.scd('~'+prefix+en.getTypeName().getLocalPart());
 422                 child.klass().ref(navigator.getClassName(en.getClazz()));
 423             }
 424 
 425             group.commit(true);
 426         }
 427 
 428         root.commit();
 429     }
 430 
 431     /**
 432      * Write out the schema documents.
 433      */
 434     public void write(SchemaOutputResolver resolver, ErrorListener errorListener) throws IOException {
 435         if(resolver==null)
 436             throw new IllegalArgumentException();
 437 
 438         if(logger.isLoggable(Level.FINE)) {
 439             // debug logging to see what's going on.
 440             logger.log(Level.FINE,"Writing XML Schema for "+toString(),new StackRecorder());
 441         }
 442 
 443         // make it fool-proof
 444         resolver = new FoolProofResolver(resolver);
 445         this.errorListener = errorListener;
 446 
 447         Map<String, String> schemaLocations = types.getSchemaLocations();
 448 
 449         Map<Namespace,Result> out = new HashMap<Namespace,Result>();
 450         Map<Namespace,String> systemIds = new HashMap<Namespace,String>();
 451 
 452         // we create a Namespace object for the XML Schema namespace
 453         // as a side-effect, but we don't want to generate it.
 454         namespaces.remove(WellKnownNamespace.XML_SCHEMA);
 455 
 456         // first create the outputs for all so that we can resolve references among
 457         // schema files when we write
 458         for( Namespace n : namespaces.values() ) {
 459             String schemaLocation = schemaLocations.get(n.uri);
 460             if(schemaLocation!=null) {
 461                 systemIds.put(n,schemaLocation);
 462             } else {
 463                 Result output = resolver.createOutput(n.uri,"schema"+(out.size()+1)+".xsd");
 464                 if(output!=null) {  // null result means no schema for that namespace
 465                     out.put(n,output);
 466                     systemIds.put(n,output.getSystemId());
 467                 }
 468             }
 469             //Clear the namespace specific set with already written classes
 470             n.resetWritten();
 471         }
 472 
 473         // then write'em all
 474         for( Map.Entry<Namespace,Result> e : out.entrySet() ) {
 475             Result result = e.getValue();
 476             e.getKey().writeTo( result, systemIds );
 477             if(result instanceof StreamResult) {
 478                 OutputStream outputStream = ((StreamResult)result).getOutputStream();
 479                 if(outputStream != null) {
 480                     outputStream.close(); // fix for bugid: 6291301
 481                 } else {
 482                     final Writer writer = ((StreamResult)result).getWriter();
 483                     if(writer != null) writer.close();
 484                 }
 485             }
 486         }
 487     }
 488 
 489 
 490 


 528          * Global element declarations to be written, keyed by their local names.
 529          */
 530         private final MultiMap<String,ElementDeclaration> elementDecls =
 531                 new MultiMap<String,ElementDeclaration>(new ElementWithType(true,anyType));
 532 
 533         private Form attributeFormDefault;
 534         private Form elementFormDefault;
 535 
 536         /**
 537          * Does schema in this namespace uses swaRef? If so, we need to generate import
 538          * statement.
 539          */
 540         private boolean useSwaRef;
 541 
 542         /**
 543          * Import for mime namespace needs to be generated.
 544          * See #856
 545          */
 546         private boolean useMimeNs;
 547 
 548         /**
 549          * Container for already processed classes
 550          */
 551         private final Set<ClassInfo> written = new HashSet<ClassInfo>();
 552 
 553         public Namespace(String uri) {
 554             this.uri = uri;
 555             assert !XmlSchemaGenerator.this.namespaces.containsKey(uri);
 556             XmlSchemaGenerator.this.namespaces.put(uri,this);
 557         }
 558 
 559         /**
 560          * Clear out the set of already processed classes for this namespace
 561          */
 562         void resetWritten() {
 563             written.clear();
 564         }
 565 
 566         /**
 567          * Process the given PropertyInfo looking for references to namespaces that
 568          * are foreign to the given namespace.  Any foreign namespace references
 569          * found are added to the given namespaces dependency list and an &lt;import>
 570          * is generated for it.
 571          *
 572          * @param p the PropertyInfo
 573          */
 574         private void processForeignNamespaces(PropertyInfo<T, C> p, int processingDepth) {
 575             for (TypeInfo<T, C> t : p.ref()) {
 576                 if ((t instanceof ClassInfo) && (processingDepth > 0)) {
 577                     java.util.List<PropertyInfo> l = ((ClassInfo) t).getProperties();
 578                     for (PropertyInfo subp : l) {
 579                         processForeignNamespaces(subp, --processingDepth);
 580                     }
 581                 }
 582                 if (t instanceof Element) {
 583                     addDependencyTo(((Element) t).getElementName());
 584                 }
 585                 if (t instanceof NonElement) {
 586                     addDependencyTo(((NonElement) t).getTypeName());


 851         private void writeEnum(EnumLeafInfo<T, C> e, SimpleTypeHost th) {
 852             SimpleType st = th.simpleType();
 853             writeName(e,st);
 854 
 855             SimpleRestrictionModel base = st.restriction();
 856             writeTypeRef(base, e.getBaseType(), "base");
 857 
 858             for (EnumConstant c : e.getConstants()) {
 859                 base.enumeration().value(c.getLexicalValue());
 860             }
 861             st.commit();
 862         }
 863 
 864         /**
 865          * Writes the schema definition for the specified class to the schema writer.
 866          *
 867          * @param c the class info
 868          * @param parent the writer of the parent element into which the type will be defined
 869          */
 870         private void writeClass(ClassInfo<T,C> c, TypeHost parent) {
 871             if (written.contains(c)) { // to avoid cycles let's check if we haven't already processed the class
 872                 return;
 873             }
 874             written.add(c);
 875             // special handling for value properties
 876             if (containsValueProp(c)) {
 877                 if (c.getProperties().size() == 1) {
 878                     // [RESULT 2 - simpleType if the value prop is the only prop]
 879                     //
 880                     // <simpleType name="foo">
 881                     //   <xs:restriction base="xs:int"/>
 882                     // </>
 883                     ValuePropertyInfo<T,C> vp = (ValuePropertyInfo<T,C>)c.getProperties().get(0);
 884                     SimpleType st = ((SimpleTypeHost)parent).simpleType();
 885                     writeName(c, st);
 886                     if(vp.isCollection()) {
 887                         writeTypeRef(st.list(),vp.getTarget(),"itemType");
 888                     } else {
 889                         writeTypeRef(st.restriction(),vp.getTarget(),"base");
 890                     }
 891                     return;
 892                 } else {
 893                     // [RESULT 1 - complexType with simpleContent]
 894                     //


< prev index next >