0001: /*
0002: *
0003: *
0004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006: *
0007: * This program is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU General Public License version
0009: * 2 only, as published by the Free Software Foundation.
0010: *
0011: * This program is distributed in the hope that it will be useful, but
0012: * WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * General Public License version 2 for more details (a copy is
0015: * included at /legal/license.txt).
0016: *
0017: * You should have received a copy of the GNU General Public License
0018: * version 2 along with this work; if not, write to the Free Software
0019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020: * 02110-1301 USA
0021: *
0022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023: * Clara, CA 95054 or visit www.sun.com if you need additional
0024: * information or have any questions.
0025: */
0026:
0027: package com.sun.j2mews.sg;
0028:
0029: import java.io.*;
0030: import java.util.*;
0031: import java.text.*;
0032:
0033: import javax.xml.namespace.QName;
0034: import com.sun.xml.rpc.processor.model.Model;
0035: import com.sun.xml.rpc.processor.model.AbstractType;
0036: import com.sun.xml.rpc.processor.model.java.*;
0037: import com.sun.xml.rpc.encoding.InternalEncodingConstants;
0038: import com.sun.xml.rpc.wsdl.document.soap.SOAPConstants;
0039: import com.sun.xml.rpc.processor.model.soap.*;
0040: import com.sun.xml.rpc.processor.model.*;
0041: import com.sun.xml.rpc.processor.model.literal.*;
0042: import com.sun.xml.rpc.processor.generator.*;
0043: import com.sun.xml.rpc.processor.*;
0044: import com.sun.xml.rpc.processor.config.Configuration;
0045: import com.sun.xml.rpc.processor.model.Service;
0046: import com.sun.xml.rpc.processor.ProcessorOptions;
0047: import com.sun.xml.rpc.processor.util.GeneratedFileInfo;
0048: import com.sun.xml.rpc.util.localization.LocalizableMessageFactory;
0049: import com.sun.xml.rpc.util.localization.Localizer;
0050: import com.sun.xml.rpc.util.localization.Localizable;
0051:
0052: import org.netbeans.modules.schema2beansdev.gen.*;
0053:
0054: /**
0055: * We'll generate the Java client stub/proxy for JSR-172.
0056: * This is intended
0057: *
0058: */
0059: public class StubGenerator extends AbstractGenerator implements
0060: ProcessorAction {
0061: // What to use for maxOccurs="unbounded"
0062: public final static int UNBOUNDED = -1;
0063:
0064: protected boolean useWSIBasicProfile = false;
0065:
0066: // Have we already given the user info on CLDC 1.0 unsupported types?
0067: protected boolean cldc1_0InfoAlready = false;
0068:
0069: // Have we already given the user info on CLDC 1.0 converted types?
0070: protected boolean cldc1_0InfoAlreadyConverted = false;
0071:
0072: // qnames is a mapping of all QNames used by the stub.
0073: protected Map qnames; // Map<QName, String>
0074:
0075: // varNameToQNames is the inverse of the qnames map
0076: protected Map varNameToQNames; // Map<String, QName>
0077:
0078: // typeNames has all Type's (Element or ComplexType) used by the stub.
0079: protected Map typeNames; // Map<String, Type>
0080: // types is the inverse of typeNames
0081: protected LinkedHashMap types; // Map<Type, Type>
0082:
0083: // All faults that this stub uses
0084: protected Map faultNames; // Map<QName, Type>
0085:
0086: // @see setOriginalTypes
0087: protected Map originalTypes; // Map<JavaType, String>
0088:
0089: // All Java class types used by the stub (for instance, {"int", "float"})
0090: protected Map usedTypes; // Map<String, null>
0091:
0092: /**
0093: * This table lists all methods in the Stub generated from WSDL Operations.
0094: */
0095: protected Map methodNames; // Map<String, null>
0096:
0097: protected boolean floatDoubleWarning = false;
0098:
0099: protected boolean genDebug = false;
0100:
0101: protected boolean hasUserExceptions = false;
0102:
0103: protected boolean faultDetailHandlerIsInnerClass = false;
0104:
0105: protected String prepOperationMethodName = "_prepOperation";
0106:
0107: /**
0108: * The package name to use for the basic 172 runtime types.
0109: */
0110: protected String javaxMicroeditionXmlRpc = "javax.microedition.xml.rpc";
0111:
0112: public StubGenerator() {
0113: messageFactory = new LocalizableMessageFactory(
0114: "com.sun.j2mews.sg.stubgenerator");
0115: originalTypes = new HashMap();
0116: }
0117:
0118: /**
0119: * @param originalTypes Map<JavaType, String> maps all JavaType's that
0120: * were replaced (@see MakeCldc1_0), and keeps a copy of the original
0121: * java class name as the value.
0122: */
0123: public void setOriginalTypes(Map originalTypes) {
0124: this .originalTypes = originalTypes;
0125: }
0126:
0127: public void perform(Model model, Configuration config,
0128: Properties options) {
0129: useWSIBasicProfile = Boolean
0130: .valueOf(
0131: options
0132: .getProperty(ProcessorOptions.USE_WSI_BASIC_PROFILE))
0133: .booleanValue();
0134: if ("true".equals(options.getProperty(FLOAT_DOUBLE_TO_STRING))) {
0135: floatDoubleWarning = true;
0136: } else {
0137: floatDoubleWarning = false;
0138: }
0139:
0140: super .perform(model, config, options);
0141: }
0142:
0143: protected void generate() throws java.io.IOException {
0144: //
0145: // This method gets called for every generated class, make sure
0146: // that all of our tables are reset.
0147: //
0148: qnames = new HashMap();
0149: varNameToQNames = new HashMap();
0150: usedTypes = new HashMap();
0151: typeNames = new HashMap();
0152: types = new LinkedHashMap();
0153: faultNames = new HashMap();
0154: methodNames = new HashMap();
0155:
0156: if (optimize) {
0157: prepOperationMethodName = "_prep";
0158: }
0159:
0160: //
0161: // Go thru and see what the user fault situation is like.
0162: //
0163: for (Iterator operations = port.getOperations(); operations
0164: .hasNext();) {
0165: com.sun.xml.rpc.processor.model.Operation operation = (com.sun.xml.rpc.processor.model.Operation) operations
0166: .next();
0167: JavaMethod method = operation.getJavaMethod();
0168: //
0169: // Does this operation have any user faults?
0170: //
0171: if (method.getExceptionsList().size() > 0)
0172: hasUserExceptions = true;
0173:
0174: //
0175: // Are we going to define a handleFault method that will conflict
0176: // with the one in FaultDetailHandler?
0177: //
0178: String methodName = method.getName();
0179: methodNames.put(methodName, method);
0180: if ("handleFault".equals(methodName))
0181: faultDetailHandlerIsInnerClass = true;
0182: }
0183:
0184: super .generate();
0185: }
0186:
0187: protected String getFullClassName() {
0188: return env.getNames().stubFor(port, null);
0189: }
0190:
0191: protected File getSourceFile() {
0192: return env.getNames().sourceFileForClass(fullClassName,
0193: fullClassName, sourceDir, env);
0194: }
0195:
0196: protected String getSourceFileType() {
0197: return GeneratorConstants.FILE_TYPE_STUB;
0198: }
0199:
0200: protected void writeImports() throws IOException {
0201: jw.writeImport("javax.xml.rpc.JAXRPCException");
0202: jw.writeImport("javax.xml.namespace.QName");
0203: jw.writeImport(javaxMicroeditionXmlRpc + ".Operation");
0204: jw.writeImport(javaxMicroeditionXmlRpc + ".Type");
0205: jw.writeImport(javaxMicroeditionXmlRpc + ".ComplexType");
0206: jw.writeImport(javaxMicroeditionXmlRpc + ".Element");
0207: if (hasUserExceptions) {
0208: jw.writeImport(javaxMicroeditionXmlRpc
0209: + ".FaultDetailException");
0210: jw.writeImport(javaxMicroeditionXmlRpc
0211: + ".FaultDetailHandler");
0212: }
0213: jw.cr();
0214: }
0215:
0216: protected void generateClass() throws java.io.IOException {
0217: JavaInterface javaInterface = port.getJavaInterface();
0218: String implements Info = javaInterface.getName()
0219: + ", javax.xml.rpc.Stub";
0220: if (hasUserExceptions && !faultDetailHandlerIsInnerClass)
0221: implements Info += ", FaultDetailHandler";
0222: jw.writeClassDecl(className, null, implements Info, jw.PUBLIC);
0223:
0224: jw.select(jw.CONSTRUCTOR_SECTION);
0225: jw.beginConstructor(className);
0226: String address = port.getAddress();
0227: if (address == null) {
0228: jw.writeEol("_propertyNames = new String[0]");
0229: jw.writeEol("_propertyValues = new Object[0]");
0230: } else {
0231: jw
0232: .writeEol("_propertyNames = new String[] {ENDPOINT_ADDRESS_PROPERTY}");
0233: jw.writeEol("_propertyValues = new Object[] {\"" + address
0234: + "\"}");
0235: }
0236: jw.end();
0237: jw.cr();
0238:
0239: generateProperties();
0240:
0241: jw.select(jw.BODY_SECTION);
0242: jw.comment("");
0243: jw.comment(" Begin user methods");
0244: jw.comment("");
0245: generateUserMethods(port);
0246: jw.comment("");
0247: jw.comment(" End user methods");
0248: jw.comment("");
0249:
0250: jw.cr();
0251:
0252: if (genDebug) {
0253: jw.beginMethod("printObjects", "Object o", null, "void",
0254: jw.PRIVATE);
0255: jw.beginIf("o == null");
0256: jw.writeEol("System.out.print(\"null\")");
0257: jw.writeEol("return");
0258: jw.end();
0259: jw.beginIf("o.getClass().isArray()");
0260: jw.writeEol("Object[] a = (Object[]) o");
0261: jw.writeEol("System.out.print(\"{\")");
0262: jw.beginFor("int i = 0", "i < a.length", "++i");
0263: jw.beginIf("i > 0");
0264: jw.writeEol("System.out.print(\", \")");
0265: jw.end();
0266: jw.writeEol("System.out.print(\"[\"+i+\"]=\")");
0267: jw.writeEol("printObjects(a[i])");
0268: jw.end();
0269: jw.writeEol("System.out.print(\"}\")");
0270: jw.endElseBegin();
0271: jw.writeEol("System.out.print(\"\\\"\"+o+\"\\\"\")");
0272: jw.end();
0273: jw.end();
0274: jw.cr();
0275: }
0276:
0277: generateQNameVars();
0278: generateInitTypes();
0279: generateFaultHandler();
0280:
0281: jw.select(jw.DECL_SECTION);
0282: jw.cr();
0283: }
0284:
0285: protected void generateProperties() throws IOException {
0286: jw.select(jw.DECL_SECTION);
0287: jw.writeEol("private String[] _propertyNames");
0288: jw.writeEol("private Object[] _propertyValues");
0289:
0290: jw.select(jw.BODY_SECTION);
0291: jw.beginMethod("_setProperty", "String name, Object value");
0292: //jw.writeEol("name = name.intern()");
0293: jw.writeEol("int size = _propertyNames.length");
0294: jw.beginFor("int i = 0", "i < size", "++i");
0295: jw.beginIf("_propertyNames[i].equals(name)");
0296: jw.writeEol("_propertyValues[i] = value");
0297: jw.writeEol("return");
0298: jw.end(); // if
0299: jw.end(); // for
0300: jw.comment("Need to expand our array for a new property");
0301: jw.writeEol("String[] newPropNames = new String[size + 1]");
0302: jw
0303: .writeEol("System.arraycopy(_propertyNames, 0, newPropNames, 0, size)");
0304: jw.writeEol("_propertyNames = newPropNames");
0305: jw.writeEol("Object[] newPropValues = new Object[size + 1]");
0306: jw
0307: .writeEol("System.arraycopy(_propertyValues, 0, newPropValues, 0, size)");
0308: jw.writeEol("_propertyValues = newPropValues");
0309: jw.cr();
0310: jw.writeEol("_propertyNames[size] = name");
0311: jw.writeEol("_propertyValues[size] = value");
0312: jw.end();
0313: jw.cr();
0314:
0315: jw.beginMethod("_getProperty", "String name", null, "Object");
0316: //jw.writeEol("name = name.intern()");
0317: jw.beginFor("int i = 0", "i < _propertyNames.length", "++i");
0318: jw.beginIf("_propertyNames[i].equals(name)");
0319: jw.writeEol("return _propertyValues[i]");
0320: jw.end(); // if
0321: jw.end(); // for
0322: jw
0323: .beginIf("ENDPOINT_ADDRESS_PROPERTY.equals(name) || USERNAME_PROPERTY.equals(name) || PASSWORD_PROPERTY.equals(name)");
0324: jw.writeEol("return null");
0325: jw.end(); // if
0326: jw.beginIf("SESSION_MAINTAIN_PROPERTY.equals(name)");
0327: jw.writeEol("return new java.lang.Boolean(false)");
0328: jw.end(); // if
0329: jw.writeEol("throw new JAXRPCException(", localize(getMessage(
0330: "stubgenerator.unrecognizedProperty", "name")), ")");
0331: jw.end();
0332: jw.cr();
0333:
0334: jw.beginMethod(prepOperationMethodName, "Operation op", null,
0335: "void", jw.PROTECTED);
0336: jw.beginFor("int i = 0", "i < _propertyNames.length", "++i");
0337: jw
0338: .writeEol("op.setProperty(_propertyNames[i], _propertyValues[i].toString())");
0339: jw.end(); // for
0340: jw.end();
0341: jw.cr();
0342: }
0343:
0344: protected void generateUserMethods(Port port)
0345: throws java.io.IOException {
0346: Iterator operations = port.getOperations();
0347: while (operations.hasNext()) {
0348: com.sun.xml.rpc.processor.model.Operation operation = (com.sun.xml.rpc.processor.model.Operation) operations
0349: .next();
0350: JavaInterface portInterface = port.getJavaInterface();
0351: generateUserMethods(operation, portInterface);
0352: }
0353: }
0354:
0355: protected void generateUserMethods(Operation operation,
0356: JavaInterface portInterface) throws java.io.IOException {
0357: JavaMethod method = operation.getJavaMethod();
0358: // methodName is the name we should give our method
0359: String methodName = method.getName();
0360: // operationName is the name of the operation as the web service sees
0361: // it.
0362: QName operationQName = operation.getName();
0363: String operationName = operationQName.getLocalPart();
0364: if (operationQName.getNamespaceURI() == null
0365: || "".equals(operationQName.getNamespaceURI()))
0366: operationQName = new QName(
0367: port.getName().getNamespaceURI(), operationName);
0368: jw.cr();
0369:
0370: // Make sure we're document/literal here.
0371: if (operation.getStyle() != com.sun.xml.rpc.wsdl.document.soap.SOAPStyle.DOCUMENT
0372: || operation.getUse() != com.sun.xml.rpc.wsdl.document.soap.SOAPUse.LITERAL) {
0373: String style = styleToString(operation.getStyle());
0374: String use = useToString(operation.getUse());
0375: Localizable msg = getMessage(
0376: "stubgenerator.wrongStyleOrUse", operationName,
0377: style, use);
0378: commentWarning(msg);
0379: return;
0380: }
0381:
0382: if (!isValid(operation, usedTypes)) {
0383: Localizable msg = getMessage(
0384: "stubgenerator.operationHasInvalidType",
0385: operationName);
0386: commentWarning(msg);
0387: return;
0388: }
0389:
0390: JavaType origReturnType = method.getReturnType();
0391: JavaType returnType = getExpandedReturnType(method);
0392: String returnTypeName = javaTypeToString(returnType);
0393: boolean voidReturnType = (returnType == null || "void"
0394: .equals(returnTypeName));
0395:
0396: Map usedNames = new HashMap();
0397: // Make sure we don't create any variables with the same name as
0398: // a method.
0399: usedNames.putAll(methodNames);
0400:
0401: jw.write("public ");
0402: if (voidReturnType) {
0403: jw.write("void");
0404: } else {
0405: jw.write(returnTypeName);
0406: }
0407: jw.write(" ");
0408: jw.write(methodName);
0409: jw.write("(");
0410: jw.setFirst(", ");
0411: List parameterList = getExpandedParametersList(method);
0412: int parameterCount = parameterList.size();
0413:
0414: for (Iterator parameters = parameterList.iterator(); parameters
0415: .hasNext();) {
0416: JavaParameter parameter = (JavaParameter) parameters.next();
0417: JavaType parameterType = parameter.getType();
0418: String paramTypeName = javaTypeToString(parameterType);
0419: jw.writeNext(paramTypeName, " ", parameter.getName());
0420: usedNames.put(parameter.getName(), parameter);
0421: }
0422: jw.write(")");
0423: jw.write(" throws java.rmi.RemoteException");
0424: boolean operationHasUserExceptions = false;
0425: for (Iterator exceptions = method.getExceptions(); exceptions
0426: .hasNext();) {
0427: operationHasUserExceptions = true;
0428: String exceptionName = (String) exceptions.next();
0429: jw.write(", ");
0430: jw.write(exceptionName);
0431: }
0432: jw.write(" ");
0433: jw.begin();
0434:
0435: String resultObjVar = makeUniq("resultObj", usedNames); // reserve this variable name
0436: String resultVar = makeUniq("result", usedNames); // reserve this variable name
0437:
0438: String inputVar = null;
0439: String inputObjectVar = null;
0440: if (method.getParameterCount() > 0) {
0441: // Make sure we iterate over parameters from the original list
0442: if (method.getParameterCount() > 1) {
0443: onWarning(getMessage(
0444: "stubgenerator.moreThanOneParameter",
0445: methodName));
0446: }
0447: for (Iterator parameters = method.getParameters(); parameters
0448: .hasNext();) {
0449: JavaParameter parameter = (JavaParameter) parameters
0450: .next();
0451:
0452: Parameter p = parameter.getParameter();
0453: Block parameterBlock = p.getBlock();
0454:
0455: JavaType parameterType = parameter.getType();
0456: String paramTypeName = javaTypeToString(parameterType);
0457: Type resultTypeVar = convertJavaTypeToType(parameterType);
0458: boolean isNillable = p.getType().isNillable();
0459: //System.out.println("methodName="+methodName+" paramTypeName="+paramTypeName+" isNillable="+isNillable);
0460: if (!isNillable) {
0461: // Double check due to a feature of JAX-RPC.
0462: isNillable = forceNillable(parameterType,
0463: methodName);
0464: }
0465: boolean isOptional = false;
0466: Element resultElement = getElement(parameterBlock
0467: .getName(), resultTypeVar, false, isNillable,
0468: isOptional);
0469: resultElement.setTopLevel(true);
0470: inputVar = resultElement.getVarName();
0471: }
0472:
0473: // Make sure to use the parameters from our copy of the list.
0474: Iterator parameters = parameterList.iterator();
0475: jw
0476: .comment("Copy the incoming values into an Object array if needed.");
0477: boolean multipleParams = parameterList.size() > 1
0478: || parameterList != method.getParametersList();
0479: String multipleParamsVar = null;
0480: if (multipleParams) {
0481: multipleParamsVar = instanceOf("input", "Object",
0482: usedNames);
0483: jw.writeEol("Object[] ", multipleParamsVar,
0484: " = new Object[" + parameterList.size(), "]");
0485: }
0486: for (int paramNum = 0; parameters.hasNext(); ++paramNum) {
0487: JavaParameter parameter = (JavaParameter) parameters
0488: .next();
0489: String paramJavaName = parameter.getName();
0490: JavaType parameterType = parameter.getType();
0491: inputObjectVar = genMakeInputObject(parameterType,
0492: usedNames, paramJavaName);
0493: if (multipleParams) {
0494: jw.writeEol(multipleParamsVar, "[" + paramNum,
0495: "] = ", inputObjectVar);
0496: }
0497: }
0498: if (multipleParams) {
0499: inputObjectVar = multipleParamsVar;
0500: }
0501: }
0502: if (genDebug) {
0503: jw.writeEol("System.out.print(\"Input objects: \")");
0504: jw.writeEol("printObjects(", inputObjectVar, ")");
0505: jw.writeEol("System.out.println()");
0506: }
0507:
0508: String outputVar = null;
0509: if (!voidReturnType) {
0510: Type outputTypeVar = convertJavaTypeToType(origReturnType);
0511: QName returnTypeQName = null;
0512: Response response = operation.getResponse();
0513: boolean isNillable = false;
0514: boolean isOptional = false;
0515: for (Iterator it = response.getParameters(); it.hasNext();) {
0516: Parameter p = (Parameter) it.next();
0517: Block block = p.getBlock();
0518: returnTypeQName = block.getName();
0519: isNillable = p.getType().isNillable();
0520: /* Trust the nillable from the type
0521: if (!isNillable) {
0522: isNillable = forceNillable(returnType, methodName);
0523: }
0524: */
0525: // There should only be 1 Parameter in the return.
0526: }
0527: Element outputElement = getElement(returnTypeQName,
0528: outputTypeVar, false, isNillable, isOptional);
0529: outputElement.setTopLevel(true);
0530: outputVar = outputElement.getVarName();
0531: }
0532:
0533: jw.cr();
0534: jw.write("Operation op = Operation.newInstance(",
0535: getQNameVar(operationQName), ", ");
0536: jw.write(inputVar, ", ", outputVar);
0537: if (operationHasUserExceptions) {
0538: if (faultDetailHandlerIsInnerClass)
0539: jw.write(", _myFaultDetailHandler");
0540: else
0541: jw.write(", this");
0542: }
0543: jw.writeEol(")");
0544: jw.writeEol(prepOperationMethodName, "(op)");
0545: String soapAction = operation.getSOAPAction();
0546: if (soapAction == null) {
0547: // See Section 8.2.1. If not set, it shall be the empty string.
0548: soapAction = "";
0549: }
0550: jw.writeEol(
0551: "op.setProperty(Operation.SOAPACTION_URI_PROPERTY, ",
0552: JavaUtil.instanceFrom("String", operation
0553: .getSOAPAction()), ")");
0554:
0555: if (!voidReturnType)
0556: jw.writeEol("Object ", resultObjVar);
0557: jw.beginTry();
0558: if (!voidReturnType) {
0559: jw.write(resultObjVar, " = ");
0560: }
0561: jw.writeEol("op.invoke(", inputObjectVar, ")");
0562: jw.endCatch("JAXRPCException e");
0563: String causeVar = makeUniq("cause", usedNames);
0564: jw.writeEol("Throwable ", causeVar, " = e.getLinkedCause()");
0565: jw.beginIf(causeVar + " instanceof java.rmi.RemoteException");
0566: jw.writeEol("throw (java.rmi.RemoteException) ", causeVar);
0567: if (operationHasUserExceptions) {
0568: jw.endElseBeginIf(causeVar
0569: + " instanceof FaultDetailException");
0570: String fdeVar = makeUniq("fde", usedNames);
0571: String fdeNameVar = makeUniq("fdeName", usedNames);
0572: jw.writeEol("FaultDetailException ", fdeVar,
0573: " = (FaultDetailException) ", causeVar);
0574: jw.write("QName ", fdeNameVar);
0575: jw.writeEol(" = ", fdeVar, ".getFaultDetailName()");
0576: genMakeFaults(operation, fdeVar, fdeNameVar, usedNames);
0577: }
0578: jw.end();
0579: jw.writeEol("throw e");
0580: jw.end();
0581: if (genDebug) {
0582: jw.writeEol("System.out.print(\"Output objects: \")");
0583: jw.writeEol("printObjects(", resultObjVar, ")");
0584: jw.writeEol("System.out.println()");
0585: }
0586:
0587: if (!voidReturnType) {
0588: jw.writeEol(returnTypeName, " ", resultVar);
0589: jw.comment("Convert the result into the right Java type.");
0590: if (origReturnType == returnType) {
0591: genMakeOutputObject(resultObjVar, false, resultVar,
0592: returnType, usedNames);
0593: } else {
0594: jw.comment("Unwrapped return value");
0595: JavaStructureType jst = (JavaStructureType) origReturnType;
0596: // There's only 1 member.
0597: JavaStructureMember jsm = (JavaStructureMember) jst
0598: .getMembers().next();
0599: genMakeOutputObject(resultObjVar, false, resultVar,
0600: jsm, 0, 1, usedNames);
0601: }
0602: jw.writeEol("return ", resultVar);
0603: }
0604: jw.end();
0605: }
0606:
0607: /**
0608: * Convert JavaType into the a Type which the stub will use.
0609: */
0610: protected Type convertJavaTypeToType(JavaType type)
0611: throws IOException {
0612: //jw.comment("type="+type);
0613: String typeName = javaTypeToString(type).intern();
0614: //jw.comment("typeName="+typeName);
0615: if (type instanceof JavaSimpleType) {
0616: Type result = Type.toType(typeName);
0617: if (result == Type.UNKNOWN) {
0618: onError(getMessage("stubgenerator.unknownSimpleType",
0619: typeName));
0620: }
0621: return result;
0622: } else if (type instanceof JavaStructureType) {
0623: JavaStructureType jst = (JavaStructureType) type;
0624: int membersCount = jst.getMembersCount();
0625: List elements = new ArrayList(membersCount); // List<Type>
0626: for (Iterator members = jst.getMembers(); members.hasNext();) {
0627: JavaStructureMember jsm = (JavaStructureMember) members
0628: .next();
0629: //jw.comment("jsm="+jsm);
0630: String memberName = jsm.getName();
0631: JavaType memberType = jsm.getType();
0632:
0633: boolean isArray = false;
0634: boolean isNillable = false;
0635: boolean isOptional = false;
0636: if (memberType instanceof JavaArrayType)
0637: isArray = true;
0638: QName memberQName = null;
0639: Object memberOwner = jsm.getOwner();
0640: //jw.comment("memberOwner="+memberOwner);
0641: if (memberOwner instanceof AbstractType) {
0642: AbstractType at = (AbstractType) memberOwner;
0643: //jw.comment("at.getName="+at.getName());
0644: memberQName = at.getName();
0645: if (at.isNillable())
0646: isNillable = true;
0647: } else if (memberOwner instanceof LiteralElementMember) {
0648: LiteralElementMember lem = (LiteralElementMember) memberOwner;
0649: memberQName = lem.getName();
0650: if (lem.isNillable()) {
0651: isNillable = true;
0652: }
0653: if (!lem.isRequired())
0654: isOptional = true;
0655: //jw.comment("lem.gettype="+lem.getType());
0656: } else {
0657: jw
0658: .comment("!!!!!!! memberOwner is of unknown type: "
0659: + memberOwner);
0660: }
0661: /*
0662: if (!isNillable) {
0663: isNillable = forceNillable(memberType, memberQName.toString());
0664: }
0665: */
0666: //jw.comment("memberQName="+memberQName+" isNillable="+isNillable+" isOptional="+isOptional+" isArray="+isArray);
0667: if (memberQName == null) {
0668: onError(getMessage(
0669: "stubgenerator.unknownQNameOfMember",
0670: memberName));
0671: }
0672:
0673: Type memberTypeVarName = convertJavaTypeToType(memberType);
0674: Element element = getElement(memberQName,
0675: memberTypeVarName, isArray, isNillable,
0676: isOptional);
0677: elements.add(element);
0678: }
0679: ComplexType cType = getComplexType(type, elements);
0680: return cType;
0681: } else if (type instanceof JavaArrayType) {
0682: JavaArrayType jat = (JavaArrayType) type;
0683: JavaType elementType = jat.getElementType();
0684: //jw.comment("jat="+jat+" elementType="+elementType);
0685: String elementTypeName = javaTypeToString(elementType);
0686: Type elementTypeVarName = convertJavaTypeToType(elementType);
0687: return elementTypeVarName;
0688: } else if (type instanceof JavaEnumerationType) {
0689: JavaEnumerationType jet = (JavaEnumerationType) type;
0690: JavaType baseType = jet.getBaseType();
0691: return convertJavaTypeToType(baseType);
0692: } else {
0693: commentWarning(getMessage("stubgenerator.unknownType",
0694: "convertJavaTypeToType", type.toString()));
0695: }
0696: return Type.UNKNOWN;
0697: }
0698:
0699: /**
0700: * Generate code to convert a java bean graph (most likely from the
0701: * formal parameter) into an Object[] as the spec defines. See
0702: * Section 8.2.4.
0703: */
0704: protected String genMakeInputObject(JavaType type, Map usedNames,
0705: String inputExpr) throws IOException {
0706: //jw.comment("type="+type);
0707: String typeName = javaTypeToString(type).intern();
0708: if (type instanceof JavaSimpleType) {
0709: return JavaUtil.toObject(inputExpr, typeName, true);
0710: } else if (type instanceof JavaStructureType) {
0711: JavaStructureType jst = (JavaStructureType) type;
0712: int membersCount = jst.getMembersCount();
0713: String varName = instanceOf(type, "Object", usedNames);
0714: List resultExprs = new ArrayList(membersCount); // List<String>
0715: jw.writeEol("Object[] ", varName);
0716: jw.beginIf(inputExpr + " == null");
0717: jw.writeEol(varName, " = null");
0718: jw.endElseBegin();
0719: for (Iterator members = jst.getMembers(); members.hasNext();) {
0720: JavaStructureMember jsm = (JavaStructureMember) members
0721: .next();
0722: JavaType memberType = jsm.getType();
0723: String memberTypeName = javaTypeToString(memberType);
0724: String curInputExpr = inputExpr + "."
0725: + jsm.getReadMethod() + "()";
0726: String resultExpr = genMakeInputObject(memberType,
0727: usedNames, curInputExpr);
0728: resultExprs.add(resultExpr);
0729: }
0730: jw.writeEol(varName, " = new Object[" + membersCount, "]");
0731: Iterator resultExprIt = resultExprs.iterator();
0732: for (int elementNum = 0; resultExprIt.hasNext(); ++elementNum) {
0733: String resultExpr = (String) resultExprIt.next();
0734: jw.write(varName, "[" + elementNum, "] = ");
0735: jw.writeEol(resultExpr);
0736: }
0737: jw.end();
0738: return varName;
0739: } else if (type instanceof JavaArrayType) {
0740: JavaArrayType jat = (JavaArrayType) type;
0741: JavaType elementType = jat.getElementType();
0742: if (elementType instanceof JavaSimpleType) {
0743: //jw.comment(inputExpr+" is already the right type (array of simple things).");
0744: return inputExpr;
0745: }
0746:
0747: String elementTypeName = javaTypeToString(elementType);
0748: String varName = instanceOf(type, "Object", usedNames);
0749: jw.writeEol("Object[] ", varName);
0750: jw.beginIf(inputExpr + " == null");
0751: //jw.writeEol(varName, " = null");
0752: //jw.comment("Arrays can only be empty, not null");
0753: //jw.writeEol("throw new IllegalArgumentException(\"", inputExpr, " == null\")");
0754: // See section 8.2.4, null arrays are the same as a 0 length array.
0755: jw.writeEol(varName, " = new Object[0]");
0756: jw.endElseBegin();
0757: jw.write(varName, " = new Object[");
0758: jw.writeEol(inputExpr, ".length]");
0759: String indexVar = instanceOf(type, "Index", usedNames);
0760: String curInputExpr = inputExpr + "[" + indexVar + "]";
0761: jw.beginFor("int " + indexVar + " = 0", indexVar + " < "
0762: + inputExpr + ".length", "++" + indexVar);
0763: String resultExpr = genMakeInputObject(elementType,
0764: usedNames, curInputExpr);
0765: jw.cr();
0766: jw.write(varName, "[", indexVar);
0767: jw.writeEol("] = ", resultExpr);
0768: jw.end();
0769: jw.end();
0770: return varName;
0771: } else if (type instanceof JavaEnumerationType) {
0772: JavaEnumerationType jet = (JavaEnumerationType) type;
0773: JavaType baseType = jet.getBaseType();
0774: return genMakeInputObject(baseType, usedNames, inputExpr
0775: + ".getValue()");
0776: } else {
0777: jw.comment(" Hit unknown type: type=" + type + " for "
0778: + inputExpr);
0779: commentWarning(getMessage("stubgenerator.unknownType",
0780: "genMakeInputObject", type.toString()));
0781: return "unknown type (" + type + ") for " + inputExpr;
0782: }
0783: }
0784:
0785: /**
0786: * Generate code to convert an Object[] into a java bean graph.
0787: * See Section 8.2.6.
0788: */
0789: protected void genMakeOutputObject(String objName,
0790: boolean objNameIsArray, String resultName, JavaType type,
0791: Map usedNames) throws IOException {
0792: //jw.comment("type="+type);
0793: String typeName = javaTypeToString(type).intern();
0794: if (type instanceof JavaSimpleType) {
0795: if (objNameIsArray)
0796: objName = "((Object)" + objName + ")";
0797: jw.writeEol(resultName, " = ", JavaUtil.fromObject(
0798: typeName, objName));
0799: } else if (type instanceof JavaStructureType) {
0800: JavaStructureType jst = (JavaStructureType) type;
0801: jw.beginIf(objName + " == null");
0802: jw.writeEol(resultName, " = null");
0803: jw.endElseBegin();
0804: jw.write(resultName, " = new ");
0805: jw.writeEol(typeName, "()");
0806: int membersCount = jst.getMembersCount();
0807: Iterator members = jst.getMembers();
0808: for (int elementNum = 0; members.hasNext(); ++elementNum) {
0809: JavaStructureMember jsm = (JavaStructureMember) members
0810: .next();
0811: JavaType memberType = jsm.getType();
0812: String memberTypeName = javaTypeToString(memberType);
0813: String varName = instanceOf(memberType, usedNames);
0814: jw.writeEol(memberTypeName, " ", varName);
0815: genMakeOutputObject(objName, objNameIsArray, varName,
0816: jsm, elementNum, membersCount, usedNames);
0817: jw.writeEol(resultName + "." + jsm.getWriteMethod()
0818: + "(" + varName + ")");
0819: }
0820: jw.end();
0821: } else if (type instanceof JavaArrayType) {
0822: JavaArrayType jat = (JavaArrayType) type;
0823: JavaType elementType = jat.getElementType();
0824: String elementTypeName = javaTypeToString(elementType);
0825: if (elementType instanceof JavaSimpleType) {
0826: //
0827: // The SPI will return an array of the right type
0828: // for simple types.
0829: // Don't need to go thru and copy it over 1 by 1.
0830: //
0831: jw.write(resultName, " = (", elementTypeName, "[]) ");
0832: jw.writeEol(objName);
0833: } else {
0834: jw.beginIf(objName + " == null");
0835: jw.writeEol(resultName, " = null");
0836: jw.endElseBegin();
0837: if (!objNameIsArray)
0838: objName = "((Object[])" + objName + ")";
0839: String sizeVar = instanceOf(type, "Size", usedNames);
0840: jw.write("int ", sizeVar, " = ");
0841: jw.writeEol(objName, ".length");
0842: jw.write(resultName, " = new ", elementTypeName);
0843: jw.writeEol("[", sizeVar, "]");
0844: String indexVar = instanceOf(type, "Index", usedNames);
0845: String curResultExpr = resultName + "[" + indexVar
0846: + "]";
0847: String curObjExpr = objName + "[" + indexVar + "]";
0848: jw.beginFor("int " + indexVar + " = 0", indexVar
0849: + " < " + sizeVar, "++" + indexVar);
0850: genMakeOutputObject(curObjExpr, false, curResultExpr,
0851: elementType, usedNames);
0852: jw.end();
0853: jw.end();
0854: }
0855: } else if (type instanceof JavaEnumerationType) {
0856: JavaEnumerationType jet = (JavaEnumerationType) type;
0857: JavaType baseType = jet.getBaseType();
0858: jw.beginIf(objName + " == null");
0859: jw.writeEol(resultName, " = null");
0860: jw.endElseBegin();
0861: String varName = instanceOf(type, usedNames);
0862: jw.writeEol(javaTypeToString(baseType), " ", varName);
0863: genMakeOutputObject(objName, objNameIsArray, varName,
0864: baseType, usedNames);
0865: jw.write(resultName, " = ");
0866: jw.writeEol(typeName, ".fromValue(", varName, ")");
0867: jw.end();
0868: } else {
0869: commentWarning(getMessage("stubgenerator.unknownType",
0870: "genMakeOutputObject", type.toString()));
0871: }
0872: }
0873:
0874: protected void genMakeOutputObject(String objName,
0875: boolean objNameIsArray, String resultName,
0876: JavaStructureMember jsm, int elementNum, int membersCount,
0877: Map usedNames) throws IOException {
0878: String memberName = jsm.getName();
0879: JavaType memberType = jsm.getType();
0880: String memberObjName = makeUniq(memberName + "Obj", usedNames);
0881: boolean memberObjNameIsArray;
0882: //
0883: // Declare a new variable, memberObjName, and initalize it's value
0884: // to be objName[elementNum]
0885: //
0886: if (memberType instanceof JavaSimpleType
0887: || memberType instanceof JavaEnumerationType
0888: || (memberType instanceof JavaArrayType && ((JavaArrayType) memberType)
0889: .getElementType() instanceof JavaSimpleType)) {
0890: jw.write("Object ", memberObjName, " = ");
0891: memberObjNameIsArray = false;
0892: } else {
0893: jw.write("Object[] ", memberObjName, " = (Object[]) ");
0894: memberObjNameIsArray = true;
0895: }
0896: if (objNameIsArray)
0897: jw.write(objName);
0898: else
0899: jw.write("((Object[])", objName, ")");
0900: jw.write("[" + elementNum, "]");
0901: jw.eol();
0902: genMakeOutputObject(memberObjName, memberObjNameIsArray,
0903: resultName, memberType, usedNames);
0904: }
0905:
0906: /**
0907: * Generate code to convert a JAXRPCException into service
0908: * specific exceptions.
0909: */
0910: protected void genMakeFaults(Operation operation, String fdeVar,
0911: String fdeNameVar, Map usedNames) throws IOException {
0912: for (Iterator faults = operation.getFaults(); faults.hasNext();) {
0913: Fault fault = (Fault) faults.next();
0914: Block faultBlock = fault.getBlock();
0915: QName exceptionName = faultBlock.getName();
0916: JavaException jexcep = fault.getJavaException();
0917:
0918: boolean wrappedSimpleType;
0919: if (jexcep.getMembersCount() == 1
0920: && faultBlock.getType() instanceof LiteralSimpleType) {
0921: //
0922: // JAX-RPC is wrapping the simple type up into a
0923: // complexType, which is fine for the Java side, but
0924: // we need to correctly describe the schema type as being
0925: // simple (in the Type's).
0926: //
0927: wrappedSimpleType = true;
0928: } else {
0929: wrappedSimpleType = false;
0930: }
0931:
0932: Type exceptionType = convertJavaTypeToType(jexcep);
0933: Element exceptionElement;
0934: if (wrappedSimpleType
0935: && exceptionType instanceof ComplexType) {
0936: ComplexType cType = (ComplexType) exceptionType;
0937: // Pull out the first element, and use it instead.
0938: exceptionElement = cType.getElement(0);
0939: exceptionName = exceptionElement.getQName();
0940: } else {
0941: exceptionElement = getElement(exceptionName,
0942: exceptionType);
0943: }
0944: exceptionElement.setTopLevel(true);
0945: //jw.comment("exception var name ="+exceptionElement.getVarName());
0946: faultNames.put(exceptionName, exceptionElement);
0947:
0948: jw.beginIf("\"" + exceptionName.getLocalPart()
0949: + "\".equals(" + fdeNameVar
0950: + ".getLocalPart()) && \""
0951: + exceptionName.getNamespaceURI() + "\".equals("
0952: + fdeNameVar + ".getNamespaceURI())");
0953: boolean firstMember = true;
0954: int elementNum = 0;
0955: List paramNames = new ArrayList(jexcep.getMembersCount());
0956: for (Iterator members = jexcep.getMembers(); members
0957: .hasNext(); ++elementNum) {
0958: firstMember = false;
0959: JavaStructureMember jsm = (JavaStructureMember) members
0960: .next();
0961: String paramName = instanceOf(jsm.getName(), "_param",
0962: usedNames);
0963: paramNames.add(paramName);
0964: JavaType memberType = jsm.getType();
0965: String memberTypeName = javaTypeToString(memberType);
0966: // Declare each parameter and give it a default value.
0967: jw.writeEol(memberTypeName, " ", paramName); // + " = " + JavaUtil.nullValueForType(memberTypeName));
0968: String objName;
0969: if (wrappedSimpleType) {
0970: objName = fdeVar + ".getFaultDetail()";
0971: } else {
0972: objName = "((Object[])" + fdeVar
0973: + ".getFaultDetail())[" + elementNum + "]";
0974: }
0975: genMakeOutputObject(objName, false, paramName,
0976: memberType, usedNames);
0977: }
0978: jw.write("throw new ");
0979: jw.write(javaTypeToString(jexcep));
0980: jw.write("(");
0981: jw.setFirst(", ");
0982: for (Iterator paramNamesIt = paramNames.iterator(); paramNamesIt
0983: .hasNext();) {
0984: String paramName = (String) paramNamesIt.next();
0985: jw.writeNext(paramName);
0986: }
0987: jw.writeEol(")");
0988: jw.end();
0989: }
0990: }
0991:
0992: /**
0993: * Check all types associated with an Operation and make sure they are
0994: * all valid.
0995: */
0996: public boolean isValid(Operation operation, Map usedTypes) {
0997: JavaMethod method = operation.getJavaMethod();
0998: JavaType returnType = method.getReturnType();
0999: String operationName = operation.getName().getLocalPart();
1000: if (!isValid("Operation " + operationName + " return type",
1001: returnType, usedTypes))
1002: return false;
1003: for (Iterator parameters = method.getParameters(); parameters
1004: .hasNext();) {
1005: JavaParameter parameter = (JavaParameter) parameters.next();
1006: if (!isValid("Operation " + operationName + " parameter "
1007: + parameter.getName(), parameter.getType(),
1008: usedTypes))
1009: return false;
1010: }
1011: for (Iterator faults = operation.getFaults(); faults.hasNext();) {
1012: Fault fault = (Fault) faults.next();
1013: Block faultBlock = fault.getBlock();
1014: JavaException jexcep = fault.getJavaException();
1015: if (!isValid("Operation " + operationName + " fault "
1016: + fault.getName(), jexcep, usedTypes))
1017: return false;
1018: }
1019: return true;
1020: }
1021:
1022: public boolean isValid(String contextInfo, JavaType type,
1023: Map usedTypes) {
1024: String typeName = javaTypeToString(type);
1025: if (typeName == null)
1026: return true;
1027: typeName = typeName.intern();
1028: if (type instanceof JavaSimpleType) {
1029: usedTypes.put(typeName, null);
1030: if (originalTypes.containsKey(type)) {
1031: String originalTypeName = (String) originalTypes
1032: .get(type);
1033: if (showCldc1_0Info) {
1034: onWarning(getMessage(
1035: "stubgenerator.cldc1_0.warning",
1036: contextInfo, originalTypeName, typeName));
1037: } else if (!cldc1_0InfoAlreadyConverted) {
1038: onWarning(getMessage("stubgenerator.cldc1_0.generalInfoConverted"));
1039: cldc1_0InfoAlreadyConverted = true;
1040: }
1041: return true;
1042: }
1043: if (typeName == "float" || typeName == "Float"
1044: || typeName == "java.lang.Float"
1045: || typeName == "double" || typeName == "Double"
1046: || typeName == "java.lang.Double") {
1047: if (showCldc1_0Info) {
1048: onInfo(getMessage("stubgenerator.cldc1_0.info",
1049: contextInfo, typeName));
1050: } else if (!cldc1_0InfoAlready) {
1051: onInfo(getMessage("stubgenerator.cldc1_0.generalInfo"));
1052: cldc1_0InfoAlready = true;
1053: }
1054: return true;
1055: }
1056: if (typeName == "javax.xml.soap.SOAPElement") {
1057: onError(getMessage("stubgenerator.unknownSimpleType",
1058: typeName));
1059: return false;
1060: }
1061: if (!isValidType(typeName)) {
1062: onError(getMessage("stubgenerator.invalidType",
1063: contextInfo, typeName));
1064: return false;
1065: }
1066: } else if (type instanceof JavaStructureType) {
1067: JavaStructureType jst = (JavaStructureType) type;
1068: Iterator members = jst.getMembers();
1069: while (members.hasNext()) {
1070: JavaStructureMember jsm = (JavaStructureMember) members
1071: .next();
1072: if (!isValid(contextInfo + "." + jsm.getName(), jsm
1073: .getType(), usedTypes))
1074: return false;
1075: }
1076: } else if (type instanceof JavaArrayType) {
1077: JavaArrayType jat = (JavaArrayType) type;
1078: if (!isValid(contextInfo + "[]", jat.getElementType(),
1079: usedTypes))
1080: return false;
1081: } else if (type instanceof JavaEnumerationType) {
1082: JavaEnumerationType jet = (JavaEnumerationType) type;
1083: JavaType baseType = jet.getBaseType();
1084: if (!isValid(contextInfo + " enumeration", baseType,
1085: usedTypes))
1086: return false;
1087: } else {
1088: onWarning(getMessage("stubgenerator.unknownType",
1089: "isValid", type.toString()));
1090: }
1091: return true;
1092: }
1093:
1094: protected void commentWarning(Localizable msg) throws IOException {
1095: comment(msg);
1096: onWarning(msg);
1097: }
1098:
1099: protected void comment(Localizable msg) throws IOException {
1100: jw.comment(localizer.localize(msg));
1101: }
1102:
1103: protected String styleToString(
1104: com.sun.xml.rpc.wsdl.document.soap.SOAPStyle style) {
1105: if (style == com.sun.xml.rpc.wsdl.document.soap.SOAPStyle.DOCUMENT)
1106: return "document";
1107: else if (style == com.sun.xml.rpc.wsdl.document.soap.SOAPStyle.RPC)
1108: return "rpc";
1109: else
1110: return "unknown";
1111: }
1112:
1113: protected String useToString(
1114: com.sun.xml.rpc.wsdl.document.soap.SOAPUse use) {
1115: if (use == com.sun.xml.rpc.wsdl.document.soap.SOAPUse.LITERAL)
1116: return "literal";
1117: else if (use == com.sun.xml.rpc.wsdl.document.soap.SOAPUse.ENCODED)
1118: return "encoded";
1119: else
1120: return "unknown";
1121: }
1122:
1123: protected boolean forceNillable(JavaType javatype, String methodName) {
1124: String type = javaTypeToString(javatype);
1125: if (!type.equals(JavaUtil.fromObjectType(type))) {
1126: //onWarning(getMessage("stubgenerator.forcingNillable",
1127: // type, methodName));
1128: return true;
1129: }
1130: return false;
1131: }
1132:
1133: protected String getQNameVar(QName name) {
1134: if (qnames.containsKey(name))
1135: return (String) qnames.get(name);
1136: String qnameVar;
1137: if (optimize)
1138: qnameVar = makeUniq("_q", varNameToQNames);
1139: else
1140: qnameVar = makeVarName(name, "_qname_", varNameToQNames);
1141: varNameToQNames.put(qnameVar, name);
1142: qnames.put(name, qnameVar);
1143: return qnameVar;
1144: }
1145:
1146: /**
1147: * Generate code to define each QName used in the stub.
1148: */
1149: protected void generateQNameVars() throws IOException {
1150: List sortedNames = new ArrayList(qnames.keySet());
1151: // Make it a stable listing.
1152: Collections.sort(sortedNames, new QNameComparator());
1153: for (Iterator it = sortedNames.iterator(); it.hasNext();) {
1154: Object o = it.next();
1155: QName name = (QName) o;
1156: jw.write("protected static final QName ");
1157: jw.write((String) qnames.get(name));
1158: jw.write(" = new QName(");
1159: if (name.getNamespaceURI() == null)
1160: jw.write("null");
1161: else {
1162: jw.write("\"");
1163: jw.write(name.getNamespaceURI());
1164: jw.write("\"");
1165: }
1166: jw.write(", \"");
1167: jw.write(name.getLocalPart());
1168: jw.writeEol("\")");
1169: }
1170: }
1171:
1172: /**
1173: * Provide an ordering for QNames.
1174: */
1175: protected static class QNameComparator implements Comparator {
1176: public QNameComparator() {
1177: }
1178:
1179: public int compare(Object o1, Object o2) {
1180: QName qn1 = (QName) o1;
1181: QName qn2 = (QName) o2;
1182: int result = qn1.getNamespaceURI().compareTo(
1183: qn2.getNamespaceURI());
1184: if (result == 0)
1185: result = qn1.getLocalPart().compareTo(
1186: qn2.getLocalPart());
1187: return result;
1188: }
1189: }
1190:
1191: /**
1192: * This class mimics javax.microedition.xml.rpc.Type and will
1193: * convert itself into java code that creates that Type.
1194: */
1195: protected static class Type {
1196: protected String varName;
1197:
1198: protected Type(String varName) {
1199: this .varName = varName;
1200: }
1201:
1202: public String getVarName() {
1203: return varName;
1204: }
1205:
1206: public String getClassName() {
1207: throw new UnsupportedOperationException();
1208: }
1209:
1210: public boolean isTopLevel() {
1211: return false;
1212: }
1213:
1214: public final static Type BOOLEAN = new Type("Type.BOOLEAN");
1215: public final static Type BYTE = new Type("Type.BYTE");
1216: public final static Type DOUBLE = new Type("Type.DOUBLE");
1217: public final static Type FLOAT = new Type("Type.FLOAT");
1218: public final static Type INT = new Type("Type.INT");
1219: public final static Type LONG = new Type("Type.LONG");
1220: public final static Type SHORT = new Type("Type.SHORT");
1221: public final static Type STRING = new Type("Type.STRING");
1222: public final static Type UNKNOWN = new Type("UNKNOWN");
1223:
1224: /**
1225: * Convert the normal java type into the enumeration of Type.
1226: * @param name The java class name (e.g., "int").
1227: */
1228: public static Type toType(String name) {
1229: Type result = (Type) toTypeMap.get(name);
1230: if (result == null) {
1231: return UNKNOWN;
1232: }
1233: return result;
1234: }
1235:
1236: private final static Map toTypeMap; // Map<String, Type>
1237: static {
1238: toTypeMap = new HashMap();
1239: toTypeMap.put("boolean", BOOLEAN);
1240: toTypeMap.put("Boolean", BOOLEAN);
1241: toTypeMap.put("java.lang.Boolean", BOOLEAN);
1242: toTypeMap.put("byte", BYTE);
1243: toTypeMap.put("Byte", BYTE);
1244: toTypeMap.put("java.lang.Byte", BYTE);
1245: toTypeMap.put("int", INT);
1246: toTypeMap.put("Integer", INT);
1247: toTypeMap.put("java.lang.Integer", INT);
1248: toTypeMap.put("long", LONG);
1249: toTypeMap.put("Long", LONG);
1250: toTypeMap.put("java.lang.Long", LONG);
1251: toTypeMap.put("short", SHORT);
1252: toTypeMap.put("Short", SHORT);
1253: toTypeMap.put("java.lang.Short", SHORT);
1254: toTypeMap.put("float", FLOAT);
1255: toTypeMap.put("Float", FLOAT);
1256: toTypeMap.put("java.lang.Float", FLOAT);
1257: toTypeMap.put("double", DOUBLE);
1258: toTypeMap.put("Double", DOUBLE);
1259: toTypeMap.put("java.lang.Double", DOUBLE);
1260: toTypeMap.put("String", STRING);
1261: toTypeMap.put("java.lang.String", STRING);
1262: }
1263:
1264: public void write(Writer out) throws IOException {
1265: throw new UnsupportedOperationException();
1266: }
1267:
1268: public boolean equals(Object o) {
1269: if (o == this )
1270: return true;
1271: if (!(o instanceof Type))
1272: return false;
1273: Type e = (Type) o;
1274: if (!(varName == null ? e.varName == null : varName
1275: .equals(e.varName)))
1276: return false;
1277: return true;
1278: }
1279:
1280: public int hashCode() {
1281: return (varName == null ? 0 : varName.hashCode());
1282: }
1283:
1284: public String toString() {
1285: try {
1286: StringWriter sw = new StringWriter();
1287: write(sw);
1288: return sw.toString();
1289: } catch (IOException e) {
1290: return varName;
1291: } catch (UnsupportedOperationException e) {
1292: return varName;
1293: }
1294: }
1295: }
1296:
1297: /**
1298: * This class mimics javax.microedition.xml.rpc.Element and will
1299: * convert itself into java code that creates that type.
1300: */
1301: protected static class Element extends Type {
1302: private String name;
1303: private QName qName;
1304: private Type type;
1305: private int minOccurs;
1306: private int maxOccurs;
1307: private boolean nillable;
1308: private boolean topLevel;
1309:
1310: protected Element(String varName, String name, QName qName,
1311: Type type, int minOccurs, int maxOccurs,
1312: boolean nillable) {
1313: super (varName);
1314: this .name = name;
1315: this .qName = qName;
1316: if (type == null)
1317: throw new IllegalArgumentException("type == null");
1318: this .type = type;
1319: this .minOccurs = minOccurs;
1320: this .maxOccurs = maxOccurs;
1321: this .nillable = nillable;
1322: }
1323:
1324: public String getClassName() {
1325: return "Element";
1326: }
1327:
1328: public void setVarName(String name) {
1329: varName = name;
1330: }
1331:
1332: public void setTopLevel(boolean value) {
1333: topLevel = value;
1334: }
1335:
1336: public boolean isTopLevel() {
1337: return topLevel;
1338: }
1339:
1340: public QName getQName() {
1341: return qName;
1342: }
1343:
1344: public void write(Writer out) throws IOException {
1345: out.write(varName);
1346: out.write(" = new ");
1347: out.write(getClassName());
1348: out.write("(");
1349: out.write(name);
1350: out.write(", ");
1351: out.write(type.getVarName());
1352: if (minOccurs != 1 || maxOccurs != 1 || nillable != false) {
1353: out.write(", " + minOccurs);
1354: out.write(", " + maxOccurs);
1355: out.write(", " + nillable);
1356: }
1357: out.write(");\n");
1358: }
1359:
1360: /**
1361: * This equals does not take topLevel into account, since toplevel
1362: * is not a value that's reflected in the external data type.
1363: */
1364: public boolean equals(Object o) {
1365: if (o == this )
1366: return true;
1367: if (!(o instanceof Element))
1368: return false;
1369: Element e = (Element) o;
1370: if (!(name == null ? e.name == null : name.equals(e.name)))
1371: return false;
1372: if (!(qName == null ? e.qName == null : qName
1373: .equals(e.qName)))
1374: return false;
1375: if (!(type == null ? e.type == null : type.equals(e.type)))
1376: return false;
1377: if (!(minOccurs == e.minOccurs))
1378: return false;
1379: if (!(maxOccurs == e.maxOccurs))
1380: return false;
1381: if (!(nillable == e.nillable))
1382: return false;
1383: return true;
1384: }
1385:
1386: public int hashCode() {
1387: int result = 17;
1388: result = 37 * result + (name == null ? 0 : name.hashCode());
1389: result = 37 * result
1390: + (qName == null ? 0 : qName.hashCode());
1391: result = 37 * result + (type == null ? 0 : type.hashCode());
1392: result = 37 * result + minOccurs;
1393: result = 37 * result + maxOccurs;
1394: result = 37 * result + (nillable ? 0 : 1);
1395: return result;
1396: }
1397: }
1398:
1399: /**
1400: * This class mimics javax.microedition.xml.rpc.ComplexType and will
1401: * convert itself into java code that creates that type.
1402: */
1403: protected static class ComplexType extends Type {
1404: private List elements; // List<Element>
1405:
1406: protected ComplexType(String varName, List elements) {
1407: super (varName);
1408: this .elements = elements;
1409: }
1410:
1411: public String getClassName() {
1412: return "ComplexType";
1413: }
1414:
1415: public void setVarName(String name) {
1416: varName = name;
1417: }
1418:
1419: public Element getElement(int index) {
1420: return (Element) elements.get(index);
1421: }
1422:
1423: public void write(Writer out) throws IOException {
1424: out.write(varName);
1425: out.write(" = new ");
1426: out.write(getClassName());
1427: out.write("();\n");
1428: out.write(varName);
1429: int size = elements.size();
1430: out.write(".elements = new Element[" + size);
1431: out.write("];\n");
1432: Iterator it = elements.iterator();
1433: for (int elementNum = 0; it.hasNext(); ++elementNum) {
1434: Element e = (Element) it.next();
1435: out.write(varName);
1436: out.write(".elements[" + elementNum);
1437: out.write("] = ");
1438: out.write(e.getVarName());
1439: out.write(";\n");
1440: }
1441: }
1442:
1443: public boolean equals(Object o) {
1444: if (o == this )
1445: return true;
1446: if (!(o instanceof ComplexType))
1447: return false;
1448: ComplexType ct = (ComplexType) o;
1449: if (elements.size() != ct.elements.size())
1450: return false;
1451: for (Iterator it = elements.iterator(), it2 = ct.elements
1452: .iterator(); it.hasNext();) {
1453: Element type = (Element) it.next();
1454: Element type2 = (Element) it2.next();
1455: if (!(type == null ? type2 == null : type.equals(type2)))
1456: return false;
1457: }
1458: return true;
1459: }
1460:
1461: public int hashCode() {
1462: int result = 17;
1463: for (Iterator it = elements.iterator(); it.hasNext();) {
1464: Element type = (Element) it.next();
1465: result = 37 * result
1466: + (type == null ? 0 : type.hashCode());
1467: }
1468: return result;
1469: }
1470: }
1471:
1472: protected Element getElement(QName name, Type type) {
1473: return getElement(name, type, 1, 1, false);
1474: }
1475:
1476: protected Element getElement(QName name, Type type, int minOccurs,
1477: int maxOccurs, boolean nillable) {
1478: String varName;
1479: if (optimize)
1480: varName = "_t";
1481: else
1482: varName = makeVarName(name, "_type_", null);
1483: Element result = new Element(varName, getQNameVar(name), name,
1484: type, minOccurs, maxOccurs, nillable);
1485: if (types.containsKey(result)) {
1486: // It might already be defined.
1487: //System.out.println("type already defined: "+result);
1488: Object o = types.get(result);
1489: // Return the one that was created first.
1490: return (Element) o;
1491: }
1492: // Make sure the name is unique.
1493: varName = makeUniq(varName, typeNames);
1494: result.setVarName(varName);
1495: //System.out.println("new Element: "+result);
1496:
1497: types.put(result, result);
1498: typeNames.put(varName, result);
1499: return result;
1500: }
1501:
1502: protected Element getElement(QName name, Type type,
1503: boolean isArray, boolean nillable, boolean optional) {
1504: return getElement(name, type, optional ? 0 : 1,
1505: isArray ? UNBOUNDED : 1, nillable);
1506: }
1507:
1508: protected ComplexType getComplexType(JavaType type, List elements) {
1509: String name = type.getName();
1510: int pos;
1511: // Remove everything before the .
1512: pos = name.lastIndexOf('.');
1513: if (pos > 0)
1514: name = name.substring(pos + 1, name.length());
1515:
1516: // Get rid of any trailing []
1517: int arrayDimensions = 0;
1518: while (name.endsWith("[]")) {
1519: name = name.substring(0, name.length() - 2);
1520: ++arrayDimensions;
1521: }
1522: for (int i = 0; i < arrayDimensions; ++i)
1523: name += "Array";
1524:
1525: return getComplexType(name, elements);
1526: }
1527:
1528: protected ComplexType getComplexType(String name, List elements) {
1529: String varName;
1530: if (optimize)
1531: varName = "_c";
1532: else
1533: varName = "_complexType_"
1534: + env.getNames().validJavaMemberName(name);
1535: ComplexType result = new ComplexType(varName, elements);
1536: if (types.containsKey(result)) {
1537: // It might already be defined.
1538: //System.out.println("type already defined: "+result);
1539: Object o = types.get(result);
1540: return (ComplexType) o;
1541: }
1542: // Make sure the name is unique.
1543: varName = makeUniq(varName, typeNames);
1544: result.setVarName(varName);
1545: //System.out.println("new ComplexType: "+result);
1546:
1547: types.put(result, result);
1548: typeNames.put(varName, result);
1549: return result;
1550: }
1551:
1552: /**
1553: * Generate code to initialize all of the Type's used by the stub.
1554: */
1555: protected void generateInitTypes() throws IOException {
1556: for (Iterator it = types.keySet().iterator(); it.hasNext();) {
1557: Type type = (Type) it.next();
1558: String varName = type.getVarName();
1559: if (type.isTopLevel()) {
1560: jw.write("protected static final ");
1561: jw.write(type.getClassName());
1562: jw.writeEol(" ", varName);
1563: }
1564: }
1565:
1566: jw.write("static ");
1567: jw.begin();
1568: jw
1569: .comment("Create all of the Type's that this stub uses, once.");
1570: for (Iterator it = types.keySet().iterator(); it.hasNext();) {
1571: Type type = (Type) it.next();
1572: String varName = type.getVarName();
1573: if (!type.isTopLevel())
1574: jw.writeEol(type.getClassName(), " ", varName);
1575: type.write(jw);
1576: }
1577: jw.end();
1578: jw.cr();
1579: }
1580:
1581: /**
1582: * Generate code for the implementation of FaultDetailHandler.
1583: */
1584: protected void generateFaultHandler() throws IOException {
1585: List sortedNames = new ArrayList(faultNames.keySet());
1586: if (sortedNames.size() == 0)
1587: return;
1588: if (faultDetailHandlerIsInnerClass) {
1589: jw.select(jw.DECL_SECTION);
1590: jw
1591: .writeEol("private MyFaultDetailHandler _myFaultDetailHandler = new MyFaultDetailHandler()");
1592: }
1593:
1594: jw.select(jw.BODY_SECTION);
1595:
1596: if (faultDetailHandlerIsInnerClass) {
1597: jw
1598: .write("private static class MyFaultDetailHandler implements FaultDetailHandler ");
1599: jw.begin();
1600: jw.writecr("public MyFaultDetailHandler() {}");
1601: }
1602: jw.write("public Element handleFault(QName name) ");
1603: jw.begin();
1604:
1605: // Make it a stable listing.
1606: Collections.sort(sortedNames, new QNameComparator());
1607: for (Iterator it = sortedNames.iterator(); it.hasNext();) {
1608: Object o = it.next();
1609: QName name = (QName) o;
1610: Type t = (Type) faultNames.get(name);
1611: jw.beginIf("\"" + name.getLocalPart()
1612: + "\".equals(name.getLocalPart()) && \""
1613: + name.getNamespaceURI()
1614: + "\".equals(name.getNamespaceURI())");
1615: jw.writeEol("return " + t.getVarName());
1616: jw.end();
1617: }
1618: jw.writeEol("return null");
1619: jw.end();
1620: if (faultDetailHandlerIsInnerClass) {
1621: jw.end();
1622: }
1623: jw.cr();
1624: }
1625: }
|