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: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 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 }