View Javadoc

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