001package net.gdface.codegen.webclient; 002 003import java.beans.PropertyDescriptor; 004import java.lang.reflect.Type; 005import java.util.ArrayList; 006import java.util.HashMap; 007import java.util.Iterator; 008import java.util.Map; 009import java.util.Map.Entry; 010 011import javax.xml.namespace.QName; 012 013import org.apache.axis2.description.AxisOperation; 014import org.apache.axis2.description.java2wsdl.TypeTable; 015import org.apache.ws.commons.schema.XmlSchemaComplexType; 016import org.apache.ws.commons.schema.XmlSchemaElement; 017import org.apache.ws.commons.schema.XmlSchemaObject; 018import org.slf4j.Logger; 019import org.slf4j.LoggerFactory; 020 021import net.gdface.codegen.AbstractSchema; 022import net.gdface.codegen.wsdl.WebServiceInfo; 023import net.gdface.utils.Assert; 024import net.gdface.utils.BeanPropertyUtils; 025 026/** 027 * {@link} 028 * @author guyadong 029 * 030 */ 031public class ComplexType extends AbstractSchema implements KSoapConstants { 032 private static final Logger logger = LoggerFactory.getLogger(ComplexType.class); 033 034 private final ArrayList<XmlSchemaElement> fieldElements; 035 private final XmlSchemaObject schemaObj; 036 private final WebServiceInfo webServiceInfo; 037 private final Object objectForPort; 038 private final TypeTable typeTable; 039 private KSoapConstants.TypePurpose purpose; 040 private boolean used=false; 041 private final AxisOperation operation; 042 protected ComplexType(XmlSchemaObject schemaObj, WebServiceInfo webServiceInfo, Object objectForPort, AxisOperation operation) { 043 Assert.notNull(schemaObj, "schemaObj"); 044 Assert.notNull(webServiceInfo, "webServiceInfo"); 045 this.objectForPort = objectForPort; 046 this.schemaObj = schemaObj; 047 this.webServiceInfo = webServiceInfo; 048 this.typeTable = webServiceInfo.getAxisService().getTypeTable(); 049 this.operation=operation; 050 if(schemaObj instanceof XmlSchemaComplexType){ 051 this.fieldElements = webServiceInfo.getFieldElements(((XmlSchemaComplexType)this.schemaObj).getQName()); 052 }else if(schemaObj instanceof XmlSchemaElement){ 053 this.fieldElements = webServiceInfo.getFieldElements(((XmlSchemaElement)schemaObj).getQName()); 054 }else 055 throw new IllegalArgumentException(String.format("invalid type,schemaObj must be %s OR %s", 056 XmlSchemaElement.class.getSimpleName(),XmlSchemaComplexType.class.getSimpleName())); 057 init(); 058 } 059 060 private void addImportedBeanFieldClass(Class<?> beanClass) { 061 this.addImportedClass(getReadablePropertiesReturnClass(beanClass).values().toArray(new Type[0])); 062 } 063 064 private void addImportedFieldElementsClass() { 065 XmlSchemaElement element; 066 String className; 067 QName typeName; 068 for (Iterator<XmlSchemaElement> it = getFieldElements().iterator(); it.hasNext();) { 069 element = it.next(); 070 typeName = element.getSchemaTypeName(); 071 try { 072 className = typeTable.getClassNameForQName(typeName); 073 if(className!=null){ 074 this.addImportedClass(className); 075 } 076 } catch (ClassNotFoundException e) { 077 throw new RuntimeException(e); 078 } 079 } 080 } 081 private void init(){ 082 try { 083 //根据objectForPort的类型判断对象类型 084 if(schemaObj instanceof XmlSchemaComplexType){ 085 String className = typeTable.getClassNameForQName(((XmlSchemaComplexType)this.schemaObj).getQName()); 086 if (className != null) {// bean对象 087 this.baseClass = Class.forName(className); 088 this.addImportedClass(baseClass); 089 this.addImportedBeanFieldClass(baseClass); 090 this.purpose = TypePurpose.BEAN; 091 }else{ 092 this.addImportedFieldElementsClass(); 093 this.purpose = TypePurpose.OTHER; 094 } 095 } else if (this.objectForPort.getClass().isArray()) {// request:参数类型数组(message) 096 this.addImportedClass((Type[]) objectForPort); 097 this.purpose = TypePurpose.REQUEST; 098 } else if (this.objectForPort instanceof Type) {// response:返回类型(message) 099 this.addImportedClass((Type) this.objectForPort); 100 this.purpose = TypePurpose.RESPONSE; 101 } else if (this.objectForPort==FAULT_MESSAGE) {// fault:异常返回消息(message) 102 this.purpose = TypePurpose.FAULT; 103 } else { 104 // 其他消息类型 105 this.addImportedFieldElementsClass(); 106 this.purpose = TypePurpose.OTHER; 107 } 108 } catch (ClassNotFoundException e) { 109 logger.error(e.toString()); 110 } finally { 111 } 112 } 113 @Override 114 public boolean compile() { 115 return true; 116 } 117 118 /** 119 * @return fieldElements 120 */ 121 public ArrayList<XmlSchemaElement> getFieldElements() { 122 return fieldElements; 123 } 124 125 public Map<String, PropertyDescriptor> getReadableProperties() { 126 return BeanPropertyUtils.getProperties(this.baseClass, 2); 127 } 128 129 public Map<String, PropertyDescriptor> getRwProperties() { 130 return BeanPropertyUtils.getProperties(this.baseClass, 3); 131 } 132 133 public Map<String, PropertyDescriptor> getAllProperties() { 134 return BeanPropertyUtils.getProperties(this.baseClass, 0); 135 } 136 137 public Map<String, Type> getReadablePropertiesReturnClass() { 138 return getReadablePropertiesReturnClass(this.baseClass); 139 } 140 141 public Map<String, Type> getReadablePropertiesReturnClass(Class<?> beanClass) { 142 try { 143 Map<String, PropertyDescriptor> properties = BeanPropertyUtils.getProperties(beanClass, 2); 144 Map<String, Type> classMap = new HashMap<String, Type>(properties.size()); 145 Entry<String, PropertyDescriptor> entry; 146 for (Iterator<Entry<String, PropertyDescriptor>> it = properties.entrySet().iterator(); it.hasNext();) { 147 entry = it.next(); 148 classMap.put(entry.getKey(), entry.getValue().getReadMethod().getGenericReturnType()); 149 } 150 return classMap; 151 } catch (Exception e) { 152 throw new RuntimeException(e); 153 } 154 } 155 156 public boolean isBean() { 157 return this.purpose == KSoapConstants.TypePurpose.BEAN; 158 } 159 160 public boolean isRequest() { 161 return this.purpose == KSoapConstants.TypePurpose.REQUEST; 162 } 163 164 public boolean isResponse() { 165 return this.purpose == KSoapConstants.TypePurpose.RESPONSE; 166 } 167 public boolean isFault() { 168 return this.purpose == KSoapConstants.TypePurpose.FAULT; 169 } 170 public boolean isOther() { 171 return this.purpose == KSoapConstants.TypePurpose.OTHER; 172 } 173 174 /** 175 * @return webServiceInfo 176 */ 177 public WebServiceInfo getWebServiceInfo() { 178 return webServiceInfo; 179 } 180 181 /** 182 * @return used 183 */ 184 public boolean isUsed() { 185 return used; 186 } 187 188 /** 189 * @param used 要设置的 used 190 */ 191 public void setUsed(boolean used) { 192 this.used = used; 193 } 194 195 /** 196 * @return schemaObj 197 */ 198 public XmlSchemaObject getSchemaObj() { 199 return schemaObj; 200 } 201 /** 202 * @return objectForPort 203 */ 204 public Object getObjectForPort() { 205 return objectForPort; 206 } 207 208 /** 209 * @return operation 210 */ 211 public AxisOperation getOperation() { 212 return operation; 213 } 214 215 216 217}