View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    * 
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   * 
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */ 
17  
18  package org.apache.commons.betwixt.schema;
19  
20  import java.beans.IntrospectionException;
21  import java.util.ArrayList;
22  import java.util.Collection;
23  import java.util.Iterator;
24  import java.util.List;
25  
26  import org.apache.commons.betwixt.ElementDescriptor;
27  import org.apache.commons.betwixt.XMLBeanInfo;
28  import org.apache.commons.betwixt.XMLIntrospector;
29  
30  /**
31   * Model for top level element in an XML Schema
32   * 
33   * @author <a href='http://commons.apache.org/'>Apache Commons Team</a>
34   * @version $Revision: 561314 $
35   */
36  public class Schema {
37  	
38  	private List elements = new ArrayList();
39  	private List complexTypes = new ArrayList();
40  	private List simpleTypes = new ArrayList(); 
41      
42      private XMLIntrospector introspector;
43  	
44      public Schema() {
45          this(new XMLIntrospector());
46      }
47      
48      public Schema(XMLIntrospector introspector) {
49          this.introspector = introspector;
50      }
51      
52      /**
53       * Introspects the given type giving an <code>XMLBeanInfo</code>.
54       * @param type Class to introspect, not null
55       * @return <code>XMLBeanInfo</code>, not null
56       * @throws IntrospectionException
57       */
58      public XMLBeanInfo introspect(Class type) throws IntrospectionException {
59           return introspector.introspect(type);
60      }
61      
62      /**
63       * Gets the complex types defined
64       * @return list of <code>ComplexType</code>'s not null
65       */
66      public List getComplexTypes() {
67          return complexTypes;
68      }
69  
70  
71  	/**
72  	 * Adds a new complex type to those defined
73  	 * @param complexType not null
74  	 */
75  	public void addComplexType(GlobalComplexType complexType) {
76  		complexTypes.add(complexType);
77  	}
78  	
79  
80      /**
81       * Gets the elements definied
82       * @return list of <code>Element</code>s not null
83       */
84      public List getElements() {
85          return elements;
86      }
87  
88  	/**
89  	 * Adds a new element to those defined.
90  	 * @param element not null
91  	 */
92  	public void addElement(GlobalElement element) {
93  		elements.add(element);
94  	}
95  
96      /**
97       * Gets the simple types defined.
98       * @return list of <code>SimpleType</code>s not null
99       */
100     public List getSimpleTypes() {
101         return simpleTypes;
102     }
103 
104 	/**
105 	 * Adds a new simple type to those defined.
106 	 * @param simpleType
107 	 */
108 	public void addSimpleType(SimpleType simpleType) {
109 		simpleTypes.add(simpleType);
110 	}
111 
112 
113     /**
114      * Adds global (top level) element and type declarations matching the given descriptor.
115      * @param elementDescriptor ElementDescriptor not null
116      */
117     public void addGlobalElementType(TranscriptionConfiguration configuration, ElementDescriptor elementDescriptor) throws IntrospectionException {
118         // need to create a global element declaration and a complex type 
119         // use the fully qualified class name as the type name
120         GlobalElement element = new GlobalElement(
121                             elementDescriptor.getLocalName(), 
122                             configuration.getSchemaTypeNamingStrategy().nameSchemaType(elementDescriptor));
123         addElement(element);
124         addGlobalComplexType(configuration, elementDescriptor);
125     }	
126     
127     /**
128      * Adds a new global complex type definition matching the given element descriptor.
129      * If this element descriptor has already been mapped to a global type then 
130      * that is returned.
131      * @since 0.7
132      * @param configuration <code>TranscriptionConfiguration</code>, not null
133      * @param elementDescriptor <code>ElementDescriptor</code>, not null
134      * @return <code>GlobalComplexType</code>
135      * @throws IntrospectionException
136      */
137     public GlobalComplexType addGlobalComplexType(TranscriptionConfiguration configuration, ElementDescriptor elementDescriptor) throws IntrospectionException  {
138         GlobalComplexType type = null;
139         for (Iterator it = complexTypes.iterator(); it.hasNext();) {
140             GlobalComplexType complexType = (GlobalComplexType) it.next();
141             if (complexType.matches( elementDescriptor )) {
142                 type = complexType;
143                 break;
144             }
145         }
146         if (type == null) {
147              type = new GlobalComplexType(configuration, elementDescriptor, this);
148         		addComplexType(type);
149         		type.fill(configuration, elementDescriptor, this);
150         }
151         return type;
152     }
153 	
154     public boolean equals(Object obj) {
155     	boolean result = false;
156         if (obj instanceof Schema) {
157         	Schema schema = (Schema) obj;
158         	result = 
159                     equalContents(elements, schema.elements) &&
160                     equalContents(complexTypes, schema.complexTypes) &&
161                     equalContents(simpleTypes, schema.simpleTypes);
162         }
163         return result;
164     }
165     
166     private boolean equalContents(Collection one, Collection two)
167     {
168         // doesn't check cardinality but should be ok
169         if (one.size() != two.size()) {
170             return false;
171         }
172         for (Iterator it=one.iterator();it.hasNext();) {
173             Object object = it.next();
174             if (!two.contains(object)) {
175                 return false;
176             }
177         }
178         return true;
179     }
180 
181     public int hashCode() {
182         return 0;
183     }
184     
185 
186 
187     public String toString() {
188         StringBuffer buffer = new StringBuffer();
189         buffer.append("<?xml version='1.0'?>");
190         buffer.append("<xsd:schema xmlns:xsd='http://www.w3c.org/2001/XMLSchema'>");
191         
192         for (Iterator it=simpleTypes.iterator(); it.hasNext();) {
193               buffer.append(it.next());    
194         }    
195         
196         for (Iterator it=complexTypes.iterator(); it.hasNext();) {
197               buffer.append(it.next());    
198         }
199         
200   
201         for (Iterator it=elements.iterator(); it.hasNext();) {
202               buffer.append(it.next());    
203         } 
204         buffer.append("</xsd:schema>");
205         return buffer.toString();
206     }
207 }