// 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) {
MappingElementBase mapping = (MappingElementBase)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);