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.List;
023
024 import org.apache.commons.betwixt.AttributeDescriptor;
025 import org.apache.commons.betwixt.ElementDescriptor;
026 import org.apache.commons.betwixt.XMLBeanInfo;
027
028 /**
029 * Models a <code>complexType</code>. Global (top level) complex types are
030 * represented by {@link GlobalComplexType}. Locally defined or referenced
031 * complex types are represented by {@link LocalComplexType}.
032 *
033 * @author <a href='http://commons.apache.org/'>Apache Commons Team </a>
034 * @version $Revision: 561314 $
035 */
036 public abstract class ComplexType {
037
038 protected List elements = new ArrayList();
039
040 protected List attributes = new ArrayList();
041
042 public ComplexType() {
043 }
044
045 public ComplexType(TranscriptionConfiguration configuration,
046 ElementDescriptor elementDescriptor, Schema schema)
047 throws IntrospectionException {
048 elementDescriptor = fillDescriptor(elementDescriptor, schema);
049 init(configuration, elementDescriptor, schema);
050 }
051
052 /**
053 * Fills the given descriptor
054 * @since 0.7
055 * @param elementDescriptor
056 * @param schema
057 * @return @throws
058 * IntrospectionException
059 */
060 protected ElementDescriptor fillDescriptor(
061 ElementDescriptor elementDescriptor, Schema schema)
062 throws IntrospectionException {
063 if (elementDescriptor.isHollow()) {
064 // need to introspector for filled descriptor
065 Class type = elementDescriptor.getSingularPropertyType();
066 if (type == null) {
067 type = elementDescriptor.getPropertyType();
068 }
069 if (type == null) {
070 // no type!
071 // TODO: handle this
072 // TODO: add support for logging
073 // TODO: maybe should try singular type?
074 } else {
075 XMLBeanInfo filledBeanInfo = schema.introspect(type);
076 elementDescriptor = filledBeanInfo.getElementDescriptor();
077 }
078 }
079 return elementDescriptor;
080 }
081
082 protected void init(TranscriptionConfiguration configuration,
083 ElementDescriptor elementDescriptor, Schema schema)
084 throws IntrospectionException {
085
086 AttributeDescriptor[] attributeDescriptors = elementDescriptor
087 .getAttributeDescriptors();
088 for (int i = 0, length = attributeDescriptors.length; i < length; i++) {
089 //TODO: need to think about computing schema types from descriptors
090 // this will probably depend on the class mapped to
091 String uri = attributeDescriptors[i].getURI();
092 if (!SchemaTranscriber.W3C_SCHEMA_INSTANCE_URI.equals(uri)) {
093 attributes.add(new Attribute(attributeDescriptors[i]));
094 }
095 }
096
097 //TODO: add support for spacing elements
098 ElementDescriptor[] elementDescriptors = elementDescriptor
099 .getElementDescriptors();
100 for (int i = 0, length = elementDescriptors.length; i < length; i++) {
101 if (elementDescriptors[i].isHollow()) {
102 elements.add(new ElementReference(configuration,
103 elementDescriptors[i], schema));
104 } else if (elementDescriptors[i].isSimple()) {
105 elements.add(new SimpleLocalElement(configuration,
106 elementDescriptors[i], schema));
107 } else {
108 elements.add(new ComplexLocalElement(configuration,
109 elementDescriptors[i], schema));
110 }
111 }
112 }
113
114 /**
115 * Gets the elements contained by this type
116 *
117 * @return <code>List</code> of contained elements, not null
118 */
119 public List getElements() {
120 return elements;
121 }
122
123 /**
124 * Adds an element to those contained by this type
125 *
126 * @param element
127 */
128 public void addElement(ElementReference element) {
129 elements.add(element);
130 }
131
132 /**
133 * Adds an element to those contained by this type
134 *
135 * @param element
136 */
137 public void addElement(LocalElement element) {
138 elements.add(element);
139 }
140
141 /**
142 * Gets the attributes contained by this type.
143 *
144 * @return <code>List</code> of attributes
145 */
146 public List getAttributes() {
147 return attributes;
148 }
149
150 /**
151 * Adds an attribute to those contained by this type
152 *
153 * @param attribute
154 */
155 public void addAttribute(Attribute attribute) {
156 attributes.add(attribute);
157 }
158
159 }