0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one
0003: * or more contributor license agreements. See the NOTICE file
0004: * distributed with this work for additional information
0005: * regarding copyright ownership. The ASF licenses this file
0006: * to you under the Apache License, Version 2.0 (the
0007: * "License"); you may not use this file except in compliance
0008: * with the License. You may obtain a copy of the License at
0009: *
0010: * http://www.apache.org/licenses/LICENSE-2.0
0011: *
0012: * Unless required by applicable law or agreed to in writing,
0013: * software distributed under the License is distributed on an
0014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015: * KIND, either express or implied. See the License for the
0016: * specific language governing permissions and limitations
0017: * under the License.
0018: */
0019: package org.apache.axis2.description.java2wsdl;
0020:
0021: import org.apache.axis2.AxisFault;
0022: import org.apache.axis2.deployment.util.Utils;
0023: import org.apache.axis2.description.AxisMessage;
0024: import org.apache.axis2.description.AxisOperation;
0025: import org.apache.axis2.description.AxisService;
0026: import org.apache.axis2.description.WSDL2Constants;
0027: import org.apache.axis2.description.java2wsdl.bytecode.MethodTable;
0028: import org.apache.axis2.wsdl.WSDLConstants;
0029: import org.apache.commons.logging.Log;
0030: import org.apache.commons.logging.LogFactory;
0031: import org.apache.ws.commons.schema.*;
0032: import org.apache.ws.commons.schema.utils.NamespaceMap;
0033: import org.apache.ws.commons.schema.utils.NamespacePrefixList;
0034: import org.codehaus.jam.*;
0035:
0036: import javax.xml.namespace.QName;
0037: import javax.activation.DataHandler;
0038: import java.util.*;
0039:
0040: public class DefaultSchemaGenerator implements Java2WSDLConstants,
0041: SchemaGenerator {
0042:
0043: private static final Log log = LogFactory
0044: .getLog(DefaultSchemaGenerator.class);
0045:
0046: public static final String NAME_SPACE_PREFIX = "ax2";// axis2 name space
0047:
0048: private static int prefixCount = 1;
0049:
0050: protected Map targetNamespacePrefixMap = new Hashtable();
0051:
0052: protected Map schemaMap = new Hashtable();
0053:
0054: protected XmlSchemaCollection xmlSchemaCollection = new XmlSchemaCollection();
0055:
0056: protected ClassLoader classLoader;
0057:
0058: protected String className;
0059:
0060: protected TypeTable typeTable = new TypeTable();
0061:
0062: // to keep loadded method using JAM
0063: protected JMethod methods[];
0064:
0065: //to store byte code method using Axis 1.x codes
0066: protected MethodTable methodTable;
0067:
0068: protected String schemaTargetNameSpace;
0069:
0070: protected String schema_namespace_prefix;
0071:
0072: protected String attrFormDefault = null;
0073:
0074: protected String elementFormDefault = null;
0075:
0076: protected ArrayList excludeMethods = new ArrayList();
0077:
0078: protected ArrayList extraClasses = null;
0079:
0080: protected boolean useWSDLTypesNamespace = false;
0081:
0082: protected Map pkg2nsmap = null;
0083:
0084: protected NamespaceGenerator nsGen = null;
0085:
0086: protected String targetNamespace = null;
0087: //to keep the list of operation which uses MR other than RPC MR
0088: protected ArrayList nonRpcMethods = new ArrayList();
0089:
0090: protected Class serviceClass = null;
0091: protected AxisService service;
0092:
0093: //To check whether we need to generate Schema element for Exception
0094: protected boolean generateBaseException;
0095:
0096: public NamespaceGenerator getNsGen() throws Exception {
0097: if (nsGen == null) {
0098: nsGen = new DefaultNamespaceGenerator();
0099: }
0100: return nsGen;
0101: }
0102:
0103: public void setNsGen(NamespaceGenerator nsGen) {
0104: this .nsGen = nsGen;
0105: }
0106:
0107: public DefaultSchemaGenerator(ClassLoader loader, String className,
0108: String schematargetNamespace,
0109: String schematargetNamespacePrefix, AxisService service)
0110: throws Exception {
0111: this .classLoader = loader;
0112: this .className = className;
0113: this .service = service;
0114:
0115: serviceClass = Class.forName(className, true, loader);
0116: methodTable = new MethodTable(serviceClass);
0117:
0118: this .targetNamespace = Java2WSDLUtils
0119: .targetNamespaceFromClassName(className, loader,
0120: getNsGen()).toString();
0121:
0122: if (schematargetNamespace != null
0123: && schematargetNamespace.trim().length() != 0) {
0124: this .schemaTargetNameSpace = schematargetNamespace;
0125: } else {
0126: this .schemaTargetNameSpace = Java2WSDLUtils
0127: .schemaNamespaceFromClassName(className, loader,
0128: getNsGen()).toString();
0129: }
0130:
0131: if (schematargetNamespacePrefix != null
0132: && schematargetNamespacePrefix.trim().length() != 0) {
0133: this .schema_namespace_prefix = schematargetNamespacePrefix;
0134: } else {
0135: this .schema_namespace_prefix = SCHEMA_NAMESPACE_PRFIX;
0136: }
0137: }
0138:
0139: /**
0140: * Generates schema for all the parameters in method. First generates schema for all different
0141: * parameter type and later refers to them.
0142: *
0143: * @return Returns XmlSchema.
0144: * @throws Exception
0145: */
0146: public Collection generateSchema() throws Exception {
0147:
0148: JamServiceFactory factory = JamServiceFactory.getInstance();
0149: JamServiceParams jam_service_parms = factory
0150: .createServiceParams();
0151: //setting the classLoder
0152: //it can posible to add the classLoader as well
0153: jam_service_parms.addClassLoader(classLoader);
0154: jam_service_parms.includeClass(className);
0155:
0156: for (int count = 0; count < getExtraClasses().size(); ++count) {
0157: jam_service_parms.includeClass((String) getExtraClasses()
0158: .get(count));
0159: }
0160: JamService service = factory.createService(jam_service_parms);
0161: QName extraSchemaTypeName;
0162: JamClassIterator jClassIter = service.getClasses();
0163: //all most all the time the ittr will have only one class in it
0164: while (jClassIter.hasNext()) {
0165: JClass jclass = (JClass) jClassIter.next();
0166: if (getQualifiedName(jclass).equals(className)) {
0167: /**
0168: * Schema genertaion done in two stage 1. Load all the methods and
0169: * create type for methods parameters (if the parameters are Bean
0170: * then it will create Complex types for those , and if the
0171: * parameters are simple type which decribe in SimpleTypeTable
0172: * nothing will happen) 2. In the next stage for all the methods
0173: * messages and port types will be creteated
0174: */
0175: JAnnotation annotation = jclass
0176: .getAnnotation(AnnotationConstants.WEB_SERVICE);
0177: if (annotation != null) {
0178: String tns = annotation.getValue(
0179: AnnotationConstants.TARGETNAMESPACE)
0180: .asString();
0181: if (tns != null && !"".equals(tns)) {
0182: targetNamespace = tns;
0183: schemaTargetNameSpace = tns;
0184: }
0185: }
0186: methods = processMethods(jclass.getDeclaredMethods());
0187:
0188: } else {
0189: //generate the schema type for extra classes
0190: extraSchemaTypeName = typeTable
0191: .getSimpleSchemaTypeName(getQualifiedName(jclass));
0192: if (extraSchemaTypeName == null) {
0193: generateSchema(jclass);
0194: }
0195: }
0196: }
0197: return schemaMap.values();
0198: }
0199:
0200: protected JMethod[] processMethods(JMethod[] declaredMethods)
0201: throws Exception {
0202: ArrayList list = new ArrayList();
0203: //short the elements in the array
0204: Arrays.sort(declaredMethods);
0205:
0206: // since we do not support overload
0207: HashMap uniqueMethods = new HashMap();
0208: XmlSchemaComplexType methodSchemaType;
0209: XmlSchemaSequence sequence = null;
0210:
0211: for (int i = 0; i < declaredMethods.length; i++) {
0212: JMethod jMethod = declaredMethods[i];
0213: JAnnotation methodAnnon = jMethod
0214: .getAnnotation(AnnotationConstants.WEB_METHOD);
0215: if (methodAnnon != null) {
0216: if (methodAnnon.getValue(AnnotationConstants.EXCLUDE)
0217: .asBoolean()) {
0218: continue;
0219: }
0220: }
0221: String methodName = getSimpleName(jMethod);
0222: // no need to think abt this method , since that is system
0223: // config method
0224: if (excludeMethods.contains(methodName)) {
0225: continue;
0226: }
0227:
0228: if (uniqueMethods.get(methodName) != null) {
0229: log
0230: .warn("We don't support method overloading. Ignoring ["
0231: + jMethod.getQualifiedName() + "]");
0232: continue;
0233: }
0234:
0235: if (!jMethod.isPublic()) {
0236: // no need to generate Schema for non public methods
0237: continue;
0238: }
0239: boolean addToService = false;
0240: AxisOperation axisOperation = service
0241: .getOperation(new QName(methodName));
0242: if (axisOperation == null) {
0243: axisOperation = Utils
0244: .getAxisOperationForJmethod(jMethod);
0245: if (WSDL2Constants.MEP_URI_ROBUST_IN_ONLY
0246: .equals(axisOperation
0247: .getMessageExchangePattern())) {
0248: AxisMessage outMessage = axisOperation
0249: .getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
0250: if (outMessage != null) {
0251: outMessage.setName(methodName + RESPONSE);
0252: }
0253: }
0254: addToService = true;
0255: }
0256: // Maintain a list of methods we actually work with
0257: list.add(jMethod);
0258:
0259: processException(jMethod, axisOperation);
0260: uniqueMethods.put(methodName, jMethod);
0261: JParameter[] paras = jMethod.getParameters();
0262: String parameterNames[] = null;
0263: AxisMessage inMessage = axisOperation
0264: .getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
0265: if (inMessage != null) {
0266: inMessage.setName(methodName
0267: + Java2WSDLConstants.MESSAGE_SUFFIX);
0268: }
0269: if (paras.length > 0) {
0270: parameterNames = methodTable
0271: .getParameterNames(methodName);
0272: sequence = new XmlSchemaSequence();
0273:
0274: methodSchemaType = createSchemaTypeForMethodPart(methodName);
0275: methodSchemaType.setParticle(sequence);
0276: inMessage.setElementQName(typeTable
0277: .getQNamefortheType(methodName));
0278: service.addMessageElementQNameToOperationMapping(
0279: methodSchemaType.getQName(), axisOperation);
0280: }
0281:
0282: for (int j = 0; j < paras.length; j++) {
0283: JParameter methodParameter = paras[j];
0284: String parameterName = null;
0285: JAnnotation paramterAnnon = methodParameter
0286: .getAnnotation(AnnotationConstants.WEB_PARAM);
0287: if (paramterAnnon != null) {
0288: parameterName = paramterAnnon.getValue(
0289: AnnotationConstants.NAME).asString();
0290: }
0291: if (parameterName == null || "".equals(parameterName)) {
0292: parameterName = (parameterNames != null && parameterNames[j] != null) ? parameterNames[j]
0293: : getSimpleName(methodParameter);
0294: }
0295: JClass paraType = methodParameter.getType();
0296: if (nonRpcMethods.contains(getSimpleName(jMethod))) {
0297: generateSchemaForType(sequence, null,
0298: getSimpleName(jMethod));
0299: break;
0300: } else {
0301: generateSchemaForType(sequence, paraType,
0302: parameterName);
0303: }
0304: }
0305: // for its return type
0306: JClass returnType = jMethod.getReturnType();
0307:
0308: if (!returnType.isVoidType()) {
0309: String partQname = methodName + RESPONSE;
0310: methodSchemaType = createSchemaTypeForMethodPart(partQname);
0311: sequence = new XmlSchemaSequence();
0312: methodSchemaType.setParticle(sequence);
0313: JAnnotation returnAnnon = jMethod
0314: .getAnnotation(AnnotationConstants.WEB_RESULT);
0315: String returnName = "return";
0316: if (returnAnnon != null) {
0317: returnName = returnAnnon.getValue(
0318: AnnotationConstants.NAME).asString();
0319: if (returnName != null && !"".equals(returnName)) {
0320: returnName = "return";
0321: }
0322: }
0323: if (nonRpcMethods.contains(getSimpleName(jMethod))) {
0324: generateSchemaForType(sequence, null, returnName);
0325: } else {
0326: generateSchemaForType(sequence, returnType,
0327: returnName);
0328: }
0329: AxisMessage outMessage = axisOperation
0330: .getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
0331: outMessage.setElementQName(typeTable
0332: .getQNamefortheType(partQname));
0333: outMessage.setName(partQname);
0334: service.addMessageElementQNameToOperationMapping(
0335: methodSchemaType.getQName(), axisOperation);
0336: }
0337: if (addToService) {
0338: service.addOperation(axisOperation);
0339: }
0340: }
0341: return (JMethod[]) list.toArray(new JMethod[list.size()]);
0342: }
0343:
0344: /**
0345: * This method will generate Schema element for all the excetion types in a given JMethod
0346: * - No matter what it will generate Schema element for java.lang.Exception so that for other
0347: * exception which extend java.lang.Excetion can use as the base class type
0348: */
0349: protected void processException(JMethod jMethod,
0350: AxisOperation axisOperation) throws Exception {
0351: XmlSchemaComplexType methodSchemaType;
0352: XmlSchemaSequence sequence;
0353: if (jMethod.getExceptionTypes().length > 0) {
0354: if (!generateBaseException) {
0355: sequence = new XmlSchemaSequence();
0356: XmlSchema xmlSchema = getXmlSchema(schemaTargetNameSpace);
0357: QName elementName = new QName(schemaTargetNameSpace,
0358: "Exception", schema_namespace_prefix);
0359: XmlSchemaComplexType complexType = new XmlSchemaComplexType(
0360: xmlSchema);
0361: complexType.setName("Exception");
0362: xmlSchema.getItems().add(complexType);
0363: xmlSchema.getElements().add(elementName, complexType);
0364: typeTable.addComplexSchema(Exception.class.getName(),
0365: elementName);
0366: QName schemaTypeName = TypeTable.ANY_TYPE;
0367: addContentToMethodSchemaType(sequence, schemaTypeName,
0368: "Exception", false);
0369: complexType.setParticle(sequence);
0370: generateBaseException = true;
0371: }
0372: JClass[] extypes = jMethod.getExceptionTypes();
0373: for (int j = 0; j < extypes.length; j++) {
0374: JClass extype = extypes[j];
0375: if (AxisFault.class.getName().equals(
0376: extype.getQualifiedName())) {
0377: continue;
0378: }
0379: String partQname = extype.getSimpleName();
0380: methodSchemaType = createSchemaTypeForFault(partQname);
0381: QName elementName = new QName(
0382: this .schemaTargetNameSpace, partQname,
0383: this .schema_namespace_prefix);
0384: sequence = new XmlSchemaSequence();
0385: if (Exception.class.getName().equals(
0386: extype.getQualifiedName())) {
0387: addContentToMethodSchemaType(sequence, typeTable
0388: .getComplexSchemaType(Exception.class
0389: .getName()), partQname, false);
0390: methodSchemaType.setParticle(sequence);
0391: typeTable.addComplexSchema(Exception.class
0392: .getPackage().getName(), methodSchemaType
0393: .getQName());
0394: } else {
0395: generateSchemaForType(sequence, extype, extype
0396: .getSimpleName());
0397: methodSchemaType.setParticle(sequence);
0398: }
0399:
0400: typeTable.addComplexSchema(partQname, elementName);
0401:
0402: if (AxisFault.class.getName().equals(
0403: extype.getQualifiedName())) {
0404: continue;
0405: }
0406: AxisMessage faultMessage = new AxisMessage();
0407: faultMessage.setName(extype.getSimpleName());
0408: faultMessage.setElementQName(typeTable
0409: .getQNamefortheType(partQname));
0410: axisOperation.setFaultMessages(faultMessage);
0411: }
0412: }
0413: }
0414:
0415: /**
0416: * JAM convert first name of an attribute into UpperCase as an example if there is a instance
0417: * variable called foo in a bean , then Jam give that as Foo so this method is to correct that
0418: * error
0419: *
0420: * @param wrongName
0421: * @return the right name, using english as the locale for case conversion
0422: */
0423: public static String getCorrectName(String wrongName) {
0424: if (wrongName.length() > 1) {
0425: return wrongName.substring(0, 1)
0426: .toLowerCase(Locale.ENGLISH)
0427: + wrongName.substring(1, wrongName.length());
0428: } else {
0429: return wrongName.substring(0, 1)
0430: .toLowerCase(Locale.ENGLISH);
0431: }
0432: }
0433:
0434: /**
0435: * Generate schema construct for given type
0436: *
0437: * @param javaType
0438: */
0439: private QName generateSchema(JClass javaType) throws Exception {
0440: String name = getQualifiedName(javaType);
0441: QName schemaTypeName = typeTable.getComplexSchemaType(name);
0442: if (schemaTypeName == null) {
0443: String simpleName = getSimpleName(javaType);
0444:
0445: String packageName = getQualifiedName(javaType
0446: .getContainingPackage());
0447: String targetNameSpace = resolveSchemaNamespace(packageName);
0448:
0449: XmlSchema xmlSchema = getXmlSchema(targetNameSpace);
0450: String targetNamespacePrefix = (String) targetNamespacePrefixMap
0451: .get(targetNameSpace);
0452: if (targetNamespacePrefix == null) {
0453: targetNamespacePrefix = generatePrefix();
0454: targetNamespacePrefixMap.put(targetNameSpace,
0455: targetNamespacePrefix);
0456: }
0457:
0458: XmlSchemaComplexType complexType = new XmlSchemaComplexType(
0459: xmlSchema);
0460: XmlSchemaSequence sequence = new XmlSchemaSequence();
0461: XmlSchemaComplexContentExtension complexExtension = new XmlSchemaComplexContentExtension();
0462:
0463: XmlSchemaElement eltOuter = new XmlSchemaElement();
0464: schemaTypeName = new QName(targetNameSpace, simpleName,
0465: targetNamespacePrefix);
0466: eltOuter.setName(simpleName);
0467: eltOuter.setQName(schemaTypeName);
0468:
0469: JClass sup = javaType.getSuperclass();
0470:
0471: if ((sup != null)
0472: && !("java.lang.Object".compareTo(sup
0473: .getQualifiedName()) == 0)
0474: && !("org.apache.axis2".compareTo(sup
0475: .getContainingPackage().getQualifiedName()) == 0)) {
0476: String super ClassName = sup.getQualifiedName();
0477: String super classname = getSimpleName(sup);
0478: String tgtNamespace;
0479: String tgtNamespacepfx;
0480: QName qName = typeTable
0481: .getSimpleSchemaTypeName(super ClassName);
0482: if (qName != null) {
0483: tgtNamespace = qName.getNamespaceURI();
0484: tgtNamespacepfx = qName.getPrefix();
0485: } else {
0486: tgtNamespace = resolveSchemaNamespace(sup
0487: .getContainingPackage().getQualifiedName());
0488: tgtNamespacepfx = (String) targetNamespacePrefixMap
0489: .get(tgtNamespace);
0490: QName super ClassQname = generateSchema(sup);
0491: if (super ClassQname != null) {
0492: tgtNamespacepfx = super ClassQname.getPrefix();
0493: tgtNamespace = super ClassQname
0494: .getNamespaceURI();
0495: }
0496: }
0497:
0498: if (tgtNamespacepfx == null) {
0499: tgtNamespacepfx = generatePrefix();
0500: targetNamespacePrefixMap.put(tgtNamespace,
0501: tgtNamespacepfx);
0502: }
0503:
0504: QName basetype = new QName(tgtNamespace,
0505: super classname, tgtNamespacepfx);
0506:
0507: complexExtension.setBaseTypeName(basetype);
0508: complexExtension.setParticle(sequence);
0509:
0510: XmlSchemaComplexContent contentModel = new XmlSchemaComplexContent();
0511:
0512: contentModel.setContent(complexExtension);
0513:
0514: complexType.setContentModel(contentModel);
0515:
0516: } else {
0517: complexType.setParticle(sequence);
0518: }
0519:
0520: complexType.setName(simpleName);
0521:
0522: // xmlSchema.getItems().add(eltOuter);
0523: xmlSchema.getElements().add(schemaTypeName, eltOuter);
0524: eltOuter.setSchemaTypeName(complexType.getQName());
0525:
0526: xmlSchema.getItems().add(complexType);
0527: xmlSchema.getSchemaTypes().add(schemaTypeName, complexType);
0528:
0529: // adding this type to the table
0530: typeTable.addComplexSchema(name, eltOuter.getQName());
0531: // adding this type's package to the table, to support inheritance.
0532: typeTable.addComplexSchema(javaType.getContainingPackage()
0533: .getQualifiedName(), eltOuter.getQName());
0534:
0535: Set propertiesSet = new HashSet();
0536: Set propertiesNames = new HashSet();
0537:
0538: JProperty[] tempProperties = javaType
0539: .getDeclaredProperties();
0540: for (int i = 0; i < tempProperties.length; i++) {
0541: propertiesSet.add(tempProperties[i]);
0542: }
0543:
0544: JProperty[] properties = (JProperty[]) propertiesSet
0545: .toArray(new JProperty[0]);
0546: Arrays.sort(properties);
0547: for (int i = 0; i < properties.length; i++) {
0548: JProperty property = properties[i];
0549: boolean isArryType = property.getType().isArrayType();
0550:
0551: String propname = getCorrectName(property
0552: .getSimpleName());
0553:
0554: propertiesNames.add(propname);
0555:
0556: this .generateSchemaforFieldsandProperties(xmlSchema,
0557: sequence, property.getType(), propname,
0558: isArryType);
0559:
0560: }
0561:
0562: JField[] tempFields = javaType.getDeclaredFields();
0563: HashMap FieldMap = new HashMap();
0564:
0565: for (int i = 0; i < tempFields.length; i++) {
0566: // create a element for the field only if it is public
0567: // and there is no property with the same name
0568:
0569: if (tempFields[i].isPublic()) {
0570:
0571: // skip field with same name as a property
0572: if (!propertiesNames.contains(tempFields[i]
0573: .getSimpleName())) {
0574:
0575: FieldMap.put(tempFields[i].getSimpleName(),
0576: tempFields[i]);
0577: }
0578: }
0579:
0580: }
0581:
0582: // remove fields from super classes patch for defect Annogen-21
0583: // getDeclaredFields is incorrectly returning fields of super classes as well
0584: // getDeclaredProperties used earlier works correctly
0585: JClass supr = javaType.getSuperclass();
0586: while (supr != null
0587: && supr.getQualifiedName().compareTo(
0588: "java.lang.Object") != 0) {
0589: JField[] suprFields = supr.getFields();
0590: for (int i = 0; i < suprFields.length; i++) {
0591: FieldMap.remove(suprFields[i].getSimpleName());
0592: }
0593: supr = supr.getSuperclass();
0594: }
0595: // end patch for Annogen -21
0596:
0597: JField[] froperties = (JField[]) FieldMap.values().toArray(
0598: new JField[0]);
0599: Arrays.sort(froperties);
0600:
0601: for (int i = 0; i < froperties.length; i++) {
0602: JField field = froperties[i];
0603: boolean isArryType = field.getType().isArrayType();
0604:
0605: this .generateSchemaforFieldsandProperties(xmlSchema,
0606: sequence, field.getType(), field
0607: .getSimpleName(), isArryType);
0608: }
0609:
0610: }
0611: return schemaTypeName;
0612: }
0613:
0614: // moved code common to Fields & properties out of above method
0615: protected void generateSchemaforFieldsandProperties(
0616: XmlSchema xmlSchema, XmlSchemaSequence sequence,
0617: JClass type, String name, boolean isArryType)
0618: throws Exception {
0619:
0620: String propertyName;
0621:
0622: if (isArryType) {
0623: propertyName = getQualifiedName(type
0624: .getArrayComponentType());
0625: } else
0626: propertyName = getQualifiedName(type);
0627:
0628: if (isArryType && "byte".equals(propertyName)) {
0629: propertyName = "base64Binary";
0630: }
0631: if (isDataHandler(type)) {
0632: propertyName = "base64Binary";
0633: }
0634:
0635: if (typeTable.isSimpleType(propertyName)) {
0636: XmlSchemaElement elt1 = new XmlSchemaElement();
0637: elt1.setName(name);
0638: elt1.setSchemaTypeName(typeTable
0639: .getSimpleSchemaTypeName(propertyName));
0640: sequence.getItems().add(elt1);
0641:
0642: if (isArryType && (!propertyName.equals("base64Binary"))) {
0643: elt1.setMaxOccurs(Long.MAX_VALUE);
0644: }
0645: elt1.setMinOccurs(0);
0646: if (!type.isPrimitiveType()) {
0647: elt1.setNillable(true);
0648: }
0649: } else {
0650: if (isArryType) {
0651: generateSchema(type.getArrayComponentType());
0652: } else {
0653: generateSchema(type);
0654: }
0655: XmlSchemaElement elt1 = new XmlSchemaElement();
0656: elt1.setName(name);
0657: elt1.setSchemaTypeName(typeTable
0658: .getComplexSchemaType(propertyName));
0659: sequence.getItems().add(elt1);
0660: if (isArryType) {
0661: elt1.setMaxOccurs(Long.MAX_VALUE);
0662: }
0663: elt1.setMinOccurs(0);
0664: elt1.setNillable(true);
0665:
0666: if (!((NamespaceMap) xmlSchema.getNamespaceContext())
0667: .values().contains(
0668: typeTable
0669: .getComplexSchemaType(propertyName)
0670: .getNamespaceURI())) {
0671: XmlSchemaImport importElement = new XmlSchemaImport();
0672: importElement.setNamespace(typeTable
0673: .getComplexSchemaType(propertyName)
0674: .getNamespaceURI());
0675: xmlSchema.getItems().add(importElement);
0676: ((NamespaceMap) xmlSchema.getNamespaceContext()).put(
0677: generatePrefix(), typeTable
0678: .getComplexSchemaType(propertyName)
0679: .getNamespaceURI());
0680: }
0681: }
0682:
0683: }
0684:
0685: private QName generateSchemaForType(XmlSchemaSequence sequence,
0686: JClass type, String partName) throws Exception {
0687:
0688: boolean isArrayType = false;
0689: if (type != null) {
0690: isArrayType = type.isArrayType();
0691: }
0692: if (isArrayType) {
0693: type = type.getArrayComponentType();
0694: }
0695: if (AxisFault.class.getName().equals(type)) {
0696: return null;
0697: }
0698: String classTypeName;
0699: if (type == null) {
0700: classTypeName = "java.lang.Object";
0701: } else {
0702: classTypeName = getQualifiedName(type);
0703: }
0704: if (isArrayType && "byte".equals(classTypeName)) {
0705: classTypeName = "base64Binary";
0706: isArrayType = false;
0707: }
0708:
0709: if (isDataHandler(type)) {
0710: classTypeName = "base64Binary";
0711: }
0712: QName schemaTypeName = typeTable
0713: .getSimpleSchemaTypeName(classTypeName);
0714: if (schemaTypeName == null) {
0715: schemaTypeName = generateSchema(type);
0716: addContentToMethodSchemaType(sequence, schemaTypeName,
0717: partName, isArrayType);
0718: String schemaNamespace;
0719: schemaNamespace = resolveSchemaNamespace(getQualifiedName(type
0720: .getContainingPackage()));
0721: addImport(getXmlSchema(schemaNamespace), schemaTypeName);
0722:
0723: } else {
0724: addContentToMethodSchemaType(sequence, schemaTypeName,
0725: partName, isArrayType);
0726: }
0727:
0728: return schemaTypeName;
0729: }
0730:
0731: protected boolean isDataHandler(JClass clazz) {
0732: if (clazz == null) {
0733: return false;
0734: }
0735: String classType = clazz.getQualifiedName();
0736: if ("java.lang.Object".equals(classType)) {
0737: return false;
0738: }
0739: if ("javax.activation.DataHandler".equals(classType)) {
0740: return true;
0741: } else {
0742: JClass supuerClass = clazz.getSuperclass();
0743: if (supuerClass != null) {
0744: return isDataHandler(supuerClass);
0745: } else {
0746: return false;
0747: }
0748: }
0749: }
0750:
0751: protected void addContentToMethodSchemaType(
0752: XmlSchemaSequence sequence, QName schemaTypeName,
0753: String paraName, boolean isArray) {
0754: XmlSchemaElement elt1 = new XmlSchemaElement();
0755: elt1.setName(paraName);
0756: elt1.setSchemaTypeName(schemaTypeName);
0757: if (sequence != null) {
0758: sequence.getItems().add(elt1);
0759: }
0760:
0761: if (isArray) {
0762: elt1.setMaxOccurs(Long.MAX_VALUE);
0763: }
0764: elt1.setMinOccurs(0);
0765: if (!("int".equals(schemaTypeName.getLocalPart())
0766: || "double".equals(schemaTypeName.getLocalPart())
0767: || "long".equals(schemaTypeName.getLocalPart())
0768: || "boolean".equals(schemaTypeName.getLocalPart())
0769: || "short".equals(schemaTypeName.getLocalPart()) || "float"
0770: .equals(schemaTypeName.getLocalPart()))) {
0771: elt1.setNillable(true);
0772: }
0773: }
0774:
0775: private XmlSchemaComplexType createSchemaTypeForMethodPart(
0776: String localPartName) {
0777: XmlSchema xmlSchema = getXmlSchema(schemaTargetNameSpace);
0778: QName elementName = new QName(this .schemaTargetNameSpace,
0779: localPartName, this .schema_namespace_prefix);
0780:
0781: XmlSchemaComplexType complexType = getComplexTypeForElement(
0782: xmlSchema, elementName);
0783: if (complexType == null) {
0784: complexType = new XmlSchemaComplexType(xmlSchema);
0785:
0786: XmlSchemaElement globalElement = new XmlSchemaElement();
0787: globalElement.setSchemaType(complexType);
0788: globalElement.setName(localPartName);
0789: globalElement.setQName(elementName);
0790: xmlSchema.getItems().add(globalElement);
0791: xmlSchema.getElements().add(elementName, globalElement);
0792: }
0793: typeTable.addComplexSchema(localPartName, elementName);
0794:
0795: return complexType;
0796: }
0797:
0798: private XmlSchemaComplexType createSchemaTypeForFault(
0799: String localPartName) {
0800: XmlSchema xmlSchema = getXmlSchema(schemaTargetNameSpace);
0801: QName elementName = new QName(this .schemaTargetNameSpace,
0802: localPartName, this .schema_namespace_prefix);
0803:
0804: XmlSchemaComplexType complexType = getComplexTypeForElement(
0805: xmlSchema, elementName);
0806: if (complexType == null) {
0807: complexType = new XmlSchemaComplexType(xmlSchema);
0808:
0809: XmlSchemaElement globalElement = new XmlSchemaElement();
0810: globalElement.setSchemaType(complexType);
0811: globalElement.setName(localPartName);
0812: globalElement.setQName(elementName);
0813: xmlSchema.getItems().add(globalElement);
0814: xmlSchema.getElements().add(elementName, globalElement);
0815: }
0816: return complexType;
0817: }
0818:
0819: protected XmlSchemaComplexType getComplexTypeForElement(
0820: XmlSchema xmlSchema, QName name) {
0821: Iterator iterator = xmlSchema.getItems().getIterator();
0822: while (iterator.hasNext()) {
0823: XmlSchemaObject object = (XmlSchemaObject) iterator.next();
0824: if (object instanceof XmlSchemaElement
0825: && ((XmlSchemaElement) object).getQName().equals(
0826: name)) {
0827: return (XmlSchemaComplexType) ((XmlSchemaElement) object)
0828: .getSchemaType();
0829: }
0830: }
0831: return null;
0832: }
0833:
0834: private XmlSchema getXmlSchema(String targetNamespace) {
0835: XmlSchema xmlSchema;
0836:
0837: if ((xmlSchema = (XmlSchema) schemaMap.get(targetNamespace)) == null) {
0838: String targetNamespacePrefix = null;
0839:
0840: if (targetNamespace.equals(schemaTargetNameSpace)
0841: && schema_namespace_prefix != null) {
0842: targetNamespacePrefix = schema_namespace_prefix;
0843: } else {
0844: targetNamespacePrefix = generatePrefix();
0845: }
0846:
0847: xmlSchema = new XmlSchema(targetNamespace,
0848: xmlSchemaCollection);
0849: xmlSchema
0850: .setAttributeFormDefault(getAttrFormDefaultSetting());
0851: xmlSchema
0852: .setElementFormDefault(getElementFormDefaultSetting());
0853:
0854: targetNamespacePrefixMap.put(targetNamespace,
0855: targetNamespacePrefix);
0856: schemaMap.put(targetNamespace, xmlSchema);
0857:
0858: NamespaceMap prefixmap = new NamespaceMap();
0859: prefixmap.put(DEFAULT_SCHEMA_NAMESPACE_PREFIX,
0860: URI_2001_SCHEMA_XSD);
0861: prefixmap.put(targetNamespacePrefix, targetNamespace);
0862: xmlSchema.setNamespaceContext(prefixmap);
0863: }
0864: return xmlSchema;
0865: }
0866:
0867: public TypeTable getTypeTable() {
0868: return typeTable;
0869: }
0870:
0871: public JMethod[] getMethods() {
0872: return methods;
0873: }
0874:
0875: protected String generatePrefix() {
0876: return NAME_SPACE_PREFIX + prefixCount++;
0877: }
0878:
0879: public void setExcludeMethods(ArrayList excludeMethods) {
0880: if (excludeMethods == null)
0881: excludeMethods = new ArrayList();
0882: this .excludeMethods = excludeMethods;
0883: }
0884:
0885: public String getSchemaTargetNameSpace() {
0886: return schemaTargetNameSpace;
0887: }
0888:
0889: protected void addImport(XmlSchema xmlSchema, QName schemaTypeName) {
0890: NamespacePrefixList map = xmlSchema.getNamespaceContext();
0891: if (map instanceof NamespaceMap
0892: && !((NamespaceMap) map).values().contains(
0893: schemaTypeName.getNamespaceURI())) {
0894: XmlSchemaImport importElement = new XmlSchemaImport();
0895: importElement
0896: .setNamespace(schemaTypeName.getNamespaceURI());
0897: xmlSchema.getItems().add(importElement);
0898: ((NamespaceMap) xmlSchema.getNamespaceContext()).put(
0899: generatePrefix(), schemaTypeName.getNamespaceURI());
0900: }
0901: }
0902:
0903: public String getAttrFormDefault() {
0904: return attrFormDefault;
0905: }
0906:
0907: public void setAttrFormDefault(String attrFormDefault) {
0908: this .attrFormDefault = attrFormDefault;
0909: }
0910:
0911: public String getElementFormDefault() {
0912: return elementFormDefault;
0913: }
0914:
0915: public void setElementFormDefault(String elementFormDefault) {
0916: this .elementFormDefault = elementFormDefault;
0917: }
0918:
0919: protected XmlSchemaForm getAttrFormDefaultSetting() {
0920: if (FORM_DEFAULT_UNQUALIFIED.equals(getAttrFormDefault())) {
0921: return new XmlSchemaForm(XmlSchemaForm.UNQUALIFIED);
0922: } else {
0923: return new XmlSchemaForm(XmlSchemaForm.QUALIFIED);
0924: }
0925: }
0926:
0927: protected XmlSchemaForm getElementFormDefaultSetting() {
0928: if (FORM_DEFAULT_UNQUALIFIED.equals(getElementFormDefault())) {
0929: return new XmlSchemaForm(XmlSchemaForm.UNQUALIFIED);
0930: } else {
0931: return new XmlSchemaForm(XmlSchemaForm.QUALIFIED);
0932: }
0933: }
0934:
0935: public ArrayList getExtraClasses() {
0936: if (extraClasses == null) {
0937: extraClasses = new ArrayList();
0938: }
0939: return extraClasses;
0940: }
0941:
0942: public void setExtraClasses(ArrayList extraClasses) {
0943: this .extraClasses = extraClasses;
0944: }
0945:
0946: protected String resolveSchemaNamespace(String packageName)
0947: throws Exception {
0948: //if all types must go into the wsdl types schema namespace
0949: if (useWSDLTypesNamespace) {
0950: //return schemaTargetNameSpace;
0951: return (String) pkg2nsmap.get("all");
0952: } else {
0953: if (pkg2nsmap != null && !pkg2nsmap.isEmpty()) {
0954: //if types should go into namespaces that are mapped against the package name for the type
0955: if (pkg2nsmap.get(packageName) != null) {
0956: //return that mapping
0957: return (String) pkg2nsmap.get(packageName);
0958: } else {
0959: return getNsGen().schemaNamespaceFromPackageName(
0960: packageName).toString();
0961: }
0962: } else {
0963: // if pkg2nsmap is null and if not default schema ns found for the custom bean
0964: return getNsGen().schemaNamespaceFromPackageName(
0965: packageName).toString();
0966: }
0967: }
0968: }
0969:
0970: public boolean isUseWSDLTypesNamespace() {
0971: return useWSDLTypesNamespace;
0972: }
0973:
0974: public void setUseWSDLTypesNamespace(boolean useWSDLTypesNamespace) {
0975: this .useWSDLTypesNamespace = useWSDLTypesNamespace;
0976: }
0977:
0978: public Map getPkg2nsmap() {
0979: return pkg2nsmap;
0980: }
0981:
0982: public void setPkg2nsmap(Map pkg2nsmap) {
0983: this .pkg2nsmap = pkg2nsmap;
0984: }
0985:
0986: public String getTargetNamespace() {
0987: return targetNamespace;
0988: }
0989:
0990: protected String getSimpleName(JMethod method) {
0991: return method.getSimpleName();
0992: }
0993:
0994: protected String getSimpleName(JClass type) {
0995: return type.getSimpleName();
0996: }
0997:
0998: protected String getSimpleName(JProperty peroperty) {
0999: return peroperty.getSimpleName();
1000: }
1001:
1002: protected String getSimpleName(JParameter parameter) {
1003: return parameter.getSimpleName();
1004: }
1005:
1006: protected String getQualifiedName(JMethod method) {
1007: return method.getQualifiedName();
1008: }
1009:
1010: protected String getQualifiedName(JClass type) {
1011: return type.getQualifiedName();
1012: }
1013:
1014: protected String getQualifiedName(JProperty peroperty) {
1015: return peroperty.getQualifiedName();
1016: }
1017:
1018: protected String getQualifiedName(JParameter parameter) {
1019: return parameter.getQualifiedName();
1020: }
1021:
1022: protected String getQualifiedName(JPackage packagez) {
1023: return packagez.getQualifiedName();
1024: }
1025:
1026: public void setNonRpcMethods(ArrayList nonRpcMethods) {
1027: if (nonRpcMethods != null) {
1028: this .nonRpcMethods = nonRpcMethods;
1029: }
1030: }
1031:
1032: public void setAxisService(AxisService service) {
1033: this.service = service;
1034: }
1035: }
|