001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.betwixt.schema; 019 020 import java.beans.IntrospectionException; 021 import java.util.ArrayList; 022 import java.util.Collection; 023 import java.util.Iterator; 024 import java.util.List; 025 026 import org.apache.commons.betwixt.ElementDescriptor; 027 import org.apache.commons.betwixt.XMLBeanInfo; 028 import org.apache.commons.betwixt.XMLIntrospector; 029 030 /** 031 * Model for top level element in an XML Schema 032 * 033 * @author <a href='http://commons.apache.org/'>Apache Commons Team</a> 034 * @version $Revision: 561314 $ 035 */ 036 public class Schema { 037 038 private List elements = new ArrayList(); 039 private List complexTypes = new ArrayList(); 040 private List simpleTypes = new ArrayList(); 041 042 private XMLIntrospector introspector; 043 044 public Schema() { 045 this(new XMLIntrospector()); 046 } 047 048 public Schema(XMLIntrospector introspector) { 049 this.introspector = introspector; 050 } 051 052 /** 053 * Introspects the given type giving an <code>XMLBeanInfo</code>. 054 * @param type Class to introspect, not null 055 * @return <code>XMLBeanInfo</code>, not null 056 * @throws IntrospectionException 057 */ 058 public XMLBeanInfo introspect(Class type) throws IntrospectionException { 059 return introspector.introspect(type); 060 } 061 062 /** 063 * Gets the complex types defined 064 * @return list of <code>ComplexType</code>'s not null 065 */ 066 public List getComplexTypes() { 067 return complexTypes; 068 } 069 070 071 /** 072 * Adds a new complex type to those defined 073 * @param complexType not null 074 */ 075 public void addComplexType(GlobalComplexType complexType) { 076 complexTypes.add(complexType); 077 } 078 079 080 /** 081 * Gets the elements definied 082 * @return list of <code>Element</code>s not null 083 */ 084 public List getElements() { 085 return elements; 086 } 087 088 /** 089 * Adds a new element to those defined. 090 * @param element not null 091 */ 092 public void addElement(GlobalElement element) { 093 elements.add(element); 094 } 095 096 /** 097 * Gets the simple types defined. 098 * @return list of <code>SimpleType</code>s not null 099 */ 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 }