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 package org.apache.geronimo.axis.builder;
018
019 import java.beans.IntrospectionException;
020 import java.beans.Introspector;
021 import java.beans.PropertyDescriptor;
022 import java.util.ArrayList;
023 import java.util.HashMap;
024 import java.util.Iterator;
025 import java.util.List;
026 import java.util.Map;
027 import java.util.Set;
028
029 import javax.xml.namespace.QName;
030
031 import org.apache.axis.description.ElementDesc;
032 import org.apache.axis.description.FieldDesc;
033 import org.apache.axis.encoding.ser.ArrayDeserializerFactory;
034 import org.apache.axis.encoding.ser.ArraySerializerFactory;
035 import org.apache.axis.encoding.ser.BeanDeserializerFactory;
036 import org.apache.axis.encoding.ser.BeanSerializerFactory;
037 import org.apache.geronimo.axis.client.TypeInfo;
038 import org.apache.geronimo.common.DeploymentException;
039 import org.apache.geronimo.kernel.ClassLoading;
040 import org.apache.geronimo.xbeans.j2ee.JavaWsdlMappingType;
041 import org.apache.geronimo.webservices.builder.SchemaTypeKey;
042 import org.apache.geronimo.webservices.builder.WSDescriptorParser;
043 import org.apache.xmlbeans.SchemaParticle;
044 import org.apache.xmlbeans.SchemaType;
045
046 /**
047 * @version $Rev: 476049 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $
048 */
049 public class LightweightTypeInfoBuilder implements TypeInfoBuilder {
050 private final ClassLoader cl;
051 private final Map schemaTypeKeyToSchemaTypeMap;
052 private final Set wrapperElementQNames;
053
054 public LightweightTypeInfoBuilder(ClassLoader cl, Map schemaTypeKeyToSchemaTypeMap, Set wrapperElementQNames) {
055 this.cl = cl;
056 this.schemaTypeKeyToSchemaTypeMap = schemaTypeKeyToSchemaTypeMap;
057 this.wrapperElementQNames = wrapperElementQNames;
058 }
059
060 public List buildTypeInfo(JavaWsdlMappingType mapping) throws DeploymentException {
061 List typeInfoList = new ArrayList();
062
063 for (Iterator iterator = schemaTypeKeyToSchemaTypeMap.keySet().iterator(); iterator.hasNext();) {
064 SchemaTypeKey key = (SchemaTypeKey) iterator.next();
065 if (!key.isElement() && !key.isAnonymous()) {
066 //default settings
067 QName typeQName = key.getqName();
068 String namespace = typeQName.getNamespaceURI();
069 String packageName = WSDescriptorParser.getPackageFromNamespace(namespace, mapping);
070 String classShortName = typeQName.getLocalPart();
071 String className = packageName + "." + classShortName;
072
073 Class clazz = null;
074 try {
075 clazz = ClassLoading.loadClass(className, cl);
076 } catch (ClassNotFoundException e) {
077 throw new DeploymentException("Could not load java type", e);
078 }
079
080 Class serializerFactoryClass = BeanSerializerFactory.class;
081 Class deserializerFactoryClass = BeanDeserializerFactory.class;
082
083 if (clazz.isArray()) {
084 serializerFactoryClass = ArraySerializerFactory.class;
085 deserializerFactoryClass = ArrayDeserializerFactory.class;
086 }
087
088 TypeInfo.UpdatableTypeInfo internalTypeInfo = new TypeInfo.UpdatableTypeInfo();
089 internalTypeInfo.setClazz(clazz);
090 internalTypeInfo.setQName(typeQName);
091 internalTypeInfo.setSerializerClass(serializerFactoryClass);
092 internalTypeInfo.setDeserializerClass(deserializerFactoryClass);
093
094 populateInternalTypeInfo(clazz, typeQName, key, internalTypeInfo);
095
096 typeInfoList.add(internalTypeInfo.buildTypeInfo());
097 }
098 }
099
100 return typeInfoList;
101 }
102
103 private void populateInternalTypeInfo(Class javaClass, QName typeQName, SchemaTypeKey key, TypeInfo.UpdatableTypeInfo typeInfo) throws DeploymentException {
104 SchemaType schemaType = (SchemaType) schemaTypeKeyToSchemaTypeMap.get(key);
105 if (schemaType == null) {
106 throw new DeploymentException("Schema type key " + key + " not found in analyzed schema: " + schemaTypeKeyToSchemaTypeMap);
107 }
108 typeInfo.setCanSearchParents(schemaType.getDerivationType() == SchemaType.DT_RESTRICTION);
109
110 Map nameToType = new HashMap();
111 if (null == schemaType.getContentModel()) {
112 ;
113 } else if (SchemaParticle.SEQUENCE == schemaType.getContentModel().getParticleType()
114 || SchemaParticle.ALL == schemaType.getContentModel().getParticleType()) {
115 SchemaParticle[] properties = schemaType.getContentModel().getParticleChildren();
116 for (int i = 0; i < properties.length; i++) {
117 SchemaParticle parameter = properties[i];
118 // if (SchemaParticle.ELEMENT != parameter.getType().getContentModel().getParticleType()) {
119 // throw new DeploymentException(parameter.getName() + " is not an element in schema " + schemaType.getName());
120 // }
121 nameToType.put(parameter.getName(), parameter);
122 }
123 } else if (SchemaParticle.ELEMENT == schemaType.getContentModel().getParticleType()) {
124 SchemaParticle parameter = schemaType.getContentModel();
125 nameToType.put(parameter.getName(), parameter);
126 } else {
127 throw new DeploymentException("Only all, choice and sequence particle types are supported." +
128 " SchemaType name =" + schemaType.getName());
129 }
130
131 PropertyDescriptor[] descriptors;
132 try {
133 descriptors = Introspector.getBeanInfo(javaClass).getPropertyDescriptors();
134 } catch (IntrospectionException e) {
135 throw new DeploymentException("Class " + javaClass + " is not a valid javabean", e);
136 }
137 Map nameToClass = new HashMap();
138 for (int i = 0; i < descriptors.length; i++) {
139 nameToClass.put(descriptors[i].getName(), descriptors[i].getPropertyType());
140 }
141
142 int idx = 0;
143 FieldDesc[] fields = new FieldDesc[nameToType.size()];
144 typeInfo.setFields(fields);
145 for (Iterator iter = nameToType.entrySet().iterator(); iter.hasNext();) {
146 Map.Entry entry = (Map.Entry) iter.next();
147 QName fieldQName = (QName) entry.getKey();
148 String fieldName = fieldQName.getLocalPart();
149 SchemaParticle particle = (SchemaParticle) entry.getValue();
150
151 ElementDesc elementDesc = new ElementDesc();
152 elementDesc.setFieldName(fieldName);
153
154 Class javaType = (Class) nameToClass.get(fieldName);
155 if (null == javaType) {
156 throw new DeploymentException("Field " + fieldName + " is not defined by class " + javaClass.getName());
157 }
158 elementDesc.setNillable(particle.isNillable());
159 elementDesc.setXmlName(fieldQName);
160 elementDesc.setXmlType(particle.getType().getName());
161
162 if (javaType.isArray()) {
163 elementDesc.setMinOccurs(particle.getIntMinOccurs());
164 elementDesc.setMaxOccurs(particle.getIntMaxOccurs());
165 //TODO axis seems to have the wrong name for this property based on how it is used
166 elementDesc.setMaxOccursUnbounded(particle.getIntMaxOccurs() > 1);
167 }
168
169 fields[idx++] = elementDesc;
170 }
171 }
172 }