001package net.gdface.codegen.webclient; 002 003import java.lang.reflect.Type; 004import java.net.URI; 005import java.util.HashMap; 006import java.util.Iterator; 007import java.util.Map; 008import java.util.Map.Entry; 009 010import javax.xml.namespace.QName; 011 012import net.gdface.codegen.AbstractSchema; 013import net.gdface.codegen.CodeGenUtils; 014import net.gdface.codegen.Method; 015import net.gdface.codegen.wsdl.WebServiceInfo; 016import net.gdface.utils.Assert; 017 018import org.apache.axis2.description.AxisMessage; 019import org.apache.axis2.description.AxisOperation; 020import org.apache.axis2.description.AxisService; 021import org.apache.axis2.description.java2wsdl.TypeTable; 022import org.apache.axis2.wsdl.WSDLConstants; 023import org.apache.ws.commons.schema.XmlSchema; 024 025public class KSoapStub<T> extends AbstractSchema implements KSoapConstants { 026 private final WebServiceInfo webServiceInfo; 027 private final AxisService service; 028 protected final Class<?> serviceClass; 029 private final Map<QName, ComplexType> complexTypeBeans = new HashMap<QName, ComplexType>(); 030 private final Map<QName, ComplexType> complexTypeRequests = new HashMap<QName, ComplexType>(); 031 private final Map<QName, ComplexType> complexTypeResponses = new HashMap<QName, ComplexType>(); 032 private final Map<QName, ComplexType> complexTypeFaults = new HashMap<QName, ComplexType>(); 033 private final Map<QName, ComplexType> complexTypeOthers = new HashMap<QName, ComplexType>(); 034 private final Map<String, Map<QName, ComplexType>> schemaMap = new HashMap<String, Map<QName, ComplexType>>() { 035 private static final long serialVersionUID = 1L; 036 { 037 put(TypePurpose.BEAN.name(), complexTypeBeans); 038 put(TypePurpose.REQUEST.name(), complexTypeRequests); 039 put(TypePurpose.RESPONSE.name(), complexTypeResponses); 040 put(TypePurpose.FAULT.name(), complexTypeFaults); 041 put(TypePurpose.OTHER.name(), complexTypeOthers); 042 } 043 }; 044 045 public KSoapStub(Class<?> serviceClass, URI wsdlURI, String serviceName) { 046 Assert.notNull(wsdlURI,"wsdlURI"); 047 Assert.notNull(serviceClass, "serviceClass"); 048 this.serviceClass=serviceClass; 049 webServiceInfo = new WebServiceInfo(wsdlURI, serviceClass, serviceName); 050 service = this.webServiceInfo.getAxisService(); 051 } 052 053 @Override 054 public boolean compile() { 055 boolean compileOk = false; 056 try{ 057 addImportedClassFromMethods(webServiceInfo.getPorts().values()); 058 this.createSchemaForBeans(); 059 this.createSchemaForPorts(); 060 this.createSchemaForOthers(); 061 compileOk = true; 062 }finally{ 063 064 } 065 return compileOk; 066 } 067 068 private void createSchemaForBeans() { 069 Entry<QName, Class<?>> entry; 070 for (Iterator<Entry<QName, Class<?>>> it = this.webServiceInfo.getQNameToClassMap().entrySet().iterator(); it 071 .hasNext();) { 072 entry = it.next(); 073 complexTypeBeans.put(entry.getKey(), new ComplexType( 074 webServiceInfo.getXmlSchemaComplexType(entry.getKey()), webServiceInfo, null, null)); 075 } 076 } 077 078 private void createSchemaForOthers() { 079 QName name; 080 for (XmlSchema schema : this.webServiceInfo.getSchema()) { 081 for (@SuppressWarnings("unchecked") 082 Iterator<QName> it = schema.getSchemaTypes().getNames(); it.hasNext();) { 083 name = it.next(); 084 if (!this.hasComplexType(name)) { 085 complexTypeOthers.put(name, new ComplexType(webServiceInfo.getXmlSchemaComplexType(name), 086 webServiceInfo, null, null)); 087 } 088 } 089 } 090 } 091 092 private final void setComplexTypeUsedRelatedBy(Class<?>... classes) { 093 String className; 094 QName name; 095 TypeTable typeTable = this.service.getTypeTable(); 096 ComplexType complexType; 097 098 for (Class<?> clazz : classes) { 099 if (null != clazz) { 100 clazz = CodeGenUtils.getElementClass(clazz); 101 if (!typeTable.isSimpleType(className = clazz.getName())) { 102 if (null != (name = typeTable.getQNamefortheType(className))) { 103 if (null != (complexType = this.complexTypeBeans.get(name))) { 104 complexType.setUsed(true); 105 } else 106 throw new IllegalArgumentException(String.format("can't found complex type for QName [%s]", 107 name)); 108 } else 109 throw new IllegalArgumentException(String.format("can't found QName for [%s] in typeTable", 110 className)); 111 } 112 } 113 } 114 } 115 116 private final void setComplexTypeUsedRelatedBy(Type... types) { 117 for (Type type : types) { 118 if (null != type) { 119 if (type instanceof Class) { 120 setComplexTypeUsedRelatedBy((Class<?>) type); 121 } else { 122 setComplexTypeUsedRelatedBy(Method.getAllClassForGenericType(type.toString())); 123 } 124 } 125 } 126 } 127 128 private void createSchemaForPorts() { 129 Entry<String, Method> entry; 130 QName qn; 131 AxisOperation op; 132 ComplexType complexType; 133 AxisMessage msg; 134 boolean used=true; 135 for (Iterator<Entry<String, Method>> it = this.webServiceInfo.getPorts().entrySet().iterator(); it.hasNext();) { 136 entry = it.next(); 137 op = service.getOperation(new QName(service.getTargetNamespace(), entry.getKey())); 138 try { 139 msg = op.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE); 140 qn = msg.getElementQName(); 141 complexType = new ComplexType(msg.getSchemaElement(), webServiceInfo, entry.getValue() 142 .getGenericParameterTypes(), op); 143 complexType.setUsed(used); 144 setComplexTypeUsedRelatedBy(entry.getValue().getGenericParameterTypes()); 145 this.complexTypeRequests.put(qn, complexType); 146 } catch (UnsupportedOperationException e) { 147 148 } 149 try { 150 msg = op.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE); 151 qn = msg.getElementQName(); 152 complexType = new ComplexType(msg.getSchemaElement(),webServiceInfo, entry.getValue().getGenericReturnType(), op); 153 complexType.setUsed(used); 154 setComplexTypeUsedRelatedBy(entry.getValue().getGenericReturnType()); 155 this.complexTypeResponses.put(qn, complexType); 156 } catch (UnsupportedOperationException e) { 157 } 158 setComplexTypeUsedRelatedBy(entry.getValue().getGenericExceptionTypes()); 159 for (AxisMessage fault : op.getFaultMessages()) { 160 qn = fault.getElementQName(); 161 if (!complexTypeFaults.containsKey(qn)) { 162 complexType = new ComplexType(fault.getSchemaElement(),webServiceInfo, FAULT_MESSAGE, op); 163 complexType.setUsed(used); 164 this.complexTypeFaults.put(qn, complexType); 165 } 166 } 167 } 168 } 169 170 public ComplexType getComplexType(QName name) { 171 ComplexType complexType = null; 172 for (Map<QName, ComplexType> schema : schemaMap.values()) { 173 if (null != (complexType = schema.get(name))) 174 return complexType; 175 } 176 return complexType; 177 } 178 179 /** 180 * @return webServiceInfo 181 */ 182 public WebServiceInfo getWebServiceInfo() { 183 return webServiceInfo; 184 } 185 186 public boolean hasComplexType(QName name) { 187 return getComplexType(name) != null; 188 } 189 190 /** 191 * @return complexTypeBeans 192 */ 193 public Map<QName, ComplexType> getComplexTypeBeans() { 194 return complexTypeBeans; 195 } 196 197 /** 198 * @return complexTypeRequests 199 */ 200 public Map<QName, ComplexType> getComplexTypeRequests() { 201 return complexTypeRequests; 202 } 203 204 /** 205 * @return complexTypeResponses 206 */ 207 public Map<QName, ComplexType> getComplexTypeResponses() { 208 return complexTypeResponses; 209 } 210 211 /** 212 * @return complexTypeFaults 213 */ 214 public Map<QName, ComplexType> getComplexTypeFaults() { 215 return complexTypeFaults; 216 } 217 218 /** 219 * @return complexTypeOthers 220 */ 221 public Map<QName, ComplexType> getComplexTypeOthers() { 222 return complexTypeOthers; 223 } 224 225 /** 226 * @return schemaMap 227 */ 228 public Map<String, Map<QName, ComplexType>> getSchemaMap() { 229 return schemaMap; 230 } 231 232 /** 233 * @param name 234 * @return 235 * @see java.util.Map#get(java.lang.Object) 236 */ 237 public Map<QName, ComplexType> getSchema(String name) { 238 return schemaMap.get(name); 239 } 240 241 /** 242 * @return serviceClass 243 */ 244 public Class<?> getServiceClass() { 245 return serviceClass; 246 } 247 248 249}