TypeHierarchyPrinter.java Sample

This topic inludes the source code for the TypeHierarchyPrinter.java Sample.

Sample Location

This sample is located in the following directory in your WebLogic Workshop installation:

BEA_HOME/weblogic81/samples/workshop/SamplesApp/WebServices/xmlBeans/schema/

Sample Source Code


001 package xmlBeans.schema;
002 
003 import com.bea.xbean.tool.CommandLine;
004 import com.bea.xml.XmlObject;
005 import com.bea.xml.XmlOptions;
006 import com.bea.xml.XmlBeans;
007 import com.bea.xml.XmlException;
008 import com.bea.xml.SchemaTypeSystem;
009 import com.bea.xml.SchemaType;
010 
011 import java.util.Collections;
012 import java.util.List;
013 import java.util.ArrayList;
014 import java.util.Collection;
015 import java.util.Iterator;
016 import java.util.HashMap;
017 import java.util.Map;
018 import java.util.Arrays;
019 import java.io.File;
020 
021 /**
022  * Provides a way to print a hierarchical list of the XML schema types
023  * corresponding to Java types that result from compiling the schema.
024  * The unique "signatures" used to represent the schema types in the hierarchy
025  * are built from several characteristics, including:
026  <ul>
027  <li>The type's position in the schema (for example, is it global or local?).</li>
028  <li>Whether the type is a datatype (complex or simple) or an element or attribute.</li>
029  <li>Whether the type is derived by restriction, union, and so on.</li>
030  </ol>
031  * There isn't yet a public standard for such signatures, but the style used here
032  * is useful for seeing the hierarchy. Keep in mind that if a signature standard does
033  * become adopted, that standard will likely be used by the SchemaType.toString()
034  * method. See the WebLogic Workshop documentation for a more complete description
035  * of the signature conventions used here.
036  <br/><br/>
037  * This class is designed so that it may be used from either another 
038  * component (such as a web service) or from the command line.
039  */
040 public class TypeHierarchyPrinter
041 {
042     /**
043      * Prints a hierarchical list of XML schema types represented by the 
044      * specified <em>typeSystem</em>.
045      */
046     public static String printHierarchy(SchemaTypeSystem typeSystemthrows Exception
047     {
048         // A StringBuffer in which to build the response hierarchy.
049         StringBuffer response = new StringBuffer();
050 
051         // A map for base SchemaType -> Collection of directly derived types.
052         Map childTypes = new HashMap();
053         
054         // Traverse the type containment tree breadthfirst.
055         List allSeenTypes = new ArrayList();
056         // Document types are special types that hold the globally defined elements.
057         allSeenTypes.addAll(Arrays.asList(typeSystem.documentTypes()));
058         // Attribute types are special types that hold the globally defined attributes.
059         allSeenTypes.addAll(Arrays.asList(typeSystem.attributeTypes()));
060         /* 
061          * Global types are globally defined schema types -- such as complex or 
062          * simple types defined just beneath the schema's root in the hierarchy.
063          */
064         allSeenTypes.addAll(Arrays.asList(typeSystem.globalTypes()));
065 
066         /**
067          * Loop through the types to examine, 
068          */
069         for (int i = 0; i < allSeenTypes.size(); i++)
070         {
071             /**
072              * A SchemaType object represents a compiled schema type. This
073              * includes all three of the kinds added to allSeenTypes above.
074              */
075             SchemaType sType = (SchemaType)allSeenTypes.get(i);
076 
077             /*
078              * Recurse through the nested anonymous types as well 
079              * (comment this line to skip nested types). Anonymous types
080              * are defined inside other types.
081              */
082             allSeenTypes.addAll(Arrays.asList(sType.getAnonymousTypes()));
083             
084             /**
085              * Don't examine nested document types, attribute types,
086              * or the base type of anyType.
087              */  
088             if (sType.isDocumentType() || sType.isAttributeType() || sType == XmlObject.type)
089                 continue;
090             
091             // Enter this type in the list of children of its base type.
092             Collection children = (Collection)childTypes.get(sType.getBaseType());
093             if (children == null)
094             {
095                 children = new ArrayList();
096                 childTypes.put(sType.getBaseType(), children);
097                 
098                 /**
099                  * The first time a built-in type is seen add it, too,
100                  * to get a complete tree up to anyType, the root. A built-in type
101                  * is a schema type defined by the schema specification, 
102                  * such as xs:string, xs:int, xs:anyType, and so on.
103                  */  
104                 if (sType.getBaseType().isBuiltinType())
105                     allSeenTypes.add(sType.getBaseType());
106             }
107             children.add(sType);
108         }
109         
110         /**
111          * Print the hierarchy tree. 
112          */
113         List typesToPrint = new ArrayList();
114 
115         // Add anyType, from which all others inherit.
116         typesToPrint.add(XmlObject.type);
117 
118         // Create a buffer to hold the indentation spaces.
119         StringBuffer spaces = new StringBuffer();
120 
121         /**
122          * Loop through the list of types, adding the hierarchy branch
123          * symbols and type "signatures".
124          */
125         while (!typesToPrint.isEmpty())
126         {
127             SchemaType sType = (SchemaType)typesToPrint.remove(typesToPrint.size() 1);
128             if (sType == null)
129                 spaces.setLength(Math.max(0, spaces.length() 2));
130             else
131             {
132                 /**
133                  * The SchemaType.toString() method returns a String containing
134                  * the schema type "signature". 
135                  */
136                 response.append(spaces + "+-" + sType.toString() "\n");
137                 Collection children = (Collection)childTypes.get(sType);
138                 if (children != null && children.size() 0)
139                 {
140                     spaces.append(typesToPrint.size() == || typesToPrint.get(typesToPrint.size() 1== null "  " "| ");
141                     typesToPrint.add(null);
142                     typesToPrint.addAll(children);
143                 }
144             }
145         }
146         return response.toString();
147     }
148     
149     /**
150      * Creates a schema type system from an array of XSD files. This method
151      * is called when this class is used from the command line.
152      */
153     public static SchemaTypeSystem typeSystemFromFiles(File[] schemaFiles)
154     {
155         /* 
156          * A SchemaTypeSystem object will hold the type system created by
157          * compiling the schema types.
158          */
159         SchemaTypeSystem typeSystem = null;
160         
161         List sdocs = new ArrayList();
162 
163         /**
164          * Loop through the File array, parsing the contents of each schema 
165          * file into an XmlObject instance. These objects will be passed to
166          * a method that compiles the schemas.
167          */
168         for (int i = 0; i < schemaFiles.length; i++)
169         {
170             try
171             {
172                 sdocs.add(XmlObject.Factory.parse(
173                     schemaFiles[i](new XmlOptions()).setLoadLineNumbers()));
174             }
175             catch (Exception e)
176             {
177                 System.err.printlnschemaFiles[i" not loadable: " + e );
178             }
179         }
180         XmlObject[] schemas = (XmlObject[])sdocs.toArray(new XmlObject[0]);
181 
182         /**
183          * Compile each schema. Use a Collection object to collect any
184          * errors that arise during compilation. 
185          */
186         Collection compErrors = new ArrayList();
187         try
188         {
189             /**
190              * Compile the schemas, specifying also the built-in type system
191              * to consult for already-compiled schema types which 
192              * may be linked while processing the given schemas. 
193              */
194             typeSystem = XmlBeans.compileXsd(schemas, 
195                 XmlBeans.getBuiltinTypeSystem()
196                 new XmlOptions().setErrorListener(compErrors).setCompileDownloadUrls());
197         }
198         catch (XmlException e)
199         {
200             System.out.println("Schema invalid");
201             for (Iterator i = compErrors.iterator(); i.hasNext())
202                 System.out.println(i.next());
203         }
204         return typeSystem;
205     }
206     
207     /**
208      * A main method so that this class may be used from the command
209      * line.
210      */
211     public static void main(String[] argsthrows Exception
212     {
213         CommandLine cl = new CommandLine(args, Collections.EMPTY_SET);
214         File[] schemaFiles = cl.getFiles();
215         
216         SchemaTypeSystem typeSystem = typeSystemFromFiles(schemaFiles);
217         String hierarchy = printHierarchy(typeSystem);
218         System.out.println(hierarchy);
219     }
220     
221 }