/**
*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.axis.builder;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.namespace.QName;
import org.apache.axis.description.ElementDesc;
import org.apache.axis.description.FieldDesc;
import org.apache.axis.encoding.ser.ArrayDeserializerFactory;
import org.apache.axis.encoding.ser.ArraySerializerFactory;
import org.apache.axis.encoding.ser.BeanDeserializerFactory;
import org.apache.axis.encoding.ser.BeanSerializerFactory;
import org.apache.geronimo.axis.client.TypeInfo;
import org.apache.geronimo.common.DeploymentException;
import org.apache.geronimo.kernel.ClassLoading;
import org.apache.geronimo.xbeans.j2ee.JavaWsdlMappingType;
import org.apache.xmlbeans.SchemaParticle;
import org.apache.xmlbeans.SchemaType;
/**
* @version $Rev: 356022 $ $Date: 2005-12-11 21:58:34 +0100 (Sun, 11 Dec 2005) $
*/
public class LightweightTypeInfoBuilder implements TypeInfoBuilder {
private final ClassLoader cl;
private final Map schemaTypeKeyToSchemaTypeMap;
private final Set wrapperElementQNames;
public LightweightTypeInfoBuilder(ClassLoader cl, Map schemaTypeKeyToSchemaTypeMap, Set wrapperElementQNames) {
this.cl = cl;
this.schemaTypeKeyToSchemaTypeMap = schemaTypeKeyToSchemaTypeMap;
this.wrapperElementQNames = wrapperElementQNames;
}
public List buildTypeInfo(JavaWsdlMappingType mapping) throws DeploymentException {
List typeInfoList = new ArrayList();
for (Iterator iterator = schemaTypeKeyToSchemaTypeMap.keySet().iterator(); iterator.hasNext();) {
SchemaTypeKey key = (SchemaTypeKey) iterator.next();
if (!key.isElement() && !key.isAnonymous()) {
//default settings
QName typeQName = key.getqName();
String namespace = typeQName.getNamespaceURI();
String packageName = WSDescriptorParser.getPackageFromNamespace(namespace, mapping);
String classShortName = typeQName.getLocalPart();
String className = packageName + "." + classShortName;
Class clazz = null;
try {
clazz = ClassLoading.loadClass(className, cl);
} catch (ClassNotFoundException e) {
throw new DeploymentException("Could not load java type", e);
}
Class serializerFactoryClass = BeanSerializerFactory.class;
Class deserializerFactoryClass = BeanDeserializerFactory.class;
if (clazz.isArray()) {
serializerFactoryClass = ArraySerializerFactory.class;
deserializerFactoryClass = ArrayDeserializerFactory.class;
}
TypeInfo.UpdatableTypeInfo internalTypeInfo = new TypeInfo.UpdatableTypeInfo();
internalTypeInfo.setClazz(clazz);
internalTypeInfo.setQName(typeQName);
internalTypeInfo.setSerializerClass(serializerFactoryClass);
internalTypeInfo.setDeserializerClass(deserializerFactoryClass);
populateInternalTypeInfo(clazz, typeQName, key, internalTypeInfo);
typeInfoList.add(internalTypeInfo.buildTypeInfo());
}
}
return typeInfoList;
}
private void populateInternalTypeInfo(Class javaClass, QName typeQName, SchemaTypeKey key, TypeInfo.UpdatableTypeInfo typeInfo) throws DeploymentException {
SchemaType schemaType = (SchemaType) schemaTypeKeyToSchemaTypeMap.get(key);
if (schemaType == null) {
throw new DeploymentException("Schema type key " + key + " not found in analyzed schema: " + schemaTypeKeyToSchemaTypeMap);
}
typeInfo.setCanSearchParents(schemaType.getDerivationType() == SchemaType.DT_RESTRICTION);
Map nameToType = new HashMap();
if (null == schemaType.getContentModel()) {
;
} else if (SchemaParticle.SEQUENCE == schemaType.getContentModel().getParticleType()
|| SchemaParticle.ALL == schemaType.getContentModel().getParticleType()) {
SchemaParticle[] properties = schemaType.getContentModel().getParticleChildren();
for (int i = 0; i < properties.length; i++) {
SchemaParticle parameter = properties[i];
// if (SchemaParticle.ELEMENT != parameter.getType().getContentModel().getParticleType()) {
// throw new DeploymentException(parameter.getName() + " is not an element in schema " + schemaType.getName());
// }
nameToType.put(parameter.getName(), parameter);
}
} else if (SchemaParticle.ELEMENT == schemaType.getContentModel().getParticleType()) {
SchemaParticle parameter = schemaType.getContentModel();
nameToType.put(parameter.getName(), parameter);
} else {
throw new DeploymentException("Only all, choice and sequence particle types are supported." +
" SchemaType name =" + schemaType.getName());
}
PropertyDescriptor[] descriptors;
try {
descriptors = Introspector.getBeanInfo(javaClass).getPropertyDescriptors();
} catch (IntrospectionException e) {
throw new DeploymentException("Class " + javaClass + " is not a valid javabean", e);
}
Map nameToClass = new HashMap();
for (int i = 0; i < descriptors.length; i++) {
nameToClass.put(descriptors[i].getName(), descriptors[i].getPropertyType());
}
int idx = 0;
FieldDesc[] fields = new FieldDesc[nameToType.size()];
typeInfo.setFields(fields);
for (Iterator iter = nameToType.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
QName fieldQName = (QName) entry.getKey();
String fieldName = fieldQName.getLocalPart();
SchemaParticle particle = (SchemaParticle) entry.getValue();
ElementDesc elementDesc = new ElementDesc();
elementDesc.setFieldName(fieldName);
Class javaType = (Class) nameToClass.get(fieldName);
if (null == javaType) {
throw new DeploymentException("Field " + fieldName + " is not defined by class " + javaClass.getName());
}
elementDesc.setNillable(particle.isNillable());
elementDesc.setXmlName(fieldQName);
elementDesc.setXmlType(particle.getType().getName());
if (javaType.isArray()) {
elementDesc.setMinOccurs(particle.getIntMinOccurs());
elementDesc.setMaxOccurs(particle.getIntMaxOccurs());
//TODO axis seems to have the wrong name for this property based on how it is used
elementDesc.setMaxOccursUnbounded(particle.getIntMaxOccurs() > 1);
}
fields[idx++] = elementDesc;
}
}
}