blob: 4fb73004b3805a094309c0a325e1fb965fb64d0a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.axis2.wsdl.codegen.emitter;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.description.AxisBinding;
import org.apache.axis2.description.AxisBindingMessage;
import org.apache.axis2.description.AxisBindingOperation;
import org.apache.axis2.description.AxisEndpoint;
import org.apache.axis2.description.AxisMessage;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.description.WSDL20DefaultValueHolder;
import org.apache.axis2.description.WSDL2Constants;
import org.apache.axis2.util.CommandLineOptionConstants;
import org.apache.axis2.util.JavaUtils;
import org.apache.axis2.util.PolicyUtil;
import org.apache.axis2.util.Utils;
import org.apache.axis2.util.XSLTUtils;
import org.apache.axis2.wsdl.HTTPHeaderMessage;
import org.apache.axis2.wsdl.SOAPHeaderMessage;
import org.apache.axis2.wsdl.SOAPModuleMessage;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.axis2.wsdl.WSDLUtil;
import org.apache.axis2.wsdl.codegen.CodeGenConfiguration;
import org.apache.axis2.wsdl.codegen.CodeGenerationException;
import org.apache.axis2.wsdl.codegen.writer.AntBuildWriter;
import org.apache.axis2.wsdl.codegen.writer.CallbackHandlerWriter;
import org.apache.axis2.wsdl.codegen.writer.ExceptionWriter;
import org.apache.axis2.wsdl.codegen.writer.FileWriter;
import org.apache.axis2.wsdl.codegen.writer.InterfaceImplementationWriter;
import org.apache.axis2.wsdl.codegen.writer.InterfaceWriter;
import org.apache.axis2.wsdl.codegen.writer.MessageReceiverWriter;
import org.apache.axis2.wsdl.codegen.writer.SchemaWriter;
import org.apache.axis2.wsdl.codegen.writer.ServiceXMLWriter;
import org.apache.axis2.wsdl.codegen.writer.SkeletonInterfaceWriter;
import org.apache.axis2.wsdl.codegen.writer.SkeletonWriter;
import org.apache.axis2.wsdl.codegen.writer.TestClassWriter;
import org.apache.axis2.wsdl.codegen.writer.WSDL11Writer;
import org.apache.axis2.wsdl.codegen.writer.WSDL20Writer;
import org.apache.axis2.wsdl.databinding.TypeMapper;
import org.apache.axis2.wsdl.util.Constants;
import org.apache.axis2.wsdl.util.MessagePartInformationHolder;
import org.apache.axis2.wsdl.util.TypeTesterUtil;
import org.apache.axis2.wsdl.util.XSLTIncludeResolver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.neethi.Policy;
import org.apache.ws.commons.schema.XmlSchema;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.lang.reflect.Constructor;
public class AxisServiceBasedMultiLanguageEmitter implements Emitter {
protected static final String CALL_BACK_HANDLER_SUFFIX = "CallbackHandler";
protected static final String STUB_SUFFIX = "Stub";
protected static final String TEST_SUFFIX = "Test";
protected static final String SKELETON_CLASS_SUFFIX = "Skeleton";
protected static final String SKELETON_CLASS_SUFFIX_BACK = "Impl";
protected static final String SKELETON_INTERFACE_SUFFIX = "SkeletonInterface";
// keep a seperate variable for SKELETON_INTERFACE_SUFFIX_BACK although it is
// "" to accomadate any future changes easily.
protected static final String SKELETON_INTERFACE_SUFFIX_BACK = "";
protected static final String STUB_INTERFACE_SUFFIX_BACK = "Stub";
protected static final String MESSAGE_RECEIVER_SUFFIX = "MessageReceiver";
protected static final String DATABINDING_SUPPORTER_NAME_SUFFIX = "DatabindingSupporter";
protected static Map mepToClassMap;
protected static Map mepToSuffixMap;
protected AxisBinding axisBinding;
protected AxisEndpoint axisEndpoint;
protected int uniqueFaultNameCounter = 0;
/**
* Field constructorMap
*/
protected static HashMap constructorMap = new HashMap(50);
//~--- static initializers ------------------------------------------------
static {
// Type maps to a valid initialization value for that type
// Type var = new Type(arg)
// Where "Type" is the key and "new Type(arg)" is the string stored
// Used in emitting test cases and server skeletons.
constructorMap.put("int", "0");
constructorMap.put("float", "0");
constructorMap.put("boolean", "true");
constructorMap.put("double", "0");
constructorMap.put("byte", "(byte)0");
constructorMap.put("short", "(short)0");
constructorMap.put("long", "0");
constructorMap.put("java.lang.Boolean", "new java.lang.Boolean(false)");
constructorMap.put("java.lang.Byte", "new java.lang.Byte((byte)0)");
constructorMap.put("java.lang.Double", "new java.lang.Double(0)");
constructorMap.put("java.lang.Float", "new java.lang.Float(0)");
constructorMap.put("java.lang.Integer", "new java.lang.Integer(0)");
constructorMap.put("java.lang.Long", "new java.lang.Long(0)");
constructorMap.put("java.lang.Short", "new java.lang.Short((short)0)");
constructorMap.put("java.math.BigDecimal", "new java.math.BigDecimal(0)");
constructorMap.put("java.math.BigInteger", "new java.math.BigInteger(\"0\")");
constructorMap.put("java.lang.Object", "new java.lang.String()");
constructorMap.put("byte[]", "new byte[0]");
constructorMap.put("java.util.Calendar", "java.util.Calendar.getInstance()");
constructorMap.put("javax.xml.namespace.QName",
"new javax.xml.namespace.QName(\"http://foo\", \"bar\")");
//populate the MEP -> class map
mepToClassMap = new HashMap();
mepToClassMap.put(WSDL2Constants.MEP_URI_IN_ONLY,
"org.apache.axis2.receivers.AbstractInMessageReceiver");
mepToClassMap.put(WSDL2Constants.MEP_URI_ROBUST_IN_ONLY,
"org.apache.axis2.receivers.AbstractMessageReceiver");
mepToClassMap.put(WSDL2Constants.MEP_URI_IN_OUT,
"org.apache.axis2.receivers.AbstractInOutMessageReceiver");
//populate the MEP -> suffix map
mepToSuffixMap = new HashMap();
mepToSuffixMap.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_IN_ONLY,
MESSAGE_RECEIVER_SUFFIX + "InOnly");
mepToSuffixMap.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_IN_ONLY,
MESSAGE_RECEIVER_SUFFIX + "InOnly");
mepToSuffixMap.put(WSDL2Constants.MEP_URI_IN_ONLY,
MESSAGE_RECEIVER_SUFFIX + "InOnly");
mepToSuffixMap.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_ROBUST_IN_ONLY,
MESSAGE_RECEIVER_SUFFIX + "RobustInOnly");
mepToSuffixMap.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_ROBUST_IN_ONLY,
MESSAGE_RECEIVER_SUFFIX + "RobustInOnly");
mepToSuffixMap.put(WSDL2Constants.MEP_URI_ROBUST_IN_ONLY,
MESSAGE_RECEIVER_SUFFIX + "RobustInOnly");
mepToSuffixMap.put(WSDLConstants.WSDL20_2004_Constants.MEP_URI_IN_OUT,
MESSAGE_RECEIVER_SUFFIX + "InOut");
mepToSuffixMap.put(WSDLConstants.WSDL20_2006Constants.MEP_URI_IN_OUT,
MESSAGE_RECEIVER_SUFFIX + "InOut");
mepToSuffixMap.put(WSDL2Constants.MEP_URI_IN_OUT,
MESSAGE_RECEIVER_SUFFIX + "InOut");
//register the other types as necessary
}
//~--- fields -------------------------------------------------------------
protected static final Log log = LogFactory.getLog(AxisServiceBasedMultiLanguageEmitter.class);
protected URIResolver resolver;
// this is used to keep the current service infoHolder
protected Map infoHolder;
// this is used to keep infoHolders for all services
protected Map allServiceInfoHolder;
protected CodeGenConfiguration codeGenConfiguration;
protected TypeMapper mapper;
protected AxisService axisService;
protected List axisServices;
//a map to keep the fault classNames
protected Map fullyQualifiedFaultClassNameMap = new HashMap();
protected Map faultClassNameMap = new HashMap();
protected Map faultElementQNameMap = new HashMap();
protected Map instantiatableMessageClassNames = new HashMap();
protected static final String TEST_SRC_DIR_NAME = "test";
protected boolean useHolderClass_jaxws = false;
protected boolean wrapped_jaxws = false;
/**
* default constructor - builds
*/
public AxisServiceBasedMultiLanguageEmitter() {
infoHolder = new HashMap();
allServiceInfoHolder = new HashMap();
}
/**
* Sets the relevant codegen configuration
*
* @param configuration
* @see Emitter#setCodeGenConfiguration(org.apache.axis2.wsdl.codegen.CodeGenConfiguration)
*/
public void setCodeGenConfiguration(CodeGenConfiguration configuration) {
this.codeGenConfiguration = configuration;
this.axisServices = codeGenConfiguration.getAxisServices();
this.axisService = codeGenConfiguration.getAxisService();
this.axisEndpoint = axisService.getEndpoint(axisService.getEndpointName());
this.axisBinding = axisEndpoint.getBinding();
resolver = new XSLTIncludeResolver(codeGenConfiguration);
}
/**
* Sets the type mapper
*
* @param mapper
* @see Emitter#setMapper(org.apache.axis2.wsdl.databinding.TypeMapper)
*/
public void setMapper(TypeMapper mapper) {
this.mapper = mapper;
}
protected Object getBindingPropertyFromOperation(String name, QName qName) {
// Get the correct AxisBindingOperation coresponding to the AxisOperation
AxisBindingOperation axisBindingOperation = null;
if (axisBinding != null) {
axisBindingOperation = (AxisBindingOperation) axisBinding.getChild(qName);
}
Object property = null;
if (axisBindingOperation != null) {
property = axisBindingOperation.getProperty(name);
}
if ((property == null) && (axisBinding != null)) {
property = axisBinding.getProperty(name);
}
if (property == null) {
property = WSDL20DefaultValueHolder.getDefaultValue(name);
}
return property;
}
protected Policy getBindingPolicyFromMessage(AxisBindingOperation axisBindingOperation,
String key) {
AxisBindingMessage axisBindingMessage = null;
if (axisBindingOperation != null) {
axisBindingMessage = (AxisBindingMessage) axisBindingOperation.getChild(key);
if (axisBindingMessage != null) {
try {
return axisBindingMessage.getEffectivePolicy();
} catch (RuntimeException ex){
log.error(ex.getMessage(), ex);
}
}
}
return null;
}
protected Object getBindingPropertyFromMessage(String name, QName qName, String key) {
Object property = null;
// Get the correct AxisBindingOperation coresponding to the AxisOperation
AxisBindingOperation axisBindingOperation = null;
if (axisBinding != null) {
axisBindingOperation = (AxisBindingOperation) axisBinding.getChild(qName);
}
AxisBindingMessage axisBindingMessage = null;
if (axisBindingOperation != null) {
axisBindingMessage = (AxisBindingMessage) axisBindingOperation.getChild(key);
if (axisBindingMessage != null) {
property = axisBindingMessage.getProperty(name);
}
if (property == null) {
property = axisBindingOperation.getProperty(name);
}
}
if ((property == null) && (axisBinding != null)) {
property = axisBinding.getProperty(name);
}
if (property == null) {
property = WSDL20DefaultValueHolder.getDefaultValue(name);
}
return property;
}
protected Object getBindingPropertyFromMessageFault(String name, QName qName, String key) {
Object property = null;
// Get the correct AxisBindingOperation coresponding to the AxisOperation
AxisBindingOperation axisBindingOperation =
(AxisBindingOperation) axisBinding.getChild(qName);
AxisBindingMessage axisBindingMessageFault = null;
AxisBindingMessage axisBindingFault = null;
if (axisBindingOperation != null) {
axisBindingMessageFault = (AxisBindingMessage) axisBindingOperation.getFault(key);
if (axisBindingMessageFault != null) {
property = axisBindingMessageFault.getProperty(name);
}
if (property == null) {
axisBindingFault = axisBinding.getFault(key);
property = axisBindingFault.getProperty(name);
}
}
if (property == null) {
property = WSDL20DefaultValueHolder.getDefaultValue(name);
}
return property;
}
/**
* Update mapper for the stub
*/
protected void updateMapperForStub() {
updateMapperClassnames(getFullyQualifiedStubName());
}
/**
* Returns the fully qualified Stub name reused in many methods
*
* @return classname
*/
protected String getFullyQualifiedStubName() {
String packageName = codeGenConfiguration.getPackageName();
String localPart = null;
if (this.axisService.getEndpoints().size() > 1) {
localPart = makeJavaClassName(axisService.getName() + axisService.getEndpointName());
} else {
localPart = makeJavaClassName(axisService.getName());
}
return packageName + "." + localPart + STUB_SUFFIX;
}
/**
* rests the fault name maps
*/
protected void resetFaultNames() {
fullyQualifiedFaultClassNameMap.clear();
faultClassNameMap.clear();
faultElementQNameMap.clear();
}
/**
* Populate a map of fault class names
*/
protected void generateAndPopulateFaultNames() {
//loop through and find the faults
Iterator operations = axisService.getOperations();
AxisOperation operation;
AxisMessage faultMessage;
while (operations.hasNext()) {
operation = (AxisOperation) operations.next();
ArrayList faultMessages = operation.getFaultMessages();
for (int i = 0; i < faultMessages.size(); i++) {
faultMessage = (AxisMessage) faultMessages.get(i);
//make a unique name and put that in the hashmap
if (!fullyQualifiedFaultClassNameMap.
containsKey(faultMessage.getName())) {
//make a name
String className = makeJavaClassName(faultMessage.getName());
QName faultQName = new QName(codeGenConfiguration.getTargetNamespace(), faultMessage.getName());
if (this.mapper.getQNameToMappingObject(faultQName) != null) {
// i.e we already have an entry
className = makeJavaClassName(className + "Exception");
}
while (fullyQualifiedFaultClassNameMap.containsValue(className)) {
className = makeJavaClassName(className + (uniqueFaultNameCounter++));
}
fullyQualifiedFaultClassNameMap.put(
faultMessage.getName(),
className);
//we've to keep track of the fault base names seperately
faultClassNameMap.put(faultMessage.getName(),
className);
faultElementQNameMap.put(faultMessage.getName(),
faultMessage.getElementQName());
}
}
}
}
/**
* Emits the stubcode with bindings.
*
* @throws CodeGenerationException
* @see Emitter#emitStub()
*/
public void emitStub() throws CodeGenerationException {
try {
//first keep a seperate copy of the original map to use in
// every iteration
// for every iteration qName2NameMap is changed in updateMapperForStub
// method if in the packing mode
Map originalTypeMap = getNewCopy(mapper.getAllMappedNames());
for (Iterator axisServicesIter = this.axisServices.iterator();
axisServicesIter.hasNext();) {
this.axisService = (AxisService) axisServicesIter.next();
//we have to generate the code for each bininding
//for the moment lets genrate the stub name with the service name and end point name
this.axisBinding = axisService.getEndpoint(axisService.getEndpointName()).getBinding();
if (!codeGenConfiguration.isPackClasses()) {
// write the call back handlers
writeCallBackHandlers();
}
Map endpoints = this.axisService.getEndpoints();
for (Iterator endPointsIter = endpoints.values().iterator();
endPointsIter.hasNext();) {
// set the end point details.
this.axisEndpoint = (AxisEndpoint) endPointsIter.next();
this.axisBinding = this.axisEndpoint.getBinding();
axisService.setEndpointName(this.axisEndpoint.getName());
axisService.setBindingName(
this.axisEndpoint.getBinding().getName().getLocalPart());
// see the comment at updateMapperClassnames for details and reasons for
// calling this method
if (mapper.isObjectMappingPresent()) {
// initialize the map to original one
copyMap(originalTypeMap, mapper.getAllMappedNames());
updateMapperForStub();
} else {
copyToFaultMap();
}
//generate and populate the fault names before hand. We need that for
//the smooth opration of the thing
//first reset the fault names and recreate it
resetFaultNames();
generateAndPopulateFaultNames();
updateFaultPackageForStub();
// write the inteface
// feed the binding information also
// note that we do not create this interface if the user switched on the wrap classes mode
// this interface also depends on the binding
if (!codeGenConfiguration.isPackClasses()) {
writeInterface(false);
}
if (codeGenConfiguration.isPackClasses()) {
// write the call back handlers
writeCallBackHandlers();
}
// write the Exceptions
writeExceptions();
// write interface implementations
writeInterfaceImplementation();
// write the test classes
writeTestClasses();
}
}
// save back type map
if (this.mapper.isObjectMappingPresent()) {
copyMap(originalTypeMap, this.mapper.getAllMappedNames());
}
if (!codeGenConfiguration.isSkipBuildXML()) {
// write an ant build file
// Note that ant build is generated only once
// and that has to happen here only if the
// client side code is required
if (!codeGenConfiguration.isGenerateAll()) {
//our logic for the build xml is that it will
//only be written when not flattened
if (!codeGenConfiguration.isFlattenFiles()) {
writeAntBuild();
}
}
}
} catch (CodeGenerationException ce) {
throw ce;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
public Map getNewCopy(Map copyFormMap) {
Map copyToMap = new HashMap();
Object key;
for (Iterator iter = copyFormMap.keySet().iterator(); iter.hasNext();) {
key = iter.next();
copyToMap.put(key, copyFormMap.get(key));
}
return copyToMap;
}
public void copyMap(Map copyFormMap, Map copyToMap) {
Object key;
for (Iterator iter = copyFormMap.keySet().iterator(); iter.hasNext();) {
key = iter.next();
copyToMap.put(key, copyFormMap.get(key));
}
}
/**
* Writes the Ant build.
*
* @throws Exception
*/
protected void writeAntBuild() throws Exception {
// Write the service xml in a folder with the
Document skeletonModel = createDOMDocumentForAntBuild();
debugLogDocument("Document for ant build:", skeletonModel);
AntBuildWriter antBuildWriter = new AntBuildWriter(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getOutputLanguage());
antBuildWriter.setDatabindingFramework(codeGenConfiguration.getDatabindingType());
antBuildWriter.setOverride(codeGenConfiguration.isOverride());
writeFile(skeletonModel, antBuildWriter);
codeGenConfiguration.addXmlFileName(antBuildWriter.getOutputFile().getAbsolutePath());//$NON-SEC-3
}
/**
* Creates the DOM tree for the Ant build. Uses the interface.
*/
protected Document createDOMDocumentForAntBuild() {
Document doc = getEmptyDocument();
Element rootElement = doc.createElement("ant");
String serviceName = makeJavaClassName(axisService.getName());
String packageName = codeGenConfiguration.getPackageName();
String[] dotSeparatedValues = packageName.split("\\.");
addAttribute(doc, "package", dotSeparatedValues[0], rootElement);
addAttribute(doc, "name", serviceName, rootElement);
addAttribute(doc, "servicename", serviceName, rootElement);
addAttribute(doc, "src", codeGenConfiguration.getSourceLocation(), rootElement);
addAttribute(doc, "resource", codeGenConfiguration.getResourceLocation(), rootElement);
if (codeGenConfiguration.getAxisServices().size() > 1){
addAttribute(doc, "artifactname", "Services", rootElement);
} else {
addAttribute(doc, "artifactname", this.axisService.getName() , rootElement);
}
if (!codeGenConfiguration.isWriteTestCase()) {
addAttribute(doc, "testOmit", "true", rootElement);
}
if (codeGenConfiguration.isServerSide()) {
addAttribute(doc,
"isserverside",
"yes",
rootElement);
}
doc.appendChild(rootElement);
//////////////////////////////////////////////////////////
// System.out.println(DOM2Writer.nodeToString(rootElement));
////////////////////////////////////////////////////////////
return doc;
}
/**
* Write the test classes
*/
protected void writeTestClasses() throws Exception {
if (codeGenConfiguration.isWriteTestCase()) {
Document classModel = createDOMDocumentForTestCase();
debugLogDocument("Document for test case:", classModel);
TestClassWriter callbackWriter =
new TestClassWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
TEST_SRC_DIR_NAME),
codeGenConfiguration.getOutputLanguage());
callbackWriter.setOverride(codeGenConfiguration.isOverride());
writeFile(classModel, callbackWriter);
}
}
/**
* Creates the XML Model for the test case
*
* @return DOM document
*/
protected Document createDOMDocumentForTestCase() {
String coreClassName = makeJavaClassName(axisService.getName());
Document doc = getEmptyDocument();
Element rootElement = doc.createElement("class");
addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
if (this.axisService.getEndpoints().size() > 1) {
addAttribute(doc, "name",
makeJavaClassName(axisService.getName() + axisService.getEndpointName())
+ TEST_SUFFIX, rootElement);
} else {
addAttribute(doc, "name", makeJavaClassName(axisService.getName())
+ TEST_SUFFIX, rootElement);
}
//todo is this right ???
addAttribute(doc, "namespace", axisService.getTargetNamespace(), rootElement);
addAttribute(doc, "interfaceName", coreClassName, rootElement);
if (codeGenConfiguration.isPackClasses()) {
if (this.axisService.getEndpoints().size() > 1) {
addAttribute(doc, "callbackname", makeJavaClassName(
axisService.getName() + axisService.getEndpointName())
+ CALL_BACK_HANDLER_SUFFIX, rootElement);
} else {
addAttribute(doc, "callbackname", makeJavaClassName(axisService.getName())
+ CALL_BACK_HANDLER_SUFFIX, rootElement);
}
} else {
addAttribute(doc, "callbackname", coreClassName + CALL_BACK_HANDLER_SUFFIX,
rootElement);
}
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
addAttribute(doc, "stubname",
makeJavaClassName(axisService.getBindingName()) + STUB_SUFFIX,
rootElement);
} else {
if (this.axisService.getEndpoints().size() > 1) {
addAttribute(doc, "stubname", makeJavaClassName(
axisService.getName() + axisService.getEndpointName())
+ STUB_SUFFIX, rootElement);
} else {
addAttribute(doc, "stubname", makeJavaClassName(axisService.getName())
+ STUB_SUFFIX, rootElement);
}
}
//add backwordcompatibility attribute
addAttribute(doc, "isbackcompatible",
String.valueOf(codeGenConfiguration.isBackwordCompatibilityMode()),
rootElement);
fillSyncAttributes(doc, rootElement);
loadOperations(doc, rootElement, null);
// add the databind supporters. Now the databind supporters are completly contained inside
// the stubs implementation and not visible outside
rootElement.appendChild(createDOMElementforDatabinders(doc, false));
doc.appendChild(rootElement);
//////////////////////////////////////////////////////////
// System.out.println(DOM2Writer.nodeToString(rootElement));
////////////////////////////////////////////////////////////
return doc;
}
/**
* Writes the implementations.
*
* @throws Exception
*/
protected void writeInterfaceImplementation() throws Exception {
// first check for the policies in this service and write them
Document interfaceImplModel = createDOMDocumentForInterfaceImplementation();
debugLogDocument("Document for interface implementation:", interfaceImplModel);
InterfaceImplementationWriter writer =
new InterfaceImplementationWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(), null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getSourceLocation()),
codeGenConfiguration.getOutputLanguage());
writer.setOverride(codeGenConfiguration.isOverride());
writeFile(interfaceImplModel, writer);
}
/**
* Creates the DOM tree for implementations.
*/
protected Document createDOMDocumentForInterfaceImplementation() throws Exception {
String packageName = codeGenConfiguration.getPackageName();
String localPart = makeJavaClassName(axisService.getName());
String stubName = makeJavaClassName(axisService.getName() + axisService.getEndpointName()) +
STUB_SUFFIX;
Document doc = getEmptyDocument();
Element rootElement = doc.createElement("class");
addAttribute(doc, "package", packageName, rootElement);
addAttribute(doc, "servicename", localPart, rootElement);
//The target nemespace is added as the namespace for this service
addAttribute(doc, "namespace", axisService.getTargetNamespace(), rootElement);
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
addAttribute(doc, "interfaceName",
makeJavaClassName(axisService.getEndpointName()) +
STUB_INTERFACE_SUFFIX_BACK,
rootElement);
addAttribute(doc, "name", makeJavaClassName(axisService.getBindingName()) + STUB_SUFFIX,
rootElement);
} else {
if (this.axisService.getEndpoints().size() > 1) {
addAttribute(doc, "interfaceName",
makeJavaClassName(
axisService.getName() + axisService.getEndpointName()),
rootElement);
addAttribute(doc, "name", stubName, rootElement);
} else {
addAttribute(doc, "interfaceName",
makeJavaClassName(axisService.getName()),
rootElement);
addAttribute(doc, "name", makeJavaClassName(axisService.getName()) + STUB_SUFFIX,
rootElement);
}
}
if (codeGenConfiguration.isPackClasses()) {
if (this.axisService.getEndpoints().size() > 1) {
addAttribute(doc, "callbackname",
makeJavaClassName(
axisService.getName() + axisService.getEndpointName()) +
CALL_BACK_HANDLER_SUFFIX, rootElement);
} else {
addAttribute(doc, "callbackname",
makeJavaClassName(axisService.getName()) +
CALL_BACK_HANDLER_SUFFIX, rootElement);
}
} else {
addAttribute(doc, "callbackname", localPart + CALL_BACK_HANDLER_SUFFIX, rootElement);
}
//add backwordcompatibility attribute
addAttribute(doc, "isbackcompatible",
String.valueOf(codeGenConfiguration.isBackwordCompatibilityMode()),
rootElement);
// add the wrap classes flag
if (codeGenConfiguration.isPackClasses()) {
addAttribute(doc, "wrapped", "yes", rootElement);
}
// add SOAP version
addSoapVersion(doc, rootElement);
// add the end point
addEndpoint(doc, rootElement);
// set the sync/async attributes
fillSyncAttributes(doc, rootElement);
// ###########################################################################################
// this block of code specifically applies to the integration of databinding code into the
// generated classes tightly (probably as inner classes)
// ###########################################################################################
// check for the special models in the mapper and if they are present process them
if (mapper.isObjectMappingPresent()) {
// add an attribute to the root element showing that the writing has been skipped
addAttribute(doc, "skip-write", "yes", rootElement);
// process the mapper objects
processModelObjects(mapper.getAllMappedObjects(), rootElement, doc);
}
// #############################################################################################
// load the operations
loadOperations(doc, rootElement, null);
// add the databind supporters. Now the databind supporters are completly contained inside
// the stubs implementation and not visible outside
rootElement.appendChild(createDOMElementforDatabinders(doc, false));
Object moduleCodegenPolicyExtensionElement;
//if some extension has added the stub methods property, add them to the
//main document
if ((moduleCodegenPolicyExtensionElement =
codeGenConfiguration.getProperty("module-codegen-policy-extensions")) != null) {
rootElement.appendChild(
doc.importNode((Element) moduleCodegenPolicyExtensionElement, true));
}
//add another element to have the unique list of faults
rootElement.appendChild(getUniqueListofFaults(doc));
doc.appendChild(rootElement);
//////////////////////////////////////////////////////////
// System.out.println(DOM2Writer.nodeToString(rootElement));
////////////////////////////////////////////////
return doc;
}
/**
* A util method that returns a unique list of faults
*
* @param doc
* @return DOM element
*/
protected Element getUniqueListofFaults(Document doc) {
Element rootElement = doc.createElement("fault-list");
Element faultElement;
String key;
Iterator iterator = fullyQualifiedFaultClassNameMap.keySet().iterator();
while (iterator.hasNext()) {
faultElement = doc.createElement("fault");
key = (String) iterator.next();
//as for the name of a fault, we generate an exception
addAttribute(doc, "name",
(String) fullyQualifiedFaultClassNameMap.get(key),
faultElement);
addAttribute(doc, "shortName",
(String) faultClassNameMap.get(key),
faultElement);
//the type represents the type that will be wrapped by this
//name
String typeMapping =
this.mapper.getTypeMappingName((QName) faultElementQNameMap.get(key));
addAttribute(doc, "type", (typeMapping == null)
? ""
: typeMapping, faultElement);
String attribValue = (String) instantiatableMessageClassNames.
get(key);
addAttribute(doc, "instantiatableType",
attribValue == null ? "" : attribValue,
faultElement);
// add an extra attribute to say whether the type mapping is
// the default
if (mapper.getDefaultMappingName().equals(typeMapping)) {
addAttribute(doc, "default", "yes", faultElement);
}
addAttribute(doc, "value", getParamInitializer(typeMapping),
faultElement);
rootElement.appendChild(faultElement);
}
return rootElement;
}
/**
* add the qNames of the operation fault message names to faultMessages Mep
*
* @param operationFaultMessages
* @param faultMessagesToMep
*/
protected void addFaultMessages(List operationFaultMessages, Set faultMessagesToMep) {
AxisMessage faultMessage;
for (Iterator iter = operationFaultMessages.iterator(); iter.hasNext();) {
faultMessage = (AxisMessage) iter.next();
faultMessagesToMep.add(faultMessage.getName());
}
}
/**
* A util method that returns a unique list of faults for a given mep
*
* @param doc
* @return DOM element
*/
protected Element getUniqueListofFaultsofMep(Document doc, String mep) {
// list to keep fault message qnames for this mep
Set faultListForMep = new HashSet();
Iterator iter = this.axisService.getOperations();
AxisOperation axisOperation;
for (; iter.hasNext();) {
axisOperation = (AxisOperation) iter.next();
if (mep == null) {
// add the fault messages
addFaultMessages(axisOperation.getFaultMessages(), faultListForMep);
} else {
if (mep.equals(axisOperation.getMessageExchangePattern())) {
// add the fault messages
addFaultMessages(axisOperation.getFaultMessages(), faultListForMep);
}
}
}
Element rootElement = doc.createElement("fault-list");
Element faultElement;
String key;
Iterator iterator = faultListForMep.iterator();
while (iterator.hasNext()) {
faultElement = doc.createElement("fault");
key = (String) iterator.next();
//as for the name of a fault, we generate an exception
addAttribute(doc, "name",
(String) fullyQualifiedFaultClassNameMap.get(key),
faultElement);
addAttribute(doc, "shortName",
(String) faultClassNameMap.get(key),
faultElement);
//the type represents the type that will be wrapped by this
//name
String typeMapping =
this.mapper.getTypeMappingName((QName) faultElementQNameMap.get(key));
addAttribute(doc, "type", (typeMapping == null)
? ""
: typeMapping, faultElement);
String attribValue = (String) instantiatableMessageClassNames.
get(key);
addAttribute(doc, "instantiatableType",
attribValue == null ? "" : attribValue,
faultElement);
String exceptionName = ((QName) faultElementQNameMap.get(key)).getLocalPart();
addAttribute(doc, "localname",
exceptionName == null ? "" : exceptionName,
faultElement);
// add an extra attribute to say whether the type mapping is
// the default
if (mapper.getDefaultMappingName().equals(typeMapping)) {
addAttribute(doc, "default", "yes", faultElement);
}
addAttribute(doc, "value", getParamInitializer(typeMapping),
faultElement);
rootElement.appendChild(faultElement);
}
return rootElement;
}
/**
* Adds the endpoint to the document.
*
* @param doc
* @param rootElement
*/
protected void addEndpoint(Document doc, Element rootElement) throws Exception {
Element endpointElement = doc.createElement("endpoint");
String endpoint = this.axisEndpoint.getEndpointURL();
Text text = doc.createTextNode((endpoint != null)
? endpoint
: "");
endpointElement.appendChild(text);
rootElement.appendChild(endpointElement);
}
/**
* Looks for the SOAPVersion and adds it.
*
* @param doc
* @param rootElement
*/
protected void addSoapVersion(Document doc, Element rootElement) {
// loop through the extensibility elements to get to the bindings element
addAttribute(doc, "soap-version",
(String) axisBinding.getProperty(WSDL2Constants.ATTR_WSOAP_VERSION),
rootElement);
}
/**
* Writes the exceptions.
*/
protected void writeExceptions() throws Exception {
Element faultElement;
String key;
Iterator iterator = fullyQualifiedFaultClassNameMap.keySet().iterator();
while (iterator.hasNext()) {
Document doc = getEmptyDocument();
faultElement = doc.createElement("fault");
addAttribute(doc, "package", codeGenConfiguration.getPackageName(), faultElement);
key = (String) iterator.next();
//as for the name of a fault, we generate an exception
addAttribute(doc, "name",
(String) faultClassNameMap.get(key),
faultElement);
addAttribute(doc, "shortName",
(String) faultClassNameMap.get(key),
faultElement);
//added the base exception class name
if (this.codeGenConfiguration.getExceptionBaseClassName() != null) {
addAttribute(doc, "exceptionBaseClass",
this.codeGenConfiguration.getExceptionBaseClassName(), faultElement);
try {
addConstructorDetails(doc, faultElement, this.codeGenConfiguration.getExceptionBaseClassName());
} catch (ClassNotFoundException e) {
log.warn("Can not load the Exception base class");
}
} else {
addAttribute(doc, "exceptionBaseClass", Exception.class.getName(), faultElement);
}
//the type represents the type that will be wrapped by this
//name
String typeMapping =
this.mapper.getTypeMappingName((QName) faultElementQNameMap.get(key));
addAttribute(doc, "type", (typeMapping == null)
? ""
: typeMapping, faultElement);
String attribValue = (String) instantiatableMessageClassNames.
get(key);
addAttribute(doc, "instantiatableType",
attribValue == null ? "" : attribValue,
faultElement);
// add an extra attribute to say whether the type mapping is
// the default
if (mapper.getDefaultMappingName().equals(typeMapping)) {
addAttribute(doc, "default", "yes", faultElement);
}
addAttribute(doc, "value", getParamInitializer(typeMapping),
faultElement);
ExceptionWriter exceptionWriter =
new ExceptionWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getSourceLocation()),
codeGenConfiguration.getOutputLanguage());
doc.appendChild(faultElement);
//////////////////////////////////////////////////////////
// System.out.println(DOM2Writer.nodeToString(doc));
////////////////////////////////////////////////////////////
exceptionWriter.setOverride(codeGenConfiguration.isOverride());
writeFile(doc, exceptionWriter);
}
}
private void addConstructorDetails(Document doc,
Element faultElement,
String exceptionClassName) throws ClassNotFoundException {
Class exceptionClass = Class.forName(exceptionClassName);
Constructor[] constructors = exceptionClass.getConstructors();
for (int i = 0; i < constructors.length; i++) {
Element constructorElement = doc.createElement("constructor");
faultElement.appendChild(constructorElement);
Class[] parameters = constructors[i].getParameterTypes();
List existingParamNames = new ArrayList();
for (int j = 0; j < parameters.length; j++){
Element parameterElement = doc.createElement("param");
constructorElement.appendChild(parameterElement);
addAttribute(doc, "type",
getTypeName(parameters[j]), parameterElement);
addAttribute(doc, "name",
getParameterName(parameters[j], existingParamNames), parameterElement);
}
}
}
private String getParameterName(Class type, List existingParamNames) {
String paramName = null;
if (type.isArray()) {
paramName = getParameterName(type.getComponentType(), existingParamNames);
} else {
String className = type.getName();
if (className.lastIndexOf(".") > 0) {
className = className.substring(className.lastIndexOf(".") + 1);
}
paramName = JavaUtils.xmlNameToJavaIdentifier(className);
if (existingParamNames.contains(paramName)){
paramName = paramName + existingParamNames.size();
}
existingParamNames.add(paramName);
}
return paramName;
}
private String getTypeName(Class type){
String typeName = null;
if (type.isArray()){
typeName = getTypeName(type.getComponentType()) + "[]";
} else {
typeName = type.getName();
}
return typeName;
}
/**
* Generates the model for the callbacks.
*/
protected Document createDOMDocumentForException() {
Document doc = getEmptyDocument();
Element rootElement = doc.createElement("callback");
addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
addAttribute(doc, "name",
makeJavaClassName(axisService.getName()) + CALL_BACK_HANDLER_SUFFIX,
rootElement);
// TODO JAXRPC mapping support should be considered here ??
this.loadOperations(doc, rootElement, null);
doc.appendChild(rootElement);
return doc;
}
/**
* Writes the callback handlers.
*/
protected void writeCallBackHandlers() throws Exception {
if (codeGenConfiguration.isAsyncOn()) {
Document interfaceModel = createDOMDocumentForCallbackHandler();
debugLogDocument("Document for callback handler:", interfaceModel);
CallbackHandlerWriter callbackWriter =
new CallbackHandlerWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getSourceLocation()),
codeGenConfiguration.getOutputLanguage());
callbackWriter.setOverride(codeGenConfiguration.isOverride());
writeFile(interfaceModel, callbackWriter);
}
}
/**
* Generates the model for the callbacks.
*/
protected Document createDOMDocumentForCallbackHandler() {
Document doc = getEmptyDocument();
Element rootElement = doc.createElement("callback");
addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
if (codeGenConfiguration.isPackClasses() && this.axisService.getEndpoints().size() > 1) {
addAttribute(doc, "name",
makeJavaClassName(axisService.getName() + axisService.getEndpointName())
+ CALL_BACK_HANDLER_SUFFIX, rootElement);
} else {
addAttribute(doc, "name",
makeJavaClassName(axisService.getName()) + CALL_BACK_HANDLER_SUFFIX,
rootElement);
}
// TODO JAXRPC mapping support should be considered here ??
this.loadOperations(doc, rootElement, null);
doc.appendChild(rootElement);
return doc;
}
/**
* Writes the interfaces.
*
* @throws Exception
*/
protected void writeInterface(boolean writeDatabinders) throws Exception {
Document interfaceModel = createDOMDocumentForInterface(writeDatabinders);
debugLogDocument("Document for interface:", interfaceModel);
InterfaceWriter interfaceWriter =
new InterfaceWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(), null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getSourceLocation()),
this.codeGenConfiguration.getOutputLanguage());
interfaceWriter.setOverride(codeGenConfiguration.isOverride());
writeFile(interfaceModel, interfaceWriter);
}
/**
* Creates the DOM tree for the interface creation. Uses the interface.
*/
protected Document createDOMDocumentForInterface(boolean writeDatabinders) {
Document doc = getEmptyDocument();
Element rootElement = doc.createElement("interface");
String localPart = null;
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
localPart =
makeJavaClassName(axisService.getEndpointName() + STUB_INTERFACE_SUFFIX_BACK);
} else {
if (this.axisService.getEndpoints().size() > 1) {
localPart =
makeJavaClassName(axisService.getName() + axisService.getEndpointName());
} else {
localPart = makeJavaClassName(axisService.getName());
}
}
addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
addAttribute(doc, "name", localPart, rootElement);
addAttribute(doc, "callbackname",
makeJavaClassName(axisService.getName()) + CALL_BACK_HANDLER_SUFFIX,
rootElement);
//add backwordcompatibility attribute
addAttribute(doc, "isbackcompatible",
String.valueOf(codeGenConfiguration.isBackwordCompatibilityMode()),
rootElement);
fillSyncAttributes(doc, rootElement);
loadOperations(doc, rootElement, null);
// ###########################################################################################
// this block of code specifically applies to the integration of databinding code into the
// generated classes tightly (probably as inner classes)
// ###########################################################################################
// check for the special models in the mapper and if they are present process them
if (writeDatabinders) {
if (mapper.isObjectMappingPresent()) {
// add an attribute to the root element showing that the writing has been skipped
addAttribute(doc, "skip-write", "yes", rootElement);
// process the mapper objects
processModelObjects(mapper.getAllMappedObjects(), rootElement, doc);
}
}
// #############################################################################################
doc.appendChild(rootElement);
return doc;
}
/**
* Update mapper for message receiver
*/
protected void updateMapperForMessageReceiver() {
updateMapperClassnames(getFullyQualifiedMessageReceiverName());
}
/**
* @return fully qualified MR name
*/
protected String getFullyQualifiedMessageReceiverName() {
String packageName = codeGenConfiguration.getPackageName();
String localPart = makeJavaClassName(axisService.getName());
return packageName + "." + localPart + MESSAGE_RECEIVER_SUFFIX;
}
/**
* @return fully qualified skeleton name
*/
protected String getFullyQualifiedSkeletonName() {
String packageName = codeGenConfiguration.getPackageName();
String localPart = makeJavaClassName(axisService.getName());
String skeltonName;
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
skeltonName = packageName + "." + makeJavaClassName(axisService.getBindingName()) +
SKELETON_CLASS_SUFFIX_BACK;
} else {
skeltonName = packageName + "." + localPart + SKELETON_CLASS_SUFFIX;
}
return skeltonName;
}
/**
* @return fully qualified skeleton interface name
*/
protected String getFullyQualifiedSkeletonInterfaceName() {
String packageName = codeGenConfiguration.getPackageName();
String localPart = makeJavaClassName(axisService.getName());
String skeltonInterfaceName;
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
skeltonInterfaceName = packageName + "." +
makeJavaClassName(axisService.getEndpointName()) +
SKELETON_INTERFACE_SUFFIX_BACK;
} else {
skeltonInterfaceName = packageName + "." + localPart + SKELETON_INTERFACE_SUFFIX;
}
return skeltonInterfaceName;
}
/**
* Emits the skeleton
*
* @throws CodeGenerationException
*/
public void emitSkeleton() throws CodeGenerationException {
try {
allServiceInfoHolder = new HashMap();
Map originalMap = getNewCopy(this.mapper.getAllMappedNames());
// we are going to generate following files seperately per service
for (Iterator axisServicesIter = this.axisServices.iterator();
axisServicesIter.hasNext();) {
// create a new hash map for each service
this.infoHolder = new HashMap();
this.axisService = (AxisService) axisServicesIter.next();
this.axisBinding =
axisService.getEndpoint(axisService.getEndpointName()).getBinding();
// see the comment at updateMapperClassnames for details and reasons for
// calling this method
if (mapper.isObjectMappingPresent()) {
copyMap(originalMap, this.mapper.getAllMappedNames());
updateMapperForMessageReceiver();
} else {
copyToFaultMap();
}
//handle faults
generateAndPopulateFaultNames();
//
if (codeGenConfiguration.isServerSideInterface()) {
//write skeletonInterface
writeSkeletonInterface();
}
// write skeleton only if the used has
// asked for the deployment descriptor in the interface mode
// else write it anyway :)
if (codeGenConfiguration.isServerSideInterface()) {
if (codeGenConfiguration.isGenerateDeployementDescriptor()) {
writeSkeleton();
}
} else {
writeSkeleton();
}
if (!codeGenConfiguration.isSkipMessageReceiver()) {
// write a MessageReceiver for this particular service.
writeMessageReceiver();
}
// write the Exceptions
writeExceptions();
if (!codeGenConfiguration.isSkipWriteWSDLs()) {
//for the server side codegen
//we need to serialize the WSDL's
writeWSDLFiles();
}
// save the info holder with the service
allServiceInfoHolder.put(this.axisService.getName(),this.infoHolder);
}
// save back type map
if (this.mapper.isObjectMappingPresent()) {
copyMap(originalMap, this.mapper.getAllMappedNames());
}
// write service xml
// if asked
if (codeGenConfiguration.isGenerateDeployementDescriptor()) {
writeServiceXml();
}
if (!codeGenConfiguration.isSkipBuildXML()) {
//write the ant build
//we skip this for the flattened case
if (!codeGenConfiguration.isFlattenFiles()) {
writeAntBuild();
}
}
} catch (CodeGenerationException cgExp) {
throw cgExp;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
/**
* Write out the WSDL files (and the schemas) writing the WSDL (and schemas) is somewhat special
* so we cannot follow the usual pattern of using the class writer
*/
protected void writeWSDLFiles() {
//first modify the schema names (and locations) so that
//they have unique (flattened) names and the schema locations
//are adjusted to suit it
axisService.setCustomSchemaNamePrefix("");//prefix with nothing
axisService.setCustomSchemaNameSuffix(".xsd");//suffix with .xsd - the file name extension
//force the mappings to be reconstructed
axisService.setSchemaLocationsAdjusted(false);
//when generating the code we should copy all the schemas to
// resource folder.
Map changedMap = axisService.populateSchemaMappings(this.codeGenConfiguration.isOverrideAbsoluteAddress());
// add these two attribute to use the user defined wsdl to use.
try {
axisService.addParameter(new Parameter("useOriginalwsdl", "true"));
axisService.addParameter(new Parameter("modifyUserWSDLPortAddress", "false"));
} catch (AxisFault axisFault) {
// there is no way to get this excpetion while in codegeneration
}
//now get the schema list and write it out
SchemaWriter schemaWriter = new SchemaWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(), null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getResourceLocation()));
// first write all the schmas.
// then use the changedMap got above to adjust the names.
Map schemaMappings = axisService.getSchemaMappingTable();
Iterator keys = schemaMappings.keySet().iterator();
String key = null;
while (keys.hasNext()) {
key = (String) keys.next();
if (!key.startsWith("http")){
schemaWriter.writeSchema((XmlSchema) schemaMappings.get(key), key);
}
}
//switch between the correct writer
if (CommandLineOptionConstants.WSDL2JavaConstants.WSDL_VERSION_2.
equals(codeGenConfiguration.getWSDLVersion())) {
// Woden cannot serialize the WSDL as yet, so lets serialize the axisService for now.
WSDL20Writer wsdl20Writer = new WSDL20Writer(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(), null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getResourceLocation()));
wsdl20Writer.writeWSDL(axisService);
} else {
// here we are going to write the wsdl and its imports
// with out using the axis service.
WSDL11Writer wsdl11Writer = new WSDL11Writer(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(), null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getResourceLocation()));
wsdl11Writer.writeWSDL(axisService,
codeGenConfiguration.getWsdlDefinition(),
changedMap);
}
}
/**
* Utility method to copy the faults to the correct map
*/
protected void copyToFaultMap() {
Map classNameMap = mapper.getAllMappedNames();
Iterator keys = classNameMap.keySet().iterator();
while (keys.hasNext()) {
Object key = keys.next();
instantiatableMessageClassNames.put(key,
classNameMap.get(key));
}
}
/**
* Change the fault classnames to go with the package and stub
*/
protected void updateFaultPackageForStub() {
Iterator faultClassNameKeys = fullyQualifiedFaultClassNameMap.keySet().iterator();
while (faultClassNameKeys.hasNext()) {
Object key = faultClassNameKeys.next();
String className = (String) fullyQualifiedFaultClassNameMap.get(key);
//append the skelton name
String fullyQualifiedStubName = getFullyQualifiedStubName();
fullyQualifiedFaultClassNameMap.put(key, codeGenConfiguration.getPackageName() + "."
+ className);
}
}
/**
* Writes the message receiver
*
* @throws Exception
*/
protected void writeMessageReceiver() throws Exception {
//loop through the meps and generate code for each mep
Iterator it = mepToClassMap.keySet().iterator();
while (it.hasNext()) {
String mep = (String) it.next();
Document classModel = createDocumentForMessageReceiver(
mep,
codeGenConfiguration.isServerSideInterface());
debugLogDocument("Document for message receiver (mep=" + mep +
"):", classModel);
//write the class only if any methods are found
if (Boolean.TRUE.equals(infoHolder.get(mep))) {
MessageReceiverWriter writer =
new MessageReceiverWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(
codeGenConfiguration.getOutputLocation(),
null) :
getOutputDirectory(
codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getSourceLocation()),
codeGenConfiguration.getOutputLanguage());
writer.setOverride(codeGenConfiguration.isOverride());
writeFile(classModel, writer);
}
}
}
/**
* Creates the XML model for the message receiver
*
* @param mep
* @param isServerSideInterface
* @return DOM Document
*/
protected Document createDocumentForMessageReceiver(String mep, boolean isServerSideInterface) {
Document doc = getEmptyDocument();
Element rootElement = doc.createElement("interface");
addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
String localPart = makeJavaClassName(axisService.getName());
addAttribute(doc, "name", localPart + mepToSuffixMap.get(mep), rootElement);
// here set the isLowerCaseMethodName variable to have the negative on useOperationName to
// make it easier to handle in Message receiver template.
if (!this.codeGenConfiguration.isUseOperationName()) {
addAttribute(doc, "isLowerCaseMethodName", "true", rootElement);
}
//add backwordcompatibility attribute
addAttribute(doc, "isbackcompatible",
String.valueOf(codeGenConfiguration.isBackwordCompatibilityMode()),
rootElement);
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
addAttribute(doc, "skeletonname",
makeJavaClassName(axisService.getBindingName()) +
SKELETON_CLASS_SUFFIX_BACK,
rootElement);
if (isServerSideInterface) {
addAttribute(doc, "skeletonInterfaceName", makeJavaClassName(
axisService.getEndpointName()) + SKELETON_INTERFACE_SUFFIX_BACK,
rootElement);
} else {
addAttribute(doc, "skeletonInterfaceName", makeJavaClassName(
axisService.getBindingName()) + SKELETON_CLASS_SUFFIX_BACK,
rootElement);
}
} else {
if (this.codeGenConfiguration.getSkeltonClassName() != null){
addAttribute(doc, "skeletonname", this.codeGenConfiguration.getSkeltonClassName(), rootElement);
} else {
addAttribute(doc, "skeletonname", localPart + SKELETON_CLASS_SUFFIX, rootElement);
}
if (isServerSideInterface) {
if (this.codeGenConfiguration.getSkeltonInterfaceName() != null){
addAttribute(doc, "skeletonInterfaceName", this.codeGenConfiguration.getSkeltonInterfaceName(),
rootElement);
} else {
addAttribute(doc, "skeletonInterfaceName", localPart + SKELETON_INTERFACE_SUFFIX,
rootElement);
}
} else {
if (this.codeGenConfiguration.getSkeltonClassName() != null){
addAttribute(doc, "skeletonInterfaceName", this.codeGenConfiguration.getSkeltonClassName(),
rootElement);
} else {
addAttribute(doc, "skeletonInterfaceName", localPart + SKELETON_CLASS_SUFFIX,
rootElement);
}
}
}
addAttribute(doc, "basereceiver", (String) mepToClassMap.get(mep), rootElement);
fillSyncAttributes(doc, rootElement);
// ###########################################################################################
// this block of code specifically applies to the integration of databinding code into the
// generated classes tightly (probably as inner classes)
// ###########################################################################################
// check for the special models in the mapper and if they are present process them
if (mapper.isObjectMappingPresent()) {
// add an attribute to the root element showing that the writing has been skipped
addAttribute(doc, "skip-write", "yes", rootElement);
// process the mapper objects
processModelObjects(mapper.getAllMappedObjects(), rootElement, doc);
}
// #############################################################################################
boolean isOpsFound = loadOperations(doc, rootElement, mep);
//put the result in the property map
infoHolder.put(mep, isOpsFound ? Boolean.TRUE : Boolean.FALSE);
//create the databinder element with serverside as true
rootElement.appendChild(createDOMElementforDatabinders(doc, true));
//attach a list of faults
rootElement.appendChild(getUniqueListofFaultsofMep(doc, mep));
doc.appendChild(rootElement);
//////////////////////////////////////////////////////////
// System.out.println(DOM2Writer.nodeToString(rootElement));
////////////////////////////////////////////////////////////
return doc;
}
/**
* create a dom element for databinders. This is called by other
*
* @param doc
*/
protected Element createDOMElementforDatabinders(Document doc, boolean isServerside) {
// First Iterate through the operations and find the relevant fromOM and toOM methods to be generated
ArrayList parameters = new ArrayList();
AxisOperation axisOperation = null;
AxisBindingOperation axisBindingOperation = null;
for (Iterator bindingOperationsIter = this.axisBinding.getChildren();
bindingOperationsIter.hasNext();) {
axisBindingOperation = (AxisBindingOperation) bindingOperationsIter.next();
axisOperation = axisBindingOperation.getAxisOperation();
// Add the parameters to a map with their type as the key
// this step is needed to remove repetitions
// process the input parameters
String MEP = axisOperation.getMessageExchangePattern();
if (WSDLUtil.isInputPresentForMEP(MEP)) {
Element[] inputParamElement = getInputParamElement(doc, axisOperation);
for (int i = 0; i < inputParamElement.length; i++) {
//add an attribute to the parameter saying that this is an
//input
addAttribute(doc, "direction", "in", inputParamElement[i]);
//add the short type name
parameters.add(
inputParamElement[i]);
}
}
// process output parameters
if (WSDLUtil.isOutputPresentForMEP(MEP)) {
Element outputParamElement = getOutputParamElement(doc, axisOperation);
if (outputParamElement != null) {
//set the direction as out
addAttribute(doc, "direction", "out", outputParamElement);
parameters.add(outputParamElement);
}
}
//process faults
Element[] faultParamElements = getFaultParamElements(doc, axisOperation);
for (int i = 0; i < faultParamElements.length; i++) {
//set the direction as out - all faults are out messages ?
addAttribute(doc, "direction", "out", faultParamElements[i]);
parameters.add(faultParamElements[i]);
}
// process the header parameters
Element newChild;
List headerParameterQNameList = new ArrayList();
addHeaderOperations(headerParameterQNameList, axisBindingOperation, true);
List parameterElementList = getParameterElementList(doc, headerParameterQNameList,
WSDLConstants.SOAP_HEADER);
for (int i = 0; i < parameterElementList.size(); i++) {
newChild = (Element) parameterElementList.get(i);
parameters.add(newChild);
}
headerParameterQNameList.clear();
parameterElementList.clear();
addHeaderOperations(headerParameterQNameList, axisBindingOperation, false);
parameterElementList = getParameterElementList(doc, headerParameterQNameList,
WSDLConstants.SOAP_HEADER);
for (int i = 0; i < parameterElementList.size(); i++) {
newChild = (Element) parameterElementList.get(i);
parameters.add(newChild);
}
}
Element rootElement = doc.createElement("databinders");
//add the db type attribute - the name of the databinding type
//this will be used to select the correct template
addAttribute(doc, "dbtype", codeGenConfiguration.getDatabindingType(), rootElement);
//add the wrapped flag state - this is used by JiBX, but may be useful
//for other frameworks in the future
String wrapflag = Boolean.toString(codeGenConfiguration.isParametersWrapped());
addAttribute(doc, "wrapped", wrapflag, rootElement);
//at this point we may need to capture the extra parameters passes to the
//particular databinding framework
//these parameters showup in the property map with String keys, and we
//can just copy these items as attributes of the <extra> element.
Element extraElement = addElement(doc, "extra", null, rootElement);
Map propertiesMap = codeGenConfiguration.getProperties();
for (Iterator it = propertiesMap.keySet().iterator(); it.hasNext();) {
Object key = it.next();
if (key instanceof String) {
Object value = propertiesMap.get(key);
//if the value is null set it to empty string
if (value == null) value = "";
//add key="value" attribute to element iff value a string
if (value instanceof String) {
addAttribute(doc, (String) key, (String) value, extraElement);
}
}
}
//add the server side attribute. this helps the databinding template
//to determine the methods to generate
if (isServerside) {
addAttribute(doc, "isserverside", "yes", rootElement);
}
// add the names of the elements that have base 64 content
// if the base64 name list is missing then this whole step is skipped
rootElement.appendChild(getBase64Elements(doc));
//add the method names
rootElement.appendChild(getOpNames(doc));
for (Iterator iterator = parameters.iterator(); iterator.hasNext();) {
rootElement.appendChild((Element) iterator.next());
}
// finish with any extra information from service and operations
Parameter details = axisService.getParameter(Constants.DATABINDING_SERVICE_DETAILS);
if (details != null) {
Object value = details.getValue();
if (value instanceof Element) {
rootElement.appendChild(doc.importNode((Element) value, true));
} else if (value instanceof List) {
for (Iterator iter = ((List) value).iterator(); iter.hasNext();) {
rootElement.appendChild(doc.importNode((Element) iter.next(), true));
}
}
}
axisOperation = null;
for (Iterator operationsIterator = axisService.getOperations();
operationsIterator.hasNext();) {
axisOperation = (AxisOperation) operationsIterator.next();
details = axisOperation.getParameter(Constants.DATABINDING_OPERATION_DETAILS);
if (details != null) {
rootElement.appendChild(doc.importNode((Element) details.getValue(), true));
}
}
///////////////////////////////////////////////
// System.out.println("databinding root element " + DOM2Writer.nodeToString(rootElement));
////////////////////////////////////////////////
return rootElement;
}
/**
* set the short type as it is in the data binding
*
* @param paramElement
* @param xmlName
*/
protected void addShortType(Element paramElement, String xmlName) {
if (xmlName != null) {
String javaName;
if (JavaUtils.isJavaKeyword(xmlName)) {
javaName = JavaUtils.makeNonJavaKeyword(xmlName);
} else {
javaName = JavaUtils.capitalizeFirstChar(JavaUtils
.xmlNameToJava(xmlName));
}
addAttribute(paramElement.getOwnerDocument(),
"shorttype",
javaName,
paramElement);
} else {
addAttribute(paramElement.getOwnerDocument(),
"shorttype",
"",
paramElement);
}
}
/**
* Gets an element representing the operation names
*
* @param doc
* @return Returns Element.
*/
protected Element getOpNames(Document doc) {
Element root = doc.createElement("opnames");
Element elt;
for (Iterator operationsIterator = axisService.getOperations();
operationsIterator.hasNext();) {
AxisOperation axisOperation = (AxisOperation) operationsIterator.next();
elt = doc.createElement("name");
String localPart = axisOperation.getName().getLocalPart();
elt.appendChild(doc.createTextNode(JavaUtils.xmlNameToJava(localPart)));
//what needs to be put here as the opertation namespace is actually the
//traget namespace of the service
addAttribute(doc, "opnsuri", axisService.getTargetNamespace(), elt);
root.appendChild(elt);
}
return root;
}
/**
* Gets the base64 types. If not available this will be empty!!!
*
* @param doc
* @return Returns Element.
*/
protected Element getBase64Elements(Document doc) {
Element root = doc.createElement("base64Elements");
Element elt;
QName qname;
// this is a list of QNames
List list = (List) codeGenConfiguration.getProperties().get(Constants.BASE_64_PROPERTY_KEY);
if ((list != null) && !list.isEmpty()) {
int count = list.size();
for (int i = 0; i < count; i++) {
qname = (QName) list.get(i);
elt = doc.createElement("name");
addAttribute(doc, "ns-url", qname.getNamespaceURI(), elt);
addAttribute(doc, "localName", qname.getLocalPart(), elt);
root.appendChild(elt);
}
}
return root;
}
/**
* @param objectMappings
* @param root
* @param doc
*/
protected void processModelObjects(Map objectMappings, Element root, Document doc) {
Iterator objectIterator = objectMappings.values().iterator();
while (objectIterator.hasNext()) {
Object o = objectIterator.next();
if (o instanceof Document) {
//we cannot have an empty document
root.appendChild(doc.importNode(((Document) o).getDocumentElement(), true));
} else {
// oops we have no idea how to do this, if the model provided is not a DOM document
// we are done. we might as well skip it here
}
}
}
/**
* we need to modify the mapper's class name list. The issue here is that in this case we do not
* expect the fully qulified class names to be present in the class names list due to the simple
* reason that they've not been written yet! Hence the mappers class name list needs to be
* updated to suit the expected package to be written in this case we modify the package name to
* have the class a inner class of the stub, interface or the message receiver depending on the
* style
*/
protected void updateMapperClassnames(String fullyQulifiedIncludingClassNamePrefix) {
Map classNameMap = mapper.getAllMappedNames();
Iterator keys = classNameMap.keySet().iterator();
while (keys.hasNext()) {
Object key = keys.next();
String className = (String) classNameMap.get(key);
String realClassName = className;
if (className.endsWith("[]")){
realClassName = realClassName.substring(0,realClassName.indexOf("[]"));
}
//this is a generated class name - update the name
if (!TypeTesterUtil.hasPackage(realClassName) && !TypeTesterUtil.isPrimitive(realClassName)) {
classNameMap.put(key, fullyQulifiedIncludingClassNamePrefix + "." + className);
instantiatableMessageClassNames.put(key,
fullyQulifiedIncludingClassNamePrefix + "$" +
className);
} else {
//this is a fully qualified class name - just leave it as it is
classNameMap.put(key, className);
instantiatableMessageClassNames.put(key,
className);
}
}
}
/**
* Write the service XML
*
* @throws Exception
*/
protected void writeServiceXml() throws Exception {
// Write the service xml in a folder with the
Document serviceXMLModel = createDOMDocumentForServiceXML();
debugLogDocument("Document for service XML:", serviceXMLModel);
FileWriter serviceXmlWriter =
new ServiceXMLWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(), null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getResourceLocation()),
this.codeGenConfiguration.getOutputLanguage());
serviceXmlWriter.setOverride(codeGenConfiguration.isOverride());
writeFile(serviceXMLModel, serviceXmlWriter);
codeGenConfiguration.addXmlFileName(serviceXmlWriter.getOutputFile().getAbsolutePath());//$NON-SEC-3
}
protected Document createDOMDocumentForServiceXML() {
Document doc = getEmptyDocument();
String className = null;
String serviceName = null;
Element rootElement = doc.createElement("interfaces");
doc.appendChild(rootElement);
for (Iterator iter = this.axisServices.iterator(); iter.hasNext();) {
this.axisService = (AxisService) iter.next();
this.axisBinding = axisService.getEndpoint(axisService.getEndpointName()).getBinding();
serviceName = axisService.getName();
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
className = makeJavaClassName(axisService.getBindingName());
} else {
className = makeJavaClassName(serviceName);
}
rootElement.appendChild(getServiceElement(serviceName, className, doc));
}
return doc;
}
/**
* A resusable method to return the service element for creating the service xml
*
* @param serviceName
* @param className
* @param doc
* @return DOM Element
*/
protected Element getServiceElement(String serviceName, String className, Document doc) {
if (allServiceInfoHolder.get(serviceName) != null){
this.infoHolder = (Map) allServiceInfoHolder.get(serviceName);
}
Element rootElement = doc.createElement("interface");
addAttribute(doc, "package", "", rootElement);
addAttribute(doc, "classpackage", codeGenConfiguration.getPackageName(), rootElement);
if (this.codeGenConfiguration.getSkeltonClassName() != null) {
addAttribute(doc, "name", this.codeGenConfiguration.getSkeltonClassName(), rootElement);
} else {
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
addAttribute(doc, "name", className + SKELETON_CLASS_SUFFIX_BACK, rootElement);
} else {
addAttribute(doc, "name", className + SKELETON_CLASS_SUFFIX, rootElement);
}
}
if (!codeGenConfiguration.isWriteTestCase()) {
addAttribute(doc, "testOmit", "true", rootElement);
}
addAttribute(doc, "servicename", serviceName, rootElement);
Iterator it = mepToClassMap.keySet().iterator();
while (it.hasNext()) {
Object key = it.next();
if (Boolean.TRUE.equals(infoHolder.get(key))) {
Element elt = addElement(doc, "messagereceiver",
makeJavaClassName(serviceName) + mepToSuffixMap.get(key),
rootElement);
addAttribute(doc, "mepURI", key.toString(), elt);
}
}
loadOperations(doc, rootElement, null);
return rootElement;
}
protected void writeSkeleton() throws Exception {
Document skeletonModel =
createDOMDocumentForSkeleton(codeGenConfiguration.isServerSideInterface());
debugLogDocument("Document for skeleton:", skeletonModel);
FileWriter skeletonWriter = new SkeletonWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(), null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getSourceLocation())
, this.codeGenConfiguration.getOutputLanguage());
skeletonWriter.setOverride(codeGenConfiguration.isOverride());
writeFile(skeletonModel, skeletonWriter);
}
/**
* Write the skeletonInterface
*
* @throws Exception
*/
protected void writeSkeletonInterface() throws Exception {
Document skeletonModel = createDOMDocumentForSkeletonInterface();
debugLogDocument("Document for skeleton Interface:", skeletonModel);
FileWriter skeletonInterfaceWriter = new SkeletonInterfaceWriter(
codeGenConfiguration.isFlattenFiles() ?
getOutputDirectory(codeGenConfiguration.getOutputLocation(), null) :
getOutputDirectory(codeGenConfiguration.getOutputLocation(),
codeGenConfiguration.getSourceLocation())
, this.codeGenConfiguration.getOutputLanguage());
skeletonInterfaceWriter.setOverride(codeGenConfiguration.isOverride());
writeFile(skeletonModel, skeletonInterfaceWriter);
}
/**
* Creates the XMLModel for the skeleton
*
* @param isSkeletonInterface
* @return DOM Document
*/
protected Document createDOMDocumentForSkeleton(boolean isSkeletonInterface) {
Document doc = getEmptyDocument();
Element rootElement = doc.createElement("interface");
String serviceName = makeJavaClassName(axisService.getName());
addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
addAttribute(doc, "name",
makeJavaClassName(axisService.getBindingName()) +
SKELETON_CLASS_SUFFIX_BACK,
rootElement);
} else if (this.codeGenConfiguration.getSkeltonClassName() != null){
addAttribute(doc, "name", this.codeGenConfiguration.getSkeltonClassName(), rootElement);
} else {
addAttribute(doc, "name", serviceName + SKELETON_CLASS_SUFFIX, rootElement);
}
addAttribute(doc, "callbackname", serviceName + CALL_BACK_HANDLER_SUFFIX,
rootElement);
//add backwordcompatibility attribute
addAttribute(doc, "isbackcompatible",
String.valueOf(codeGenConfiguration.isBackwordCompatibilityMode()),
rootElement);
if (isSkeletonInterface) {
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
addAttribute(doc, "skeletonInterfaceName", makeJavaClassName(
axisService.getEndpointName()) + SKELETON_INTERFACE_SUFFIX_BACK,
rootElement);
} else if (this.codeGenConfiguration.getSkeltonInterfaceName() != null){
addAttribute(doc, "skeletonInterfaceName", this.codeGenConfiguration.getSkeltonInterfaceName(),
rootElement);
} else {
addAttribute(doc, "skeletonInterfaceName", serviceName + SKELETON_INTERFACE_SUFFIX,
rootElement);
}
}
fillSyncAttributes(doc, rootElement);
loadOperations(doc, rootElement, null);
//attach a list of faults
rootElement.appendChild(getUniqueListofFaults(doc));
doc.appendChild(rootElement);
//////////////////////////////////////////////////////////
// System.out.println(DOM2Writer.nodeToString(rootElement));
////////////////////////////////////////////////////////////
return doc;
}
/**
* Creates the XML model for the skeleton interface
*
* @return DOM Document
*/
protected Document createDOMDocumentForSkeletonInterface() {
Document doc = getEmptyDocument();
Element rootElement = doc.createElement("interface");
String serviceName = makeJavaClassName(axisService.getName());
addAttribute(doc, "package", codeGenConfiguration.getPackageName(), rootElement);
if (this.codeGenConfiguration.isBackwordCompatibilityMode()) {
addAttribute(doc, "name", makeJavaClassName(axisService.getEndpointName()) +
SKELETON_INTERFACE_SUFFIX_BACK, rootElement);
} else if (this.codeGenConfiguration.getSkeltonInterfaceName() != null){
addAttribute(doc, "name", this.codeGenConfiguration.getSkeltonInterfaceName() , rootElement);
} else {
addAttribute(doc, "name", serviceName + SKELETON_INTERFACE_SUFFIX, rootElement);
}
addAttribute(doc, "callbackname", serviceName + CALL_BACK_HANDLER_SUFFIX,
rootElement);
//add backwordcompatibility attribute
addAttribute(doc, "isbackcompatible",
String.valueOf(codeGenConfiguration.isBackwordCompatibilityMode()),
rootElement);
fillSyncAttributes(doc, rootElement);
loadOperations(doc, rootElement, null);
//attach a list of faults
rootElement.appendChild(getUniqueListofFaults(doc));
doc.appendChild(rootElement);
//////////////////////////////////////////////////////////
// System.out.println(DOM2Writer.nodeToString(rootElement));
////////////////////////////////////////////////////////////
return doc;
}
/**
* Loads the operations
*
* @param doc
* @param rootElement
* @param mep
* @return boolean
*/
protected boolean loadOperations(Document doc, Element rootElement, String mep) {
Element methodElement;
String serviceName = makeJavaClassName(axisService.getName());
Iterator bindingOperations = this.axisBinding.getChildren();
boolean opsFound = false;
AxisBindingOperation axisBindingOperation = null;
AxisOperation axisOperation = null;
while (bindingOperations.hasNext()) {
axisBindingOperation = (AxisBindingOperation) bindingOperations.next();
axisOperation = axisBindingOperation.getAxisOperation();
// populate info holder with mep information. This will used in determining which
// message receiver to use, etc.,
String messageExchangePattern = axisOperation.getMessageExchangePattern();
if (infoHolder.get(messageExchangePattern) == null) {
infoHolder.put(messageExchangePattern, Boolean.TRUE);
}
if (mep == null) {
opsFound = true;
methodElement = generateMethodElement(doc, serviceName, axisBindingOperation);
rootElement.appendChild(methodElement);
} else {
//mep is present - we move ahead only if the given mep matches the mep of this operation
if (mep.equals(axisOperation.getMessageExchangePattern())) {
//at this point we know it's true
opsFound = true;
methodElement = generateMethodElement(doc, serviceName, axisBindingOperation);
rootElement.appendChild(methodElement);
//////////////////////
}
}
}
return opsFound;
}
/**
* Common code to generate a <method> element from an operation.
*
* @param doc
* @param endpointName
* @param bindingOperation
* @return generated element
* @throws DOMException
*/
protected Element generateMethodElement(Document doc,
String endpointName,
AxisBindingOperation bindingOperation) throws DOMException {
AxisOperation axisOperation = bindingOperation.getAxisOperation();
Element methodElement;
List soapHeaderInputParameterList = new ArrayList();
List soapHeaderOutputParameterList = new ArrayList();
methodElement = doc.createElement("method");
String localPart = axisOperation.getName().getLocalPart();
if (this.codeGenConfiguration.isUseOperationName()) {
addAttribute(doc, "name", JavaUtils.xmlNameToJava(localPart), methodElement);
} else {
addAttribute(doc, "name", JavaUtils.xmlNameToJavaIdentifier(localPart), methodElement);
}
addAttribute(doc, "originalName", localPart, methodElement);
addAttribute(doc, "namespace", axisOperation.getName().getNamespaceURI(), methodElement);
addAttribute(doc, "style", (String) getBindingPropertyFromOperation(
WSDLConstants.WSDL_1_1_STYLE, axisOperation.getName()), methodElement);
// add documentation for this operation
String comment = "";
if (axisOperation.getDocumentation() != null){
comment = axisOperation.getDocumentation().trim();
}
addAttribute(doc, "comment", comment, methodElement);
String messageExchangePattern = axisOperation.getMessageExchangePattern();
//Jaxws Specific
if("jax-ws".equals(codeGenConfiguration.getOutputLanguage())){
boolean wrapped = false;
if (WSDLUtil.isInputPresentForMEP(messageExchangePattern)) {
AxisMessage msg = axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
if(msg.getParameter(Constants.UNWRAPPED_KEY) != null){
wrapped = true;
}
}
addAttribute(doc, "parameterstyle", (wrapped)?"WRAPPPED":"BARE", methodElement);
}
addAttribute(doc, "dbsupportname",
endpointName + localPart + DATABINDING_SUPPORTER_NAME_SUFFIX,
methodElement);
addAttribute(doc, "mep", Utils.getAxisSpecifMEPConstant(messageExchangePattern) + "",
methodElement);
addAttribute(doc, "mepURI", messageExchangePattern, methodElement);
Parameter wsdl2StyleParameter = axisOperation.getParameter(WSDL2Constants.OPERATION_STYLE);
if (wsdl2StyleParameter != null) {
// provide WSDL2 styles to allow templates to take advantage of them, if desired
addAttribute(doc, "wsdl2Styles", arrayToString((URI[])wsdl2StyleParameter.getValue()), methodElement);
}
// check for this operation to be handled directly by databinding code generation
Parameter dbmethname = axisOperation.getParameter(Constants.DATABINDING_GENERATED_RECEIVER);
if (dbmethname != null) {
addAttribute(doc, "usedbmethod", (String) dbmethname.getValue(), methodElement);
}
Parameter dbgenimpl =
axisOperation.getParameter(Constants.DATABINDING_GENERATED_IMPLEMENTATION);
if (dbgenimpl != null && Boolean.TRUE.equals(dbgenimpl.getValue())) {
addAttribute(doc, "usdbimpl", "true", methodElement);
} else {
addAttribute(doc, "usdbimpl", "false", methodElement);
}
addSOAPAction(doc, methodElement, bindingOperation.getName());
addOutputAndFaultActions(doc, methodElement, axisOperation);
addHeaderOperations(soapHeaderInputParameterList, bindingOperation, true);
// addHeaderOperations(soapHeaderOutputParameterList, axisOperation, false);
if (WSDLUtil.isInputPresentForMEP(messageExchangePattern)) {
if("jax-ws".equals(codeGenConfiguration.getOutputLanguage())){
useHolderClass_jaxws = false;
AxisMessage inMessage = axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
if (WSDLUtil.isOutputPresentForMEP(messageExchangePattern)) {
AxisMessage outMessage = axisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
if(inMessage.getName().equals(outMessage.getName())){
// in/out message
useHolderClass_jaxws = true;
addAttribute(doc, "useholder", "true", methodElement);
}
}
}
methodElement.appendChild(getInputElement(doc,
bindingOperation, soapHeaderInputParameterList));
}
if (WSDLUtil.isOutputPresentForMEP(messageExchangePattern)) {
methodElement.appendChild(getOutputElement(doc,
bindingOperation,
soapHeaderOutputParameterList));
}
methodElement.appendChild(getFaultElement(doc,
axisOperation));
setTransferCoding(axisOperation, methodElement, doc);
String property = (String) getBindingPropertyFromOperation(
WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR,
axisOperation.getName());
if (property != null) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_QUERY_PARAMETER_SEPARATOR",
"\"" + property + "\""));
}
property = (String) getBindingPropertyFromOperation(
WSDL2Constants.ATTR_WHTTP_LOCATION,
axisOperation.getName());
if (property != null) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_LOCATION",
"\"" + property + "\""));
}
String mep = (String) getBindingPropertyFromOperation(WSDL2Constants.ATTR_WSOAP_MEP,
axisOperation.getName());
String bindingType = null;
if (axisBinding != null) {
bindingType = axisBinding.getType();
}
if (WSDL2Constants.URI_WSOAP_MEP.equalsIgnoreCase(mep)) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.ENABLE_REST",
"true"));
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.HTTP_METHOD",
"\"" +
org.apache.axis2.Constants.Configuration
.HTTP_METHOD_GET +
"\""));
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.CONTENT_TYPE",
"\"" +
org.apache.axis2.transport.http.HTTPConstants
.MEDIA_TYPE_X_WWW_FORM +
"\""));
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.MESSAGE_TYPE",
"\"" +
org.apache.axis2.transport.http.HTTPConstants
.MEDIA_TYPE_X_WWW_FORM +
"\""));
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.SOAP_RESPONSE_MEP",
"true"));
} else if (bindingType != null && bindingType.equals(WSDL2Constants.URI_WSDL2_HTTP)) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.ENABLE_REST",
"true"));
property = (String) getBindingPropertyFromOperation(WSDL2Constants.ATTR_WHTTP_METHOD,
axisOperation.getName());
if (property != null) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.HTTP_METHOD",
"\"" + property + "\""));
} else if (!WSDL2Constants.URI_WSOAP_MEP.equalsIgnoreCase(mep)) {
// If there is no WHTTP_METHOD defined then we better compute the default value which is get if the operation
// is wsdlx:safe or post otherwise
Parameter safe = axisOperation.getParameter(WSDL2Constants.ATTR_WSDLX_SAFE);
if (safe != null) {
if (((Boolean) safe.getValue()).booleanValue()) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.HTTP_METHOD",
"\"" +
org.apache.axis2.Constants.Configuration
.HTTP_METHOD_GET +
"\""));
} else {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.HTTP_METHOD",
"\"" +
org.apache.axis2.Constants.Configuration
.HTTP_METHOD_POST +
"\""));
}
}
}
Boolean value = (Boolean) getBindingPropertyFromOperation(
WSDL2Constants.ATTR_WHTTP_IGNORE_UNCITED,
axisOperation.getName());
if (value != null) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_IGNORE_UNCITED",
"\"" + value.booleanValue() +
"\""));
}
property = (String) getBindingPropertyFromOperation(WSDL2Constants.ATTR_WHTTP_CODE,
axisOperation.getName());
if (property != null) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.description.WSDL2Constants.ATTR_WHTTP_CODE",
"\"" + property + "\""));
}
property = (String) getBindingPropertyFromOperation(
WSDL2Constants.ATTR_WHTTP_INPUT_SERIALIZATION,
axisOperation.getName());
if (property != null) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.CONTENT_TYPE",
"\"" + property + "\""));
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.Constants.Configuration.MESSAGE_TYPE",
"\"" + property + "\""));
}
}
return methodElement;
}
/**
* Returns a comma-separated list of the string representations of the array elements.
* @param array the array to be processed
* @return the empty string "" if array is null or empty, the array element if size is 1,
* or a comma-separated list when size > 1.
*/
private String arrayToString(Object[] array) {
if (array == null || array.length == 0) {
return "";
}
int size = array.length;
if (size == 1) {
return String.valueOf(array[0]);
}
StringBuffer result = new StringBuffer(String.valueOf(array[0]));
for (int i=1; i<size; i++) {
result.append(",");
result.append(String.valueOf(array[i]));
}
return result.toString();
}
/**
* Set the transfer coding property of the input message
*
* @param axisOperation
* @param methodElement
* @param doc
*/
private void setTransferCoding(AxisOperation axisOperation, Element methodElement,
Document doc) {
// Add a optionParam element which holds the value of transferCoding
String transferCoding =
(String) getBindingPropertyFromMessage(WSDL2Constants.ATTR_WHTTP_CONTENT_ENCODING,
axisOperation.getName(),
WSDLConstants.WSDL_MESSAGE_DIRECTION_IN);
if (!"".equals(transferCoding)) {
if ("gzip".equals(transferCoding) || "compress".equals(transferCoding)) {
methodElement.appendChild(generateOptionParamComponent(doc,
"org.apache.axis2.transport.http.HTTPConstants.MC_GZIP_REQUEST",
"true"));
}
}
}
/**
* Set thttp header properties needed for the stub
*
* @param axisOperation
* @param methodElement
* @param doc
*/
private void setHttpHeaderOptions(AxisOperation axisOperation, Element methodElement,
Document doc) {
// Add a optionParam elements here
}
// ==================================================================
// Util Methods
// ==================================================================
protected Document getEmptyDocument() {
try {
DocumentBuilder documentBuilder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
return documentBuilder.newDocument();
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
}
}
/**
* @param word
* @return Returns character removed string.
*/
protected String makeJavaClassName(String word) {
if (JavaUtils.isJavaKeyword(word)) {
return JavaUtils.makeNonJavaKeyword(word);
} else {
return JavaUtils.capitalizeFirstChar(JavaUtils.xmlNameToJava(word));
}
}
/**
* Utility method to add an attribute to a given element.
*
* @param document
* @param AttribName
* @param attribValue
* @param element
*/
protected void addAttribute(Document document, String AttribName, String attribValue,
Element element) {
XSLTUtils.addAttribute(document, AttribName, attribValue, element);
}
/**
* @param doc
* @param rootElement
*/
protected void fillSyncAttributes(Document doc, Element rootElement) {
addAttribute(doc, "isAsync", this.codeGenConfiguration.isAsyncOn()
? "1"
: "0", rootElement);
addAttribute(doc, "isSync", this.codeGenConfiguration.isSyncOn()
? "1"
: "0", rootElement);
}
/**
* debugging method - write the output to the debugger
*
* @param description
* @param doc
*/
protected void debugLogDocument(String description, Document doc) {
if (log.isDebugEnabled()) {
try {
DOMSource source = new DOMSource(doc);
StringWriter swrite = new StringWriter();
swrite.write(description);
swrite.write("\n");
Transformer transformer =
TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty("omit-xml-declaration", "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(source, new StreamResult(swrite));
log.debug(swrite.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Gets the output directory for source files.
*
* @param outputDir
* @return Returns File.
*/
protected File getOutputDirectory(File outputDir, String dir2) {
if (dir2 != null && !"".equals(dir2)) {
outputDir = new File(outputDir, dir2);
}
if (!outputDir.exists()) {//$NON-SEC-3
outputDir.mkdirs();//$NON-SEC-2
}
return outputDir;
}
/**
* A resusable method for the implementation of interface and implementation writing.
*
* @param model
* @param writer
* @throws java.io.IOException
* @throws Exception
*/
protected void writeFile(Document model, FileWriter writer) throws IOException, Exception {
writer.loadTemplate();
String packageName = model.getDocumentElement().getAttribute("package");
String className = model.getDocumentElement().getAttribute("name");
writer.createOutFile(packageName, className);
// use the global resolver
writer.parse(model, resolver);
}
/**
* Adds the soap action
*
* @param doc
* @param rootElement
* @param qName
*/
protected void addSOAPAction(Document doc, Element rootElement, QName qName) {
addAttribute(doc, "soapaction",
(String) getBindingPropertyFromOperation(WSDL2Constants.ATTR_WSOAP_ACTION,
qName),
rootElement);
}
/**
* Adds the output and fault actions
*
* @param doc
* @param methodElement
* @param operation
*/
private void addOutputAndFaultActions(Document doc, Element methodElement,
AxisOperation operation) {
String outputAction = operation.getOutputAction();
if (outputAction != null) {
Element outputActionElt =
doc.createElement(org.apache.axis2.Constants.OUTPUT_ACTION_MAPPING);
outputActionElt.setAttribute(AddressingConstants.WSA_ACTION, outputAction);
methodElement.appendChild(outputActionElt);
}
String[] faultActionNames = operation.getFaultActionNames();
if (faultActionNames != null) {
for (int i = 0; i < faultActionNames.length; i++) {
Element faultActionElt =
doc.createElement(org.apache.axis2.Constants.FAULT_ACTION_MAPPING);
faultActionElt.setAttribute(org.apache.axis2.Constants.FAULT_ACTION_NAME,
faultActionNames[i]);
faultActionElt.setAttribute(AddressingConstants.WSA_ACTION,
operation.getFaultAction(faultActionNames[i]));
methodElement.appendChild(faultActionElt);
}
}
}
/**
* populate the header parameters
*
* @param soapHeaderParameterQNameList
* @param bindingOperation
* @param input
*/
protected void addHeaderOperations(List soapHeaderParameterQNameList,
AxisBindingOperation bindingOperation,
boolean input) {
AxisOperation axisOperation = bindingOperation.getAxisOperation();
ArrayList headerparamList = new ArrayList();
String MEP = axisOperation.getMessageExchangePattern();
if (input) {
if (WSDLUtil.isInputPresentForMEP(MEP)) {
headerparamList = (ArrayList) getBindingPropertyFromMessage(
WSDL2Constants.ATTR_WSOAP_HEADER, bindingOperation.getName(),
WSDLConstants.MESSAGE_LABEL_IN_VALUE);
}
} else {
if (WSDLUtil.isOutputPresentForMEP(MEP)) {
headerparamList = (ArrayList) getBindingPropertyFromMessage(
WSDL2Constants.ATTR_WSOAP_HEADER, bindingOperation.getName(),
WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
}
}
if (headerparamList != null) {
for (Iterator iterator = headerparamList.iterator(); iterator.hasNext();) {
SOAPHeaderMessage header = (SOAPHeaderMessage) iterator.next();
soapHeaderParameterQNameList.add(header);
}
}
}
/**
* populate the header parameters to faults
*
* @param soapHeaderParameterQNameList
* @param axisOperation
*/
protected void addHeaderOperationsToFault(List soapHeaderParameterQNameList,
AxisOperation axisOperation) {
ArrayList headerparamList = new ArrayList();
ArrayList faultMessages = axisOperation.getFaultMessages();
Iterator iter = faultMessages.iterator();
while (iter.hasNext()) {
AxisMessage axisFaultMessage = (AxisMessage) iter.next();
headerparamList.addAll((ArrayList) getBindingPropertyFromMessageFault(
WSDL2Constants.ATTR_WSOAP_HEADER, axisOperation.getName(),
axisFaultMessage.getName()));
}
if (headerparamList != null) {
for (Iterator iterator = headerparamList.iterator(); iterator.hasNext();) {
SOAPHeaderMessage header = (SOAPHeaderMessage) iterator.next();
soapHeaderParameterQNameList.add(header.getElement());
}
}
}
/**
* Get the input element
*
* @param doc
* @param bindingOperation
* @param headerParameterQNameList
* @return DOM element
*/
protected Element getInputElement(Document doc,
AxisBindingOperation bindingOperation,
List headerParameterQNameList) {
AxisOperation operation = bindingOperation.getAxisOperation();
Element inputElt = doc.createElement("input");
String mep = operation.getMessageExchangePattern();
if (WSDLUtil.isInputPresentForMEP(mep)) {
Element[] param = getInputParamElement(doc, operation);
for (int i = 0; i < param.length; i++) {
inputElt.appendChild(param[i]);
}
List parameterElementList = getParameterElementList(doc, headerParameterQNameList,
WSDLConstants.SOAP_HEADER);
parameterElementList.addAll(getParameterElementListForHttpHeader(doc,
(ArrayList) getBindingPropertyFromMessage(
WSDL2Constants.ATTR_WHTTP_HEADER,
operation.getName(),
WSDLConstants.WSDL_MESSAGE_DIRECTION_IN),
WSDLConstants.HTTP_HEADER));
parameterElementList.addAll(getParameterElementListForSOAPModules(doc,
(ArrayList) getBindingPropertyFromMessage(
WSDL2Constants.ATTR_WSOAP_MODULE,
operation.getName(),
WSDLConstants.WSDL_MESSAGE_DIRECTION_IN)));
for (int i = 0; i < parameterElementList.size(); i++) {
inputElt.appendChild((Element) parameterElementList.get(i));
}
/*
* Setting the effective policy of input message
*/
Policy policy = getBindingPolicyFromMessage(bindingOperation,
WSDLConstants.MESSAGE_LABEL_IN_VALUE);
if (policy != null) {
try {
addAttribute(doc, "policy",
PolicyUtil.getSafeString(PolicyUtil.policyComponentToString(policy)),
inputElt);
} catch (Exception ex) {
throw new RuntimeException("can't serialize the policy ..");
}
}
}
return inputElt;
}
/**
* Get the fault element - No header faults are supported
*
* @param doc
* @param operation
*/
protected Element getFaultElement(Document doc, AxisOperation operation) {
Element faultElt = doc.createElement("fault");
Element[] param = getFaultParamElements(doc, operation);
for (int i = 0; i < param.length; i++) {
faultElt.appendChild(param[i]);
}
return faultElt;
}
/**
* Finds the output element.
*
* @param doc
* @param bindingOperation
* @param headerParameterQNameList
*/
protected Element getOutputElement(Document doc,
AxisBindingOperation bindingOperation,
List headerParameterQNameList) {
AxisOperation operation = bindingOperation.getAxisOperation();
Element outputElt = doc.createElement("output");
String mep = operation.getMessageExchangePattern();
if (WSDLUtil.isOutputPresentForMEP(mep)) {
Element param = getOutputParamElement(doc, operation);
if (param != null) {
outputElt.appendChild(param);
}
List outputElementList = getParameterElementList(doc, headerParameterQNameList,
WSDLConstants.SOAP_HEADER);
outputElementList.addAll(getParameterElementListForHttpHeader(doc,
(ArrayList) getBindingPropertyFromMessage(
WSDL2Constants.ATTR_WHTTP_HEADER,
operation.getName(),
WSDLConstants.WSDL_MESSAGE_DIRECTION_OUT),
WSDLConstants.HTTP_HEADER));
for (int i = 0; i < outputElementList.size(); i++) {
outputElt.appendChild((Element) outputElementList.get(i));
}
/*
* Setting the effective policy for the output message.
*/
Policy policy = getBindingPolicyFromMessage(bindingOperation,
WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
if (policy != null) {
try {
addAttribute(doc, "policy",
PolicyUtil.getSafeString(PolicyUtil.policyComponentToString(policy)),
outputElt);
} catch (Exception ex) {
throw new RuntimeException("can't serialize the policy ..");
}
}
}
return outputElt;
}
/**
* @param doc
* @param operation
* @return Returns the parameter element.
*/
protected Element[] getFaultParamElements(Document doc, AxisOperation operation) {
ArrayList params = new ArrayList();
ArrayList faultMessages = operation.getFaultMessages();
if (faultMessages != null && !faultMessages.isEmpty()) {
Element paramElement;
AxisMessage msg;
for (int i = 0; i < faultMessages.size(); i++) {
paramElement = doc.createElement("param");
msg = (AxisMessage) faultMessages.get(i);
if (msg.getElementQName() == null) {
throw new RuntimeException("Element QName is null for " + msg.getName() + "!");
}
//as for the name of a fault, we generate an exception
String faultComment = "";
if (msg.getDocumentation() != null){
faultComment = msg.getDocumentation().trim();
}
addAttribute(doc, "comment", faultComment, paramElement);
addAttribute(doc, "name",
(String) fullyQualifiedFaultClassNameMap.get(msg.getName()),
paramElement);
addAttribute(doc, "shortName",
(String) faultClassNameMap.get(msg.getName()),
paramElement);
// attach the namespace and the localName
addAttribute(doc, "namespace",
msg.getElementQName().getNamespaceURI(),
paramElement);
addAttribute(doc, "localname",
msg.getElementQName().getLocalPart(),
paramElement);
if (msg.getElementQName() != null) {
Element qNameElement = doc.createElement("qname");
addAttribute(doc, "nsuri", msg.getElementQName().getNamespaceURI(), qNameElement);
addAttribute(doc, "localname", msg.getElementQName().getLocalPart(), qNameElement);
paramElement.appendChild(qNameElement);
}
//the type represents the type that will be wrapped by this
//name
String typeMapping =
this.mapper.getTypeMappingName(msg.getElementQName());
addAttribute(doc, "type", (typeMapping == null)
? ""
: typeMapping, paramElement);
//add the short name
addShortType(paramElement, (msg.getElementQName() == null) ? null :
msg.getElementQName().getLocalPart());
String attribValue = (String) instantiatableMessageClassNames.
get(msg.getElementQName());
addAttribute(doc, "instantiatableType",
attribValue == null ? "" : attribValue,
paramElement);
// add an extra attribute to say whether the type mapping is
// the default
if (mapper.getDefaultMappingName().equals(typeMapping)) {
addAttribute(doc, "default", "yes", paramElement);
}
addAttribute(doc, "value", getParamInitializer(typeMapping),
paramElement);
Iterator iter = msg.getExtensibilityAttributes().iterator();
while (iter.hasNext()) {
// process extensibility attributes
}
params.add(paramElement);
}
return (Element[]) params.toArray(new Element[params.size()]);
} else {
return new Element[]{};//return empty array
}
}
/**
* @param doc
* @param operation
* @return Returns the parameter element.
*/
protected Element[] getInputParamElement(Document doc, AxisOperation operation) {
AxisMessage inputMessage = operation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
List paramElementList = new ArrayList();
if (inputMessage != null) {
// This is the wrapped component - add the type mapping
Element mainParameter = generateParamComponent(doc,
this.mapper.getParameterName(
inputMessage.getElementQName()),
this.mapper.getTypeMappingName(
inputMessage.getElementQName()),
operation.getName(),
inputMessage.getElementQName(),
inputMessage.getPartName(),
false,false
);
paramElementList.add(mainParameter);
//if the unwrapping or backWordCompatibility flag is on then we have to
//put the element complex type if it exits
if (this.codeGenConfiguration.isBackwordCompatibilityMode() ||
!this.codeGenConfiguration.isParametersWrapped()) {
if (inputMessage.getParameter(Constants.COMPLEX_TYPE) != null) {
Parameter parameter = inputMessage.getParameter(Constants.COMPLEX_TYPE);
addAttribute(doc, "complextype", (String) parameter.getValue(), mainParameter);
}
}
//added the unwapparameters attribute this is use full to unwrap if paramerters are
//zero
if (!this.codeGenConfiguration.isParametersWrapped()){
addAttribute(doc, "unwrappParameters", "true", mainParameter);
}
// this message has been unwrapped - find the correct references of the
// the message by looking at the unwrapped details object and attach the
// needed parameters inside main parameter element
if (inputMessage.getParameter(Constants.UNWRAPPED_KEY) != null) {
//we have this unwrapped earlier. get the info holder
//and then look at the parameters
Parameter detailsParameter =
inputMessage.getParameter(Constants.UNWRAPPED_DETAILS);
MessagePartInformationHolder infoHolder =
(MessagePartInformationHolder) detailsParameter.getValue();
List partsList = infoHolder.getPartsList();
wrapped_jaxws = true;
//populate the parts list - this list is needed to generate multiple
//parameters in the signatures
for (int i = 0; i < partsList.size(); i++) {
QName qName = (QName) partsList.get(i);
mainParameter.appendChild(generateParamComponent(doc,
this.mapper.getParameterName(
qName),
this.mapper.getTypeMappingName(
qName),
operation.getName(),
qName,
qName.getLocalPart(),
(this.mapper
.getTypeMappingStatus(
qName) !=
null),
Constants.ARRAY_TYPE.equals(
this.mapper.getTypeMappingStatus(
qName)))
);
}
}
}
return (Element[]) paramElementList.toArray(
new Element[paramElementList.size()]);
}
/**
* A convenient method for the generating the parameter element
*
* @param doc
* @param paramName
* @param paramType
* @return DOM Element
*/
protected Element generateParamComponent(Document doc,
String paramName,
String paramType,
QName operationName,
QName paramQName) {
return generateParamComponent(doc, paramName, paramType, operationName, paramQName, null,
false, false);
}
/**
* A convenient method for the generating the parameter element
*
* @param doc
* @param paramName
* @param paramType
* @return DOM Element
*/
protected Element generateParamComponent(Document doc,
String paramName,
String paramType,
QName paramQName) {
return generateParamComponent(doc, paramName, paramType, null, paramQName, null, false,
false);
}
/**
* A convenient method for the generating optionParam components
*
* @param doc
* @param name
* @param value
* @return Element
*/
protected Element generateOptionParamComponent(Document doc, String name, String value) {
Element optionParamElement = doc.createElement("optionParam");
addAttribute(doc, "name", name, optionParamElement);
addAttribute(doc, "value", value, optionParamElement);
return optionParamElement;
}
/**
* A convenient method for the generating the parameter element
*
* @param doc
* @param paramName
* @param paramType
* @param opName
* @param paramName
*/
protected Element generateParamComponent(Document doc,
String paramName,
String paramType,
QName opName,
QName paramQName,
String partName,
boolean isPrimitive,
boolean isArray) {
Element paramElement = doc.createElement("param");
addAttribute(doc, "name",
paramName, paramElement);
if (codeGenConfiguration.getOutputLanguage().equals("jax-ws") && useHolderClass_jaxws) {
Class primitive = JavaUtils.getWrapperClass(paramType);
if(primitive != null){
paramType = primitive.getName();
}
}
addAttribute(doc, "type",
(paramType == null) ? "" : paramType,
paramElement);
//adds the short type
addShortType(paramElement, (paramQName == null) ? null : paramQName.getLocalPart());
// add an extra attribute to say whether the type mapping is the default
if (mapper.getDefaultMappingName().equals(paramType)) {
addAttribute(doc, "default", "yes", paramElement);
}
addAttribute(doc, "value", getParamInitializer(paramType), paramElement);
// add this as a body parameter
addAttribute(doc, "location", "body", paramElement);
//if the opName and partName are present , add them
if (opName != null) {
String localPart = opName.getLocalPart();
addAttribute(doc, "opname", JavaUtils.xmlNameToJava(localPart), paramElement);
}
if (paramQName != null) {
Element qNameElement = doc.createElement("qname");
addAttribute(doc, "nsuri", paramQName.getNamespaceURI(), qNameElement);
addAttribute(doc, "localname", paramQName.getLocalPart(), qNameElement);
paramElement.appendChild(qNameElement);
}
if (partName != null) {
String javaName = null;
if (JavaUtils.isJavaKeyword(partName)) {
javaName = JavaUtils.makeNonJavaKeyword(partName);
} else {
if (codeGenConfiguration.getOutputLanguage().equals("jax-ws")) {
javaName = JavaUtils.xmlNameToJavaIdentifier(JavaUtils.xmlNameToJava(partName));
} else {
javaName = JavaUtils.capitalizeFirstChar(JavaUtils.xmlNameToJava(partName));
}
}
addAttribute(doc, "partname", javaName, paramElement);
}
if (isPrimitive) {
addAttribute(doc, "primitive", "yes", paramElement);
}
if (isArray) {
addAttribute(doc, "array", "yes", paramElement);
}
return paramElement;
}
/**
* @param doc
* @param operation
* @return Returns Element.
*/
protected Element getOutputParamElement(Document doc, AxisOperation operation) {
Element paramElement = doc.createElement("param");
AxisMessage outputMessage = operation.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
String typeMappingStr;
String parameterName;
if (outputMessage != null) {
parameterName = this.mapper.getParameterName(outputMessage.getElementQName());
String typeMapping = this.mapper.getTypeMappingName(outputMessage.getElementQName());
typeMappingStr = (typeMapping == null)
? ""
: typeMapping;
} else {
parameterName = "";
typeMappingStr = "";
}
addAttribute(doc, "name", parameterName, paramElement);
addAttribute(doc, "type", typeMappingStr, paramElement);
//adds the short type
addShortType(paramElement,
(outputMessage.getElementQName() == null) ? null :
outputMessage.getElementQName().getLocalPart());
// add an extra attribute to say whether the type mapping is the default
if (mapper.getDefaultMappingName().equals(typeMappingStr)) {
addAttribute(doc, "default", "yes", paramElement);
}
// add this as a body parameter
addAttribute(doc, "location", "body", paramElement);
String localPart = operation.getName().getLocalPart();
addAttribute(doc, "opname", JavaUtils.xmlNameToJava(localPart), paramElement);
//if the unwrapping or backWordCompatibility flag is on then we have to
//put the element complex type if it exits
if (this.codeGenConfiguration.isBackwordCompatibilityMode() ||
!this.codeGenConfiguration.isParametersWrapped()) {
if (outputMessage.getParameter(Constants.COMPLEX_TYPE) != null) {
Parameter parameter = outputMessage.getParameter(Constants.COMPLEX_TYPE);
addAttribute(doc, "complextype", (String) parameter.getValue(), paramElement);
}
}
String partName = outputMessage.getPartName();
if (partName != null && codeGenConfiguration.getOutputLanguage().equals("jax-ws")) {
String javaName = null;
if (JavaUtils.isJavaKeyword(partName)) {
javaName = JavaUtils.makeNonJavaKeyword(partName);
} else {
javaName = JavaUtils.xmlNameToJavaIdentifier(JavaUtils.xmlNameToJava(partName));
}
addAttribute(doc, "partname", javaName, paramElement);
}
// this message has been unwrapped - find the correct references of the
// the message by looking at the unwrapped details object and attach the
// needed parameters inside main parameter element
if (outputMessage.getParameter(Constants.UNWRAPPED_KEY) != null) {
//we have this unwrapped earlier. get the info holder
//and then look at the parameters
Parameter detailsParameter =
outputMessage.getParameter(Constants.UNWRAPPED_DETAILS);
MessagePartInformationHolder infoHolder =
(MessagePartInformationHolder) detailsParameter.getValue();
List partsList = infoHolder.getPartsList();
//populate the parts list - this list is needed to generate multiple
//parameters in the signatures
// in out put params we only intersted if there is only one parameter
// otherwise we can not unwrap it.
// this logic handles at the template level
QName qName = null;
for (Iterator iter = partsList.iterator(); iter.hasNext();) {
qName = (QName) iter.next();
paramElement.appendChild(generateParamComponent(doc,
this.mapper.getParameterName(qName),
this.mapper.getTypeMappingName(
qName),
operation.getName(),
qName,
qName.getLocalPart(),
(this.mapper.getTypeMappingStatus(
qName) != null),
Constants.ARRAY_TYPE.equals(
this.mapper.getTypeMappingStatus(
qName)))
);
}
}
QName paramQName = outputMessage.getElementQName();
if (paramQName != null) {
Element qNameElement = doc.createElement("qname");
addAttribute(doc, "nsuri", paramQName.getNamespaceURI(), qNameElement);
addAttribute(doc, "localname", paramQName.getLocalPart(), qNameElement);
paramElement.appendChild(qNameElement);
}
return paramElement;
}
/**
* @param paramType
*/
protected String getParamInitializer(String paramType) {
// Look up paramType in the table
String out = (String) constructorMap.get(paramType);
if (out == null) {
out = "null";
}
return out;
}
/**
* @param doc
* @param parameters
* @param location
*/
protected List getParameterElementList(Document doc, List parameters, String location) {
List parameterElementList = new ArrayList();
if ((parameters != null) && !parameters.isEmpty()) {
int count = parameters.size();
for (int i = 0; i < count; i++) {
Element param = doc.createElement("param");
SOAPHeaderMessage header = (SOAPHeaderMessage) parameters.get(i);
QName name = header.getElement();
addAttribute(doc, "name", this.mapper.getParameterName(name), param);
String typeMapping = this.mapper.getTypeMappingName(name);
String typeMappingStr = (typeMapping == null)
? ""
: typeMapping;
addAttribute(doc, "type", typeMappingStr, param);
addAttribute(doc, "location", location, param);
if (header.isMustUnderstand()) {
addAttribute(doc, "mustUnderstand", "true", param);
}
if (name != null) {
Element qNameElement = doc.createElement("qname");
addAttribute(doc, "nsuri", name.getNamespaceURI(), qNameElement);
addAttribute(doc, "localname", name.getLocalPart(), qNameElement);
param.appendChild(qNameElement);
}
parameterElementList.add(param);
}
}
return parameterElementList;
}
protected List getParameterElementListForHttpHeader(Document doc, List parameters,
String location) {
List parameterElementList = new ArrayList();
if ((parameters != null) && !parameters.isEmpty()) {
int count = parameters.size();
for (int i = 0; i < count; i++) {
Element param = doc.createElement("param");
HTTPHeaderMessage httpHeaderMessage = (HTTPHeaderMessage) parameters.get(i);
QName qName = httpHeaderMessage.getqName();
String name = httpHeaderMessage.getName();
// use name as the name attribute of the parameter
addAttribute(doc, "name", JavaUtils.xmlNameToJavaIdentifier(name), param);
// header name is to set the header value
addAttribute(doc, "headername", name, param);
String typeMapping = this.mapper.getTypeMappingName(qName);
String typeMappingStr = (typeMapping == null)
? ""
: typeMapping;
addAttribute(doc, "type", typeMappingStr, param);
addAttribute(doc, "location", location, param);
parameterElementList.add(param);
}
}
return parameterElementList;
}
protected List getParameterElementListForSOAPModules(Document doc, List parameters) {
List parameterElementList = new ArrayList();
if ((parameters != null) && !parameters.isEmpty()) {
int count = parameters.size();
for (int i = 0; i < count; i++) {
Element param = doc.createElement("param");
SOAPModuleMessage soapModuleMessage = (SOAPModuleMessage) parameters.get(i);
// header name is to set the header value
addAttribute(doc, "uri", soapModuleMessage.getUri(), param);
addAttribute(doc, "location", "wsoap_module", param);
parameterElementList.add(param);
}
}
return parameterElementList;
}
/**
* Utility method to add an attribute to a given element.
*
* @param document
* @param eltName
* @param eltValue
* @param element
*/
protected Element addElement(Document document, String eltName, String eltValue,
Element element) {
Element elt = XSLTUtils.addChildElement(document, eltName, element);
if (eltValue != null) {
elt.appendChild(document.createTextNode(eltValue));
}
return elt;
}
}