📄 xmltypecreator.java
字号:
package org.codehaus.xfire.aegis.type;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import javax.xml.namespace.QName;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.codehaus.xfire.XFireRuntimeException;import org.codehaus.xfire.aegis.XMLClassMetaInfoManager;import org.codehaus.xfire.aegis.type.basic.BeanType;import org.codehaus.xfire.aegis.type.basic.XMLBeanTypeInfo;import org.codehaus.xfire.util.ClassLoaderUtils;import org.codehaus.xfire.util.NamespaceHelper;import org.jdom.Document;import org.jdom.Element;import org.jdom.JDOMException;import org.jdom.Namespace;import org.jdom.xpath.XPath;/** * Deduce mapping information from an xml file. * The xml file should be in the same packages as the class, with the name <code>className.aegis.xml</code>. * For example, given the following service interface: * <p/> * <pre> * public Collection getResultsForValues(String id, Collection values); //method 1 * public Collection getResultsForValues(int id, Collection values); //method 2 * public String getResultForValue(String value); //method 3 * </pre> * An example of the type xml is: * <pre> * <mappings> * <mapping> * <method name="getResultsForValues"> * <return-type componentType="com.acme.ResultBean" /> * <!-- no need to specify index 0, since it's a String --> * <parameter index="1" componentType="java.lang.String" /> * </method> * </mapping> * </mappings> * </pre> * <p/> * Note that for values which can be easily deduced (such as the String parameter, or the second service method) * no mapping need be specified in the xml descriptor, which is why no mapping is specified for method 3. * <p/> * However, if you have overloaded methods with different semantics, then you will need to specify enough * parameters to disambiguate the method and uniquely identify it. So in the example above, the mapping * specifies will apply to both method 1 and method 2, since the parameter at index 0 is not specified. * * @author Hani Suleiman * Date: Jun 14, 2005 * Time: 7:47:56 PM * @author <a href="mailto:mikagoeckel@codehaus.org">Mika G�ckel</a> * @author �yvind Matheson Wergeland * @author <a href="mailto:tsztelak@gmail.com">Tomasz Sztelak</a> */public class XMLTypeCreator extends AbstractTypeCreator{ private static final Log log = LogFactory.getLog(XMLTypeCreator.class); XMLClassMetaInfoManager manager = new XMLClassMetaInfoManager (); private static List stopClasses = new ArrayList(); static { stopClasses.add(Object.class); stopClasses.add(Exception.class); stopClasses.add(RuntimeException.class); stopClasses.add(Throwable.class); } protected Document getDocument(Class clazz) { if(clazz == null) return null; return manager.getDocument(clazz); } protected boolean isEnum(Class javaType) { Element mapping = findMapping(javaType); if (mapping != null) { return super.isEnum(javaType); } else { return nextCreator.isEnum(javaType); } } public Type createEnumType(TypeClassInfo info) { Element mapping = findMapping(info.getTypeClass()); if (mapping != null) { return super.createEnumType(info); } else { return nextCreator.createEnumType(info); } } public Type createCollectionType(TypeClassInfo info) { if (info.getGenericType() instanceof Class || info.getGenericType() instanceof TypeClassInfo) { return createCollectionTypeFromGeneric(info); } return nextCreator.createCollectionType(info); } public TypeClassInfo createClassInfo(PropertyDescriptor pd) { Element mapping = findMapping(pd.getReadMethod().getDeclaringClass()); if(mapping == null) { return nextCreator.createClassInfo(pd); } Element propertyEl = manager.getProperty(mapping,pd.getName() ); if(propertyEl == null) { return nextCreator.createClassInfo(pd); } TypeClassInfo info = new TypeClassInfo(); info.setTypeClass(pd.getReadMethod().getReturnType()); readMetadata(info, mapping, propertyEl); return info; } protected Element findMapping(Class clazz) { return manager.findMapping(clazz,getTypeMapping().getEncodingStyleURI()); } protected List findMappings(Class clazz) { ArrayList mappings = new ArrayList(); Element top = findMapping(clazz); if (top != null) mappings.add(top); Class parent = clazz; while(true) { // Read mappings for interfaces as well Class[] interfaces = parent.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { Class interfaze = interfaces[i]; List interfaceMappings = findMappings(interfaze); mappings.addAll(interfaceMappings); } Class sup = parent.getSuperclass(); if (sup == null || stopClasses.contains(sup)) break; Element mapping = findMapping(sup); if (mapping != null) { mappings.add(mapping); } parent = sup; } return mappings; } public Type createDefaultType(TypeClassInfo info) { Element mapping = findMapping(info.getTypeClass()); List mappings = findMappings(info.getTypeClass()); if (mapping != null || mappings.size() > 0 ) { String typeNameAtt = null; if (mapping != null) typeNameAtt = mapping.getAttributeValue("name"); String extensibleElements = null; if (mapping != null) extensibleElements = mapping.getAttributeValue("extensibleElements"); String extensibleAttributes = null; if (mapping != null) extensibleAttributes = mapping.getAttributeValue("extensibleAttributes"); String defaultNS = NamespaceHelper.makeNamespaceFromClassName(info.getTypeClass().getName(), "http"); QName name = null; if (typeNameAtt != null) { name = NamespaceHelper.createQName(mapping, typeNameAtt, defaultNS); defaultNS = name.getNamespaceURI(); } XMLBeanTypeInfo btinfo = new XMLBeanTypeInfo(info.getTypeClass(), mappings, defaultNS); btinfo.setTypeMapping(getTypeMapping()); btinfo.setDefaultMinOccurs(getConfiguration().getDefaultMinOccurs()); btinfo.setDefaultNillable( getConfiguration().isDefaultNillable() ); if ( extensibleElements != null ) btinfo.setExtensibleElements( Boolean.valueOf( extensibleElements ).booleanValue() ); else btinfo.setExtensibleElements(getConfiguration().isDefaultExtensibleElements()); if ( extensibleAttributes != null ) btinfo.setExtensibleAttributes( Boolean.valueOf( extensibleAttributes ).booleanValue() ); else btinfo.setExtensibleAttributes(getConfiguration().isDefaultExtensibleAttributes()); BeanType type = new BeanType(btinfo); if (name == null) name = createQName(info.getTypeClass()); type.setSchemaType(name); type.setTypeClass(info.getTypeClass()); type.setTypeMapping(getTypeMapping()); return type; } else { return nextCreator.createDefaultType(info); } } public TypeClassInfo createClassInfo(Method m, int index) { Element mapping = findMapping(m.getDeclaringClass()); if(mapping == null) return nextCreator.createClassInfo(m, index); //find the elements that apply to the specified method TypeClassInfo info = new TypeClassInfo(); if(index >= 0) { if(index >= m.getParameterTypes().length) { throw new XFireRuntimeException("Method " + m + " does not have a parameter at index " + index); } //we don't want nodes for which the specified index is not specified List nodes = getMatches(mapping, "./method[@name='" + m.getName() + "']/parameter[@index='" + index + "']/parent::*"); if(nodes.size() == 0) { //no mapping for this method return nextCreator.createClassInfo(m, index); } //pick the best matching node Element bestMatch = getBestMatch(mapping, m, nodes); if(bestMatch == null) { //no mapping for this method
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -