|
Axis 2 example source code file (CodeGenerationUtility.java)
The Axis 2 CodeGenerationUtility.java source code
/*
* 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.jibx;
import org.apache.axis2.AxisFault;
import org.apache.axis2.description.AxisMessage;
import org.apache.axis2.description.AxisOperation;
import org.apache.axis2.description.Parameter;
import org.apache.axis2.wsdl.SOAPHeaderMessage;
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.extension.JiBXExtension;
import org.apache.axis2.wsdl.databinding.JavaTypeMapper;
import org.apache.axis2.wsdl.util.Constants;
import org.apache.axis2.wsdl.util.MessagePartInformationHolder;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
import org.apache.ws.commons.schema.XmlSchemaParticle;
import org.apache.ws.commons.schema.XmlSchemaSequence;
import org.apache.ws.commons.schema.XmlSchemaSimpleType;
import org.apache.ws.commons.schema.XmlSchemaSimpleTypeContent;
import org.apache.ws.commons.schema.XmlSchemaSimpleTypeRestriction;
import org.apache.ws.commons.schema.XmlSchemaType;
import org.jibx.binding.model.BindingElement;
import org.jibx.binding.model.ElementBase;
import org.jibx.binding.model.FormatElement;
import org.jibx.binding.model.IncludeElement;
import org.jibx.binding.model.MappingElement;
import org.jibx.binding.model.ModelVisitor;
import org.jibx.binding.model.NamespaceElement;
import org.jibx.binding.model.ValidationContext;
import org.jibx.binding.model.ValidationProblem;
import org.jibx.runtime.JiBXException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Framework-linked code used by JiBX data binding support. This is accessed via reflection from the
* JiBX code generation extension when JiBX data binding is selected. JiBX uses a different approach
* to unwrapping method parameters from that implemented by ADB, and since the ADB technique is
* assumed by all code generation templates this has to create the same data structures. These data
* structures are undocumented, and can only be determined by going through the {@link
* org.apache.axis2.wsdl.codegen.extension.SchemaUnwrapperExtension} and {@link
* org.apache.axis2.wsdl.codegen.emitter.AxisServiceBasedMultiLanguageEmitter} code.
*/
public class CodeGenerationUtility {
private static final String SCHEMA_NAMESPACE = "http://www.w3.org/2001/XMLSchema";
private final CodeGenConfiguration codeGenConfig;
private static HashSet s_primitiveSet = new HashSet();
static {
s_primitiveSet.add("boolean");
s_primitiveSet.add("byte");
s_primitiveSet.add("char");
s_primitiveSet.add("double");
s_primitiveSet.add("float");
s_primitiveSet.add("int");
s_primitiveSet.add("long");
s_primitiveSet.add("short");
s_primitiveSet.add("void");
}
private static HashMap s_wrapperMap = new HashMap();
static {
s_wrapperMap.put("boolean", "Boolean");
s_wrapperMap.put("byte", "Byte");
s_wrapperMap.put("char", "Character");
s_wrapperMap.put("double", "Double");
s_wrapperMap.put("float", "Float");
s_wrapperMap.put("int", "Integer");
s_wrapperMap.put("long", "Long");
s_wrapperMap.put("short", "Short");
}
/** Reserved words for Java (keywords and literals). */
private static final HashSet s_reservedWords = new HashSet();
static {
// keywords
s_reservedWords.add("abstract");
s_reservedWords.add("assert");
s_reservedWords.add("boolean");
s_reservedWords.add("break");
s_reservedWords.add("byte");
s_reservedWords.add("case");
s_reservedWords.add("catch");
s_reservedWords.add("char");
s_reservedWords.add("class");
s_reservedWords.add("const");
s_reservedWords.add("continue");
s_reservedWords.add("default");
s_reservedWords.add("do");
s_reservedWords.add("double");
s_reservedWords.add("else");
s_reservedWords.add("enum");
s_reservedWords.add("extends");
s_reservedWords.add("final");
s_reservedWords.add("finally");
s_reservedWords.add("float");
s_reservedWords.add("for");
s_reservedWords.add("goto");
s_reservedWords.add("if");
s_reservedWords.add("implements");
s_reservedWords.add("import");
s_reservedWords.add("instanceof");
s_reservedWords.add("int");
s_reservedWords.add("interface");
s_reservedWords.add("long");
s_reservedWords.add("native");
s_reservedWords.add("new");
s_reservedWords.add("package");
s_reservedWords.add("private");
s_reservedWords.add("protected");
s_reservedWords.add("public");
s_reservedWords.add("return");
s_reservedWords.add("short");
s_reservedWords.add("static");
s_reservedWords.add("strictfp");
s_reservedWords.add("super");
s_reservedWords.add("switch");
s_reservedWords.add("synchronized");
s_reservedWords.add("this");
s_reservedWords.add("throw");
s_reservedWords.add("throws");
s_reservedWords.add("transient");
s_reservedWords.add("try");
s_reservedWords.add("void");
s_reservedWords.add("volatile");
s_reservedWords.add("while");
// literals
s_reservedWords.add("true");
s_reservedWords.add("false");
s_reservedWords.add("null");
// variable names used by template unwrapped code generation
// TODO change templates to use $xxx names, block generation from WSDL
s_reservedWords.add("true");
s_reservedWords.add("uctx");
s_reservedWords.add("child");
s_reservedWords.add("wrapper");
}
/**
* Constructor.
*
* @param config code generation configuration
*/
public CodeGenerationUtility(CodeGenConfiguration config) {
codeGenConfig = config;
}
/**
* Configure the code generation based on the supplied parameters and WSDL. This first gets type
* mappings from binding definition, then goes through the operations checking the input and
* output messages. If unwrapping is disabled the message element must be handled directly by a
* mapping. If unwrapping is enabled, this checks that the message element is of the proper form
* (a sequence of other elements, which all have maxOccurs="1"). It then generates an unwrapping
* description and adds it to the code generation configuration, where it'll be picked up and
* included in the XML passed to code generation. This also constructs a type mapping, since
* that's required by the base Axis2 code generation. In the case of unwrapped elements, the
* type mapping includes a synthesized qname for each unwrapped parameter, and the detailed
* information is set on the message information. Sound confusing? Welcome to Axis2 code
* generation.
*
* @param path binding path (<code>null if none)
*/
public void engage(String path) {
// make sure the binding definition file is present, if passed
File file = null;
if (path != null) {
file = new File(path);
if (!file.exists()) {
throw new RuntimeException("jibx binding definition file " + path + " not found");
}
}
try {
// set flag for unwrapping
boolean unwrap = !codeGenConfig.isParametersWrapped();
// initialize the binding information
BindingElement binding = null;
if (file == null) {
// unwrapped can be used without a binding, but wrapped requires one
if (!unwrap) {
throw new RuntimeException(
"JiBX wrapped support requires a binding definition to be provided using the -E" +
JiBXExtension.BINDING_PATH_OPTION + " {file-path} parameter");
}
} else {
// Read the JiBX binding definition into memory. The binding definition
// is only prevalidated so as not to require the user to have all
// the referenced classes in the classpath, though this does make for
// added work in finding the namespaces.
ValidationContext vctx = BindingElement.newValidationContext();
binding = BindingElement.readBinding(new FileInputStream(file), path, vctx);
binding.setBaseUrl(file.toURL());
vctx.setBindingRoot(binding);
IncludePrevalidationVisitor ipv = new IncludePrevalidationVisitor(vctx);
vctx.tourTree(binding, ipv);
if (vctx.getErrorCount() != 0 || vctx.getFatalCount() != 0) {
ArrayList probs = vctx.getProblems();
System.err.println("Errors in generated binding:");
for (int j = 0; j < probs.size(); j++) {
ValidationProblem prob = (ValidationProblem)probs.get(j);
System.err.print(prob.getSeverity() >=
ValidationProblem.ERROR_LEVEL ? "Error: " : "Warning: ");
System.err.println(prob.getDescription());
}
throw new RuntimeException("invalid jibx binding definition file " + path);
}
}
// create table with all built-in format definitions
Map simpleTypeMap = new HashMap();
buildFormat("byte", "byte",
"org.jibx.runtime.Utility.serializeByte",
"org.jibx.runtime.Utility.parseByte", "0", simpleTypeMap);
buildFormat("unsignedShort", "char",
"org.jibx.runtime.Utility.serializeChar",
"org.jibx.runtime.Utility.parseChar", "0", simpleTypeMap);
buildFormat("double", "double",
"org.jibx.runtime.Utility.serializeDouble",
"org.jibx.runtime.Utility.parseDouble", "0.0", simpleTypeMap);
buildFormat("float", "float",
"org.jibx.runtime.Utility.serializeFloat",
"org.jibx.runtime.Utility.parseFloat", "0.0", simpleTypeMap);
buildFormat("int", "int",
"org.jibx.runtime.Utility.serializeInt",
"org.jibx.runtime.Utility.parseInt", "0", simpleTypeMap);
buildFormat("long", "long",
"org.jibx.runtime.Utility.serializeLong",
"org.jibx.runtime.Utility.parseLong", "0", simpleTypeMap);
buildFormat("short", "short",
"org.jibx.runtime.Utility.serializeShort",
"org.jibx.runtime.Utility.parseShort", "0", simpleTypeMap);
buildFormat("boolean", "boolean",
"org.jibx.runtime.Utility.serializeBoolean",
"org.jibx.runtime.Utility.parseBoolean", "false",
simpleTypeMap);
buildFormat("dateTime", "java.util.Date",
"org.jibx.runtime.Utility.serializeDateTime",
"org.jibx.runtime.Utility.deserializeDateTime", null,
simpleTypeMap);
buildFormat("date", "java.sql.Date",
"org.jibx.runtime.Utility.serializeSqlDate",
"org.jibx.runtime.Utility.deserializeSqlDate", null,
simpleTypeMap);
buildFormat("time", "java.sql.Time",
"org.jibx.runtime.Utility.serializeSqlTime",
"org.jibx.runtime.Utility.deserializeSqlTime", null,
simpleTypeMap);
buildFormat("base64Binary", "byte[]",
"org.jibx.runtime.Utility.serializeBase64",
"org.jibx.runtime.Utility.deserializeBase64", null,
simpleTypeMap);
buildFormat("string", "java.lang.String", null, null, null,
simpleTypeMap);
// collect all the top-level mapping and format definitions
Map elementMap = new HashMap();
Map complexTypeMap = new HashMap();
Map bindingMap = new HashMap();
if (binding != null) {
collectTopLevelComponents(binding, "", elementMap,
complexTypeMap, simpleTypeMap, bindingMap);
}
// make sure classes will be generated for abstract mappings
if (unwrap && complexTypeMap.size() > 0 && (binding == null || !binding.isForceClasses())) {
throw new RuntimeException(
"unwrapped binding must use force-classes='true' option in " + path);
}
// force off inappropriate option (set by error in options handling)
codeGenConfig.setPackClasses(false);
// configure handling for all operations of service
codeGenConfig.setTypeMapper(new NamedParameterTypeMapper());
Iterator operations = codeGenConfig.getAxisService().getOperations();
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
int opindex = 0;
Map typeMappedClassMap = new HashMap();
String mappedclass = null;
Set objins = new HashSet();
Set objouts = new HashSet();
Set objfaults = new HashSet();
Map nsMap = new HashMap();
ArrayList wrappers = new ArrayList();
while (operations.hasNext()) {
// get the basic operation information
AxisOperation op = (AxisOperation)operations.next();
String mep = op.getMessageExchangePattern();
AxisMessage inmsg = null;
AxisMessage outmsg = null;
if (WSDLUtil.isInputPresentForMEP(mep)) {
inmsg = op.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
if (inmsg == null) {
throw new RuntimeException(
"Expected input message not found for operation " + op.getName());
}
ArrayList headers = inmsg.getSoapHeaders();
for (int i = 0; i < headers.size(); i++) {
SOAPHeaderMessage header = (SOAPHeaderMessage)headers.get(i);
String cname = mapMessage(header, elementMap);
objins.add(cname);
if (mappedclass == null && isLookupClass(cname)) {
mappedclass = cname;
}
}
}
if (WSDLUtil.isOutputPresentForMEP(mep)) {
outmsg = op.getMessage(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
if (outmsg == null) {
throw new RuntimeException(
"Expected output message not found for operation " + op.getName());
}
ArrayList headers = outmsg.getSoapHeaders();
for (int i = 0; i < headers.size(); i++) {
SOAPHeaderMessage header = (SOAPHeaderMessage)headers.get(i);
String cname = mapMessage(header, elementMap);
objouts.add(cname);
if (mappedclass == null && isLookupClass(cname)) {
mappedclass = cname;
}
}
}
if (unwrap) {
// use unwrapping for both input and output
String receivername = "jibxReceiver" + opindex++;
Element dbmethod = doc.createElement("dbmethod");
dbmethod.setAttribute("receiver-name", receivername);
dbmethod.setAttribute("method-name", op.getName().getLocalPart());
Set nameset = new HashSet(s_reservedWords);
if (inmsg != null) {
Element wrapper = unwrapMessage(inmsg, false, simpleTypeMap, elementMap,
complexTypeMap, typeMappedClassMap,
bindingMap, nameset, nsMap, doc);
dbmethod.appendChild(wrapper);
wrappers.add(wrapper);
}
if (outmsg != null) {
Element wrapper = unwrapMessage(outmsg, true, simpleTypeMap, elementMap,
complexTypeMap, typeMappedClassMap,
bindingMap, nameset, nsMap, doc);
dbmethod.appendChild(wrapper);
wrappers.add(wrapper);
}
// save unwrapping information for use in code generation
op.addParameter(
new Parameter(Constants.DATABINDING_GENERATED_RECEIVER, receivername));
op.addParameter(new Parameter(Constants.DATABINDING_GENERATED_IMPLEMENTATION,
Boolean.TRUE));
op.addParameter(
new Parameter(Constants.DATABINDING_OPERATION_DETAILS, dbmethod));
} else {
// concrete mappings, just save the mapped class name(s)
if (inmsg != null) {
String cname = mapMessage(inmsg, elementMap);
objins.add(cname);
if (mappedclass == null && isLookupClass(cname)) {
mappedclass = cname;
}
}
if (outmsg != null) {
String cname = mapMessage(outmsg, elementMap);
objouts.add(cname);
if (mappedclass == null && isLookupClass(cname)) {
mappedclass = cname;
}
}
}
// always handle faults as wrapped
for (Iterator iter = op.getFaultMessages().iterator(); iter.hasNext();) {
String cname = mapMessage((AxisMessage)iter.next(), elementMap);
objfaults.add(cname);
if (mappedclass == null && isLookupClass(cname)) {
mappedclass = cname;
}
}
}
// check for default namespace usage within bindings or wrappers
// (meaning we can't declare a conflicting default namespace)
Collection prefixes = nsMap.values();
boolean dfltns = prefixes.contains("");
boolean wrapdflt = false;
if (!dfltns) {
for (int i = 0; i < wrappers.size(); i++) {
Element wrapper = (Element)wrappers.get(i);
if ("true".equals(wrapper.getAttribute("uses-default"))) {
wrapdflt = true;
break;
}
}
}
// find a prefix that we can use where needed for extra namespace
String xtrapref = "";
if (dfltns || wrapdflt) {
xtrapref = "_";
int index = 0;
while (prefixes.contains(xtrapref)) {
xtrapref = "_" + index++;
}
}
// for each wrapper (input and output), determine what additional
// namespaces need to be declared, what prefix is to be used for
// the wrapper element, and what prefix to be used for each child
// element
for (int i = 0; i < wrappers.size(); i++) {
Element wrapper = (Element)wrappers.get(i);
boolean addns = false;
String ns = wrapper.getAttribute("ns");
String prefix = "";
if ("true".equals(wrapper.getAttribute("need-namespaces"))) {
// check extra definition needed for wrapper namespace
if (!"".equals(ns)) {
if (dfltns || wrapdflt) {
// need a namespace, can't be default, get or set it
prefix = (String)nsMap.get(ns);
if (prefix == null) {
prefix = xtrapref;
addns = true;
}
} else {
// just make the wrapper namespace the default
prefix = "";
addns = true;
}
}
wrapper.setAttribute("prefix", prefix);
// set prefixes for child elements of wrapper
Node node = wrapper.getFirstChild();
while (node != null) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element)node;
String lname = element.getNodeName();
if ("parameter-element".equals(lname) || "return-element".equals(lname))
{
String childns = element.getAttribute("ns");
if ("".equals(childns)) {
element.setAttribute("prefix", "");
} else if (ns.equals(childns)) {
element.setAttribute("prefix", prefix);
} else {
String childprefix = (String)nsMap.get(childns);
if (childprefix == null) {
throw new RuntimeException("Unable to set namespace " +
childns + " for child element");
}
element.setAttribute("prefix", childprefix);
}
}
}
node = node.getNextSibling();
}
} else {
// check extra definition needed for wrapper namespace
if (!"".equals(ns)) {
// just make the wrapper namespace the default
prefix = "";
addns = true;
}
wrapper.setAttribute("prefix", prefix);
// set prefixes for child elements of wrapper
Node node = wrapper.getFirstChild();
while (node != null) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element)node;
String lname = element.getNodeName();
if ("parameter-element".equals(lname) || "return-element".equals(lname))
{
String childns = element.getAttribute("ns");
if ("".equals(childns)) {
element.setAttribute("prefix", "");
} else if (ns.equals(childns)) {
element.setAttribute("prefix", prefix);
} else {
throw new RuntimeException("Unable to set namespace " +
childns + " for child element");
}
}
}
node = node.getNextSibling();
}
}
if (addns) {
Element addedns = doc.createElement("extra-namespace");
addedns.setAttribute("ns", ns);
addedns.setAttribute("prefix", prefix);
wrapper.appendChild(addedns);
}
}
// add type usage information for binding initialization
List details = new ArrayList();
Element bindinit = doc.createElement("initialize-binding");
if (!typeMappedClassMap.isEmpty()) {
for (Iterator iter = typeMappedClassMap.keySet().iterator(); iter.hasNext();) {
QName tname = (QName)iter.next();
String clsindex = ((Integer)typeMappedClassMap.get(tname)).toString();
Element detail = doc.createElement("abstract-type");
detail.setAttribute("ns", tname.getNamespaceURI());
detail.setAttribute("name", tname.getLocalPart());
detail.setAttribute("type-index", clsindex);
bindinit.appendChild(detail);
if (mappedclass == null) {
MappingElement mapping = (MappingElement)complexTypeMap.get(tname);
mappedclass = mapping.getClassName();
}
}
}
// set binding lookup parameters
if (binding != null && binding.getName() != null && binding.getTargetPackage() != null) {
bindinit.setAttribute("binding-name", binding.getName());
bindinit.setAttribute("binding-package", binding.getTargetPackage());
} else {
if (mappedclass == null) {
mappedclass = "";
}
bindinit.setAttribute("bound-class", mappedclass);
}
// include binding namespaces in initialization data
for (Iterator iter = nsMap.keySet().iterator(); iter.hasNext();) {
String ns = (String)iter.next();
String prefix = (String)nsMap.get(ns);
Element detail = doc.createElement("binding-namespace");
detail.setAttribute("ns", ns);
detail.setAttribute("prefix", prefix);
bindinit.appendChild(detail);
}
details.add(bindinit);
// add details for all objects used as inputs/outputs/faults
for (Iterator iter = objins.iterator(); iter.hasNext();) {
String classname = (String)iter.next();
Element detail = doc.createElement("object-input");
detail.setAttribute("type", classname);
details.add(detail);
}
for (Iterator iter = objouts.iterator(); iter.hasNext();) {
String classname = (String)iter.next();
Element detail = doc.createElement("object-output");
detail.setAttribute("type", classname);
details.add(detail);
}
for (Iterator iter = objfaults.iterator(); iter.hasNext();) {
String classname = (String)iter.next();
Element detail = doc.createElement("object-fault");
detail.setAttribute("type", classname);
details.add(detail);
}
codeGenConfig.getAxisService()
.addParameter(new Parameter(Constants.DATABINDING_SERVICE_DETAILS, details));
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (JiBXException e) {
throw new RuntimeException(e);
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
} catch (AxisFault e) {
throw new RuntimeException(e);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
/**
* Check if a class is potentially usable for looking up binding information.
*
* @param type fully-qualified type name
* @return <code>true if potentially usable,
Other Axis 2 examples (source code examples)Here is a short list of links related to this Axis 2 CodeGenerationUtility.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.