/**
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.openejb.server.axis.assembler;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.jee.JavaWsdlMapping;
import org.apache.openejb.jee.PackageMapping;
import javax.xml.namespace.QName;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class LightweightTypeInfoBuilder {
private final JavaWsdlMapping mapping;
private final XmlSchemaInfo schemaInfo;
private final ClassLoader classLoader;
public LightweightTypeInfoBuilder(final JavaWsdlMapping mapping, final XmlSchemaInfo schemaInfo, final ClassLoader classLoader) {
this.mapping = mapping;
this.classLoader = classLoader;
this.schemaInfo = schemaInfo;
}
public List<JaxRpcTypeInfo> buildTypeInfo() throws OpenEJBException {
final List<JaxRpcTypeInfo> typeInfoList = new ArrayList<JaxRpcTypeInfo>();
for (final XmlTypeInfo xmlTypeInfo : schemaInfo.types.values()) {
// skip anonymous elements
if (!xmlTypeInfo.anonymous) {
final QName typeQName = xmlTypeInfo.qname;
final Class clazz = loadClass(typeQName, mapping);
JaxRpcTypeInfo.SerializerType serializerType = JaxRpcTypeInfo.SerializerType.OTHER;
if (clazz.isArray()) {
serializerType = JaxRpcTypeInfo.SerializerType.ARRAY;
}
final JaxRpcTypeInfo typeInfo = new JaxRpcTypeInfo();
typeInfo.qname = typeQName;
typeInfo.javaType = clazz.getName();
typeInfo.serializerType = serializerType;
typeInfo.simpleBaseType = xmlTypeInfo.simpleBaseType;
mapFields(clazz, xmlTypeInfo, typeInfo);
typeInfoList.add(typeInfo);
}
}
return typeInfoList;
}
private void mapFields(final Class javaClass, final XmlTypeInfo xmlTypeInfo, final JaxRpcTypeInfo typeInfo) throws OpenEJBException {
// Map JavaBean property name to propertyType
final Map<String, Class> propertyToClass = new HashMap<String, Class>();
try {
for (final PropertyDescriptor descriptor : Introspector.getBeanInfo(javaClass).getPropertyDescriptors()) {
propertyToClass.put(descriptor.getName(), descriptor.getPropertyType());
}
} catch (final IntrospectionException e) {
throw new OpenEJBException("Class " + javaClass + " is not a valid javabean", e);
}
// Map the elements nexted in the XML Schema Type
for (final XmlElementInfo nestedElement : xmlTypeInfo.elements.values()) {
final String fieldName = nestedElement.qname.getLocalPart();
final Class javaType = propertyToClass.get(fieldName);
if (javaType == null) {
throw new OpenEJBException("Field " + fieldName + " is not defined by class " + javaClass.getName());
}
final JaxRpcFieldInfo fieldInfo = new JaxRpcFieldInfo();
fieldInfo.name = fieldName;
fieldInfo.isNillable = nestedElement.nillable;
fieldInfo.xmlName = nestedElement.qname;
fieldInfo.xmlType = nestedElement.xmlType;
if (javaType.isArray()) {
fieldInfo.minOccurs = nestedElement.minOccurs;
fieldInfo.maxOccurs = nestedElement.maxOccurs;
}
typeInfo.fields.add(fieldInfo);
}
}
private Class loadClass(final QName typeQName, final JavaWsdlMapping mapping) throws OpenEJBException {
final String namespace = typeQName.getNamespaceURI();
// package name comes from the package mapping
final PackageMapping packageMapping = mapping.getPackageMappingMap().get(namespace);
if (packageMapping == null) {
throw new OpenEJBException("Namespace " + namespace + " was not mapped in jaxrpc mapping file");
}
final String packageName = packageMapping.getPackageType();
// class name is package + type local part
final String className = packageName + "." + typeQName.getLocalPart();
try {
final Class clazz = Class.forName(className, false, classLoader);
return clazz;
} catch (final ClassNotFoundException e) {
throw new OpenEJBException("Could not load java type " + className, e);
}
}
}