You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by bi...@apache.org on 2007/10/26 04:06:48 UTC
svn commit: r588466 - in /incubator/cxf/trunk/rt/javascript/src:
main/java/org/apache/cxf/javascript/
main/java/org/apache/cxf/javascript/types/ test/java/org/
test/java/org/apache/ test/java/org/apache/cxf/
test/java/org/apache/cxf/javascript/ test/ja...
Author: bimargulies
Date: Thu Oct 25 19:06:47 2007
New Revision: 588466
URL: http://svn.apache.org/viewvc?rev=588466&view=rev
Log:
More code for the javascript generator, and some trivial error handling code to replace 'printStackTrace' calls.
Added:
incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/BasicNameManager.java
incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NameManager.java
incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties
incubator/cxf/trunk/rt/javascript/src/test/java/org/
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java
incubator/cxf/trunk/rt/javascript/src/test/resources/serializationTestBeans.xml
Modified:
incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java
incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/UnsupportedSchemaConstruct.java
incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java
Added: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/BasicNameManager.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/BasicNameManager.java?rev=588466&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/BasicNameManager.java (added)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/BasicNameManager.java Thu Oct 25 19:06:47 2007
@@ -0,0 +1,70 @@
+/**
+ * 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.cxf.javascript;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.cxf.service.model.SchemaInfo;
+import org.apache.cxf.service.model.ServiceInfo;
+import org.apache.ws.commons.schema.XmlSchemaComplexType;
+import org.apache.ws.commons.schema.utils.NamespacePrefixList;
+
+/**
+ *
+ */
+public class BasicNameManager implements NameManager {
+
+ private Map<String, String> nsPrefixMap;
+
+ public BasicNameManager(ServiceInfo service) {
+ nsPrefixMap = new HashMap<String, String>();
+ Set<String> poorPrefixURIs = new HashSet<String>();
+ for (SchemaInfo schemaInfo : service.getSchemas()) {
+ NamespacePrefixList schemaPrefixList = schemaInfo.getSchema().getNamespaceContext();
+ for (String declaredPrefix : schemaPrefixList.getDeclaredPrefixes()) {
+ String uri = schemaPrefixList.getNamespaceURI(declaredPrefix);
+
+ if (!nsPrefixMap.containsKey(uri)) { // first schema to define a prefix wins.
+ if (declaredPrefix.startsWith("ns") || "tns".equals(declaredPrefix)) {
+ poorPrefixURIs.add(uri);
+ } else {
+ nsPrefixMap.put(uri, declaredPrefix.toUpperCase());
+ }
+ }
+ }
+ }
+
+ for (String uri : poorPrefixURIs) {
+ // this needs more work later. We are bound to annoy someone somehow in this area.
+ String jsPrefix = uri.replace("http:", "").replace("uri:", "").replaceAll("[\\.:/-]", "_");
+ nsPrefixMap.put(uri, jsPrefix.toUpperCase());
+ }
+ }
+
+ /** {@inheritDoc}*/
+ public String getJavascriptName(XmlSchemaComplexType schemaType) {
+ return nsPrefixMap.get(schemaType.getQName().getNamespaceURI())
+ //TODO: the local part of the name may be a problem for JavaScript.
+ + schemaType.getQName().getLocalPart();
+ }
+}
Modified: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java?rev=588466&r1=588465&r2=588466&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java (original)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/JavascriptUtils.java Thu Oct 25 19:06:47 2007
@@ -19,8 +19,14 @@
package org.apache.cxf.javascript;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
import java.util.Stack;
+import org.apache.ws.commons.schema.XmlSchemaSimpleType;
+
/**
*
*/
@@ -29,11 +35,41 @@
private StringBuffer code;
private Stack<String> prefixStack;
private String xmlStringAccumulatorVariable;
+ private Map<String, String> defaultValueForSimpleType;
+ private Set<String> nonStringSimpleTypes;
public JavascriptUtils(StringBuffer code) {
this.code = code;
+ defaultValueForSimpleType = new HashMap<String, String>();
+ defaultValueForSimpleType.put("int", "0");
+ defaultValueForSimpleType.put("long", "0");
+ defaultValueForSimpleType.put("float", "0.0");
+ defaultValueForSimpleType.put("double", "0.0");
+ nonStringSimpleTypes = new HashSet<String>();
+ nonStringSimpleTypes.add("int");
+ nonStringSimpleTypes.add("long");
+ nonStringSimpleTypes.add("float");
+ nonStringSimpleTypes.add("double");
+
prefixStack = new Stack<String>();
- prefixStack.push("");
+ prefixStack.push(" ");
+ }
+
+ public String getDefaultValueForSimpleType(XmlSchemaSimpleType type) {
+ String val = defaultValueForSimpleType.get(type.getName());
+ if (val == null) {
+ return "''";
+ } else {
+ return val;
+ }
+ }
+
+ public boolean isStringSimpleType(XmlSchemaSimpleType type) {
+ return !nonStringSimpleTypes.contains(type.getName());
+ }
+
+ public void setXmlStringAccumulator(String variableName) {
+ xmlStringAccumulatorVariable = variableName;
}
public void startXmlStringAccumulator(String variableName) {
@@ -48,11 +84,22 @@
return value.replaceAll("'", "\\'");
}
+ public String escapeStringQuotes(String data) {
+ return data.replace("'", "\\'");
+ }
+
/**
* emit javascript to append a value to the accumulator.
* @param value
*/
- public void appendAppend(String value) {
+ public void appendString(String value) {
+ code.append(prefix());
+ code.append(xmlStringAccumulatorVariable + " = " + xmlStringAccumulatorVariable + " + '");
+ code.append(escapeStringQuotes(value));
+ code.append("';" + NL);
+ }
+
+ public void appendExpression(String value) {
code.append(prefix());
code.append(xmlStringAccumulatorVariable + " = " + xmlStringAccumulatorVariable + " + ");
code.append(value);
Added: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NameManager.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NameManager.java?rev=588466&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NameManager.java (added)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/NameManager.java Thu Oct 25 19:06:47 2007
@@ -0,0 +1,26 @@
+/**
+ * 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.cxf.javascript;
+
+import org.apache.ws.commons.schema.XmlSchemaComplexType;
+
+public interface NameManager {
+ String getJavascriptName(XmlSchemaComplexType schemaType);
+}
Modified: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/UnsupportedSchemaConstruct.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/UnsupportedSchemaConstruct.java?rev=588466&r1=588465&r2=588466&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/UnsupportedSchemaConstruct.java (original)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/UnsupportedSchemaConstruct.java Thu Oct 25 19:06:47 2007
@@ -18,6 +18,8 @@
*/
package org.apache.cxf.javascript;
+import org.apache.cxf.common.i18n.Message;
+
/**
* This exception is thrown when the Javascript client generator hits a schema
* construct that it cannot handle.
@@ -37,6 +39,10 @@
public UnsupportedSchemaConstruct(String explanation, Throwable cause) {
super(explanation, cause);
+ }
+
+ public UnsupportedSchemaConstruct(Message message) {
+ super(message.toString());
}
}
Added: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties?rev=588466&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties (added)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/Messages.properties Thu Oct 25 19:06:47 2007
@@ -0,0 +1,24 @@
+#
+#
+# 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.
+#
+#
+NON_ELEMENT_CHILD=JavaScript limitation: Non-Element sequence member {0} of {1}. {2}
+NON_SEQUENCE_PARTICLE=JavaScript limitation: Type {0} is not defined as a sequence. {1}
+ABSTRACT_ELEMENT=JavaScript limitation: Abstract element {0} of {1}. {2}
+NULL_PARTICLE=JavaScript limitation: Type {0} has no particle. {1}
Modified: incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java?rev=588466&r1=588465&r2=588466&view=diff
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java (original)
+++ incubator/cxf/trunk/rt/javascript/src/main/java/org/apache/cxf/javascript/types/SchemaJavascriptBuilder.java Thu Oct 25 19:06:47 2007
@@ -19,17 +19,30 @@
package org.apache.cxf.javascript.types;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+
import javax.xml.namespace.QName;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.javascript.JavascriptUtils;
+import org.apache.cxf.javascript.NameManager;
import org.apache.cxf.javascript.UnsupportedSchemaConstruct;
import org.apache.cxf.service.model.SchemaInfo;
import org.apache.cxf.wsdl.WSDLConstants;
import org.apache.ws.commons.schema.XmlSchemaComplexType;
import org.apache.ws.commons.schema.XmlSchemaElement;
import org.apache.ws.commons.schema.XmlSchemaForm;
+import org.apache.ws.commons.schema.XmlSchemaObject;
+import org.apache.ws.commons.schema.XmlSchemaObjectTable;
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.XmlSchemaType;
/**
@@ -38,15 +51,71 @@
* @author bimargulies
*/
public class SchemaJavascriptBuilder {
+
+ private static final Logger LOG = LogUtils.getL7dLogger(SchemaJavascriptBuilder.class);
+
private static final XmlSchemaForm QUALIFIED = new XmlSchemaForm(XmlSchemaForm.QUALIFIED);
+ private static final XmlSchemaForm UNQUALIFIED = new XmlSchemaForm(XmlSchemaForm.UNQUALIFIED);
+
private static final String XSI_NS_ATTR = WSDLConstants.NP_XMLNS + ":"
- + WSDLConstants.NP_SCHEMA_XSI + "=" + WSDLConstants.NU_SCHEMA_XSI;
+ + WSDLConstants.NP_SCHEMA_XSI + "='" + WSDLConstants.NU_SCHEMA_XSI + "'";
private static final String NIL_ATTRIBUTES = XSI_NS_ATTR + " xsi:nil='true'";
// The schema that we are operating upon.
private SchemaInfo schemaInfo;
+ private NameManager nameManager;
+ private Map<String, String> fallbackNamespacePrefixMap;
+ private int nsCounter;
- public SchemaJavascriptBuilder(SchemaInfo schemaInfo) {
+ public SchemaJavascriptBuilder(NameManager nameManager, SchemaInfo schemaInfo) {
+ this.nameManager = nameManager;
this.schemaInfo = schemaInfo;
+ fallbackNamespacePrefixMap = new HashMap<String, String>();
+ }
+
+ // this class assumes that the rest of the code is not going to try to use the same prefix twice
+ // for two different URIs.
+ private static class NamespacePrefixAccumulator {
+ private StringBuffer attributes;
+ private Set<String> prefixes;
+
+ NamespacePrefixAccumulator() {
+ attributes = new StringBuffer();
+ prefixes = new HashSet<String>();
+ }
+
+ void collect(String prefix, String uri) {
+ if (!prefixes.contains(prefix)) {
+ attributes.append("xmlns:" + prefix + "='" + uri + "' ");
+ prefixes.add(prefix);
+ }
+ }
+
+ String getAttributes() {
+ return attributes.toString();
+ }
+ }
+
+ private String cleanedUpSchemaSource(XmlSchemaType subject) {
+ if (subject.getSourceURI() == null) {
+ return "";
+ } else {
+ return subject.getSourceURI() + ":" + subject.getLineNumber();
+ }
+ }
+
+ private void unsupportedConstruct(String messageKey, XmlSchemaType subject) {
+ Message message = new Message(messageKey, LOG, subject.getQName(),
+ cleanedUpSchemaSource(subject));
+ throw new UnsupportedSchemaConstruct(message);
+
+ }
+
+ private void unsupportedConstruct(String messageKey, String what, XmlSchemaType subject) {
+ Message message = new Message(messageKey, LOG, what, subject.getQName(),
+ cleanedUpSchemaSource(subject));
+ LOG.severe(message.toString());
+ throw new UnsupportedSchemaConstruct(message);
+
}
public static boolean isParticleArray(XmlSchemaParticle particle) {
@@ -57,22 +126,187 @@
return particle.getMinOccurs() == 0 && particle.getMaxOccurs() == 1;
}
- private String xmlElementString(XmlSchemaElement element) {
- return getQNameString(element.getQName());
+ /**
+ * This function obtains a name, perhaps namespace-qualified, for an element.
+ * It also maintains a Map that records all the prefixes used in the course
+ * of working on a single serializer function (and thus a single complex-type-element
+ * XML element) which is used for namespace prefix management.
+ * @param element
+ * @param namespaceMap
+ * @return
+ */
+ private String xmlElementString(XmlSchemaElement element, NamespacePrefixAccumulator accumulator) {
+ QName qname = element.getQName();
+ if (isElementNameQualified(element)) {
+ String prefix = qname.getPrefix();
+ if ("".equals(prefix)) { // this is not quite good enough.
+ prefix = getPrefix(qname.getNamespaceURI());
+ }
+ accumulator.collect(prefix, qname.getNamespaceURI());
+ return prefix + ":" + qname.getLocalPart();
+ } else {
+ return qname.getLocalPart();
+ }
}
- private String getQNameString(QName name) {
- if (schemaInfo.getSchema().getElementFormDefault().equals(QUALIFIED)) {
- return getPrefix(name.getNamespaceURI()) + ":" + name.getLocalPart();
- } else {
- return name.getLocalPart();
+ private boolean isElementNameQualified(XmlSchemaElement element) {
+ if (element.getForm().equals(QUALIFIED)) {
+ return true;
+ }
+ if (element.getForm().equals(UNQUALIFIED)) {
+ return false;
+ }
+ return schemaInfo.getSchema().getElementFormDefault().equals(QUALIFIED);
+ }
+
+ private String getPrefix(String namespaceURI) {
+ String schemaPrefix = schemaInfo.getSchema().getNamespaceContext().getPrefix(namespaceURI);
+ if (schemaPrefix == null || "tns".equals(schemaPrefix)) {
+ schemaPrefix = fallbackNamespacePrefixMap.get(namespaceURI);
+ if (schemaPrefix == null) {
+ schemaPrefix = "jns" + nsCounter;
+ nsCounter++;
+ fallbackNamespacePrefixMap.put(namespaceURI, schemaPrefix);
+ }
}
+ return schemaPrefix;
+ }
+
+ public String generateCodeForSchema(SchemaInfo schema) {
+ StringBuffer code = new StringBuffer();
+ XmlSchemaObjectTable schemaTypes = schema.getSchema().getSchemaTypes();
+ Iterator namesIterator = schemaTypes.getNames();
+ while (namesIterator.hasNext()) {
+ QName name = (QName)namesIterator.next();
+ XmlSchemaObject xmlSchemaObject = (XmlSchemaObject)schemaTypes.getItem(name);
+ if (xmlSchemaObject instanceof XmlSchemaComplexType) {
+ try {
+ XmlSchemaComplexType complexType = (XmlSchemaComplexType)xmlSchemaObject;
+ code.append(complexTypeConstructorAndAccessors(complexType));
+ code.append(complexTypeSerializerFunction(complexType));
+ } catch (UnsupportedSchemaConstruct usc) {
+ continue; // it could be empty, but the style checker would complain.
+ }
+ }
+ }
+
+ return code.toString();
}
+
+ public String complexTypeConstructorAndAccessors(XmlSchemaComplexType type) {
+ StringBuffer code = new StringBuffer();
+ StringBuffer accessors = new StringBuffer();
+ JavascriptUtils utils = new JavascriptUtils(code);
+ XmlSchemaParticle particle = type.getParticle();
+ XmlSchemaSequence sequence = null;
+ final String elementPrefix = "this._";
+
+ String typeObjectName = nameManager.getJavascriptName(type);
+ code.append(typeObjectName + " () {\n");
+
+ if (particle == null) {
+ unsupportedConstruct("NULL_PARTICLE", type);
+ }
+
+ try {
+ sequence = (XmlSchemaSequence) particle;
+ } catch (ClassCastException cce) {
+ unsupportedConstruct("NON_SEQUENCE_PARTICLE", type);
+ }
+
+ for (int i = 0; i < sequence.getItems().getCount(); i++) {
+ XmlSchemaObject thing = sequence.getItems().getItem(i);
+ if (!(thing instanceof XmlSchemaElement)) {
+ unsupportedConstruct("NON_ELEMENT_CHILD", thing.getClass().getSimpleName(), type);
+ }
+
+ XmlSchemaElement elChild = (XmlSchemaElement)thing;
+ XmlSchemaType elType = elChild.getSchemaType();
+ boolean nillable = elChild.isNillable();
+ if (elChild.isAbstract()) {
+ unsupportedConstruct("ABSTRACT_ELEMENT", elChild.getName(), type);
+ }
+
+ // Assume that no lunatic has created multiple elements that differ only by namespace.
+ // if elementForm is unqualified, how can that be valid?
+ String elementName = elementPrefix + elChild.getName();
+
+ String accessorName = typeObjectName + "_get" + elChild.getName();
+ accessors.append(accessorName + "() { return " + elementName + ";}\n");
+ accessors.append(typeObjectName + ".get" + elChild.getName() + " = " + accessorName + ";\n");
+
+ accessorName = typeObjectName + "_set" + elChild.getName();
+ accessors.append(accessorName + "(value) {" + elementName + " = value;}\n");
+ accessors.append(typeObjectName + ".set" + elChild.getName() + " = " + accessorName + ";\n");
+
+ if (isParticleOptional(elChild) || (nillable && !isParticleArray(elChild))) {
+ utils.appendLine(elementName + " = null;");
+ } else if (isParticleArray(elChild)) {
+ utils.appendLine(elementName + " = [];");
+ } else if (elType instanceof XmlSchemaComplexType) {
+ // even for required complex elements, we leave them null.
+ // otherwise, we could end up in a cycle or otherwise miserable. The
+ // application code is responsible for this.
+ utils.appendLine(elementName + " = null;");
+ } else {
+ String defaultValueString = elChild.getDefaultValue();
+ if (defaultValueString == null) {
+ defaultValueString =
+ utils.getDefaultValueForSimpleType((XmlSchemaSimpleType)elChild.getSchemaType());
+ }
+ utils.appendLine(elementName + " = " + defaultValueString + ";");
+ }
+ }
+ code.append("}\n");
+ return code.toString() + "\n" + accessors.toString();
+ }
+
+ /**
+ * Produce a serializer function for a type.
+ * These functions emit the surrounding element XML if the caller supplies an XML element name.
+ * It's not quite as simple as that, though. The element name may need namespace qualification,
+ * and this function will add more namespace prefixes as needed.
+ * @param type
+ * @return
+ */
+ public String complexTypeSerializerFunction(XmlSchemaComplexType type) {
+
+ StringBuffer bodyCode = new StringBuffer();
+ JavascriptUtils bodyUtils = new JavascriptUtils(bodyCode);
+ bodyUtils.setXmlStringAccumulator("xml");
+
+ NamespacePrefixAccumulator prefixAccumulator = new NamespacePrefixAccumulator();
+ complexTypeSerializerBody(type, "this._", bodyUtils, prefixAccumulator);
+
+ StringBuffer code = new StringBuffer();
+ JavascriptUtils utils = new JavascriptUtils(code);
+ String functionName = nameManager.getJavascriptName(type) + "_" + "serialize";
+ code.append(functionName + "(elementName) {\n");
+ utils.startXmlStringAccumulator("xml");
+ utils.startIf("elementName != null");
+ utils.appendString("<");
+ utils.appendExpression("elementName");
+ // now add any accumulated namespaces.
+ String moreNamespaces = prefixAccumulator.getAttributes();
+ if (moreNamespaces.length() > 0) {
+ utils.appendString(" ");
+ utils.appendString(moreNamespaces);
+ }
+ utils.appendString(">");
+ utils.endBlock();
+ code.append(bodyCode);
+ utils.startIf("elementName != null");
+ utils.appendString("</");
+ utils.appendExpression("elementName");
+ utils.appendString(">");
+ utils.endBlock();
+ code.append("}\n");
- private String getPrefix(String string) {
- return schemaInfo.getSchema().getNamespaceContext().getPrefix(string);
+ code.append(nameManager.getJavascriptName(type) + ".serialize = " + functionName + ";\n");
+ return code.toString();
}
+
/**
* Build the serialization code for a complex type. At the top level, this operates on single items,
@@ -80,35 +314,31 @@
* it manages optional elements and arrays.
* @param type
* @param elementPrefix
+ * @param bodyNamespaceURIs
* @return
*/
- public void complexTypeSerializerBody(XmlSchemaComplexType type,
+ protected void complexTypeSerializerBody(XmlSchemaComplexType type,
String elementPrefix,
- StringBuffer code) {
- JavascriptUtils utils = new JavascriptUtils(code);
+ JavascriptUtils utils,
+ NamespacePrefixAccumulator prefixAccumulator) {
+
XmlSchemaParticle particle = type.getParticle();
XmlSchemaSequence sequence = null;
- try {
- sequence = (XmlSchemaSequence) particle;
- } catch (ClassCastException cce) {
- throw new UnsupportedSchemaConstruct("Cannot build serializer for " + particle.toString());
- }
-
- utils.startXmlStringAccumulator("xml");
+ sequence = (XmlSchemaSequence) particle;
// XML Schema, please meet Iterable (not).
for (int i = 0; i < sequence.getItems().getCount(); i++) {
XmlSchemaElement elChild = (XmlSchemaElement)sequence.getItems().getItem(i);
XmlSchemaType elType = elChild.getSchemaType();
boolean nillable = elChild.isNillable();
- if (elChild.isAbstract()) {
- throw new UnsupportedSchemaConstruct("Abstract element " + elChild.toString());
+ if (elChild.isAbstract()) {
+ unsupportedConstruct("ABSTRACT_ELEMENT", elChild.getName(), type);
}
// assume that no lunatic has created multiple elements that differ only by namespace.
// or, perhaps, detect that when generating the parser?
String elementName = elementPrefix + elChild.getName();
- String elementXmlRef = xmlElementString(elChild);
+ String elementXmlRef = xmlElementString(elChild, prefixAccumulator);
// first question: optional?
if (isParticleOptional(elChild)) {
@@ -119,7 +349,7 @@
// and nillable in the array case applies to the elements.
if (nillable && !isParticleArray(elChild)) {
utils.startIf(elementName + " == null");
- utils.appendAppend("<" + elementXmlRef + " " + NIL_ATTRIBUTES + "/>");
+ utils.appendString("<" + elementXmlRef + " " + NIL_ATTRIBUTES + "/>");
utils.appendElse();
}
@@ -129,20 +359,24 @@
// we need an extra level of 'nil' testing here. Or do we, depending on the type structure?
// Recode and fiddle appropriately.
utils.startIf(elementName + " == null");
- utils.appendAppend("<" + elementXmlRef + " " + NIL_ATTRIBUTES + "/>");
+ utils.appendString("<" + elementXmlRef + " " + NIL_ATTRIBUTES + "/>");
utils.appendElse();
}
// now for the thing itself.
- utils.appendAppend("<" + elementXmlRef + ">");
if (elType instanceof XmlSchemaComplexType) {
- utils.appendAppend(elementName + ".serialize()");
+ utils.appendExpression(elementName + ".serialize(" + elementXmlRef + ")");
} else {
+ utils.appendString("<" + elementXmlRef + ">");
// warning: this assumes that ordinary Javascript serialization is all we need.
// except for > ad all of that.
- utils.appendAppend("cxf_xml_serialize_string(" + elementName + ")");
+ if (utils.isStringSimpleType((XmlSchemaSimpleType)elType)) {
+ utils.appendExpression("cxf_xml_serialize_string(" + elementName + ")");
+ } else {
+ utils.appendExpression(elementName);
+ }
+ utils.appendString("</" + elementXmlRef + ">");
}
- utils.appendAppend("</" + elementXmlRef + ">");
if (isParticleArray(elChild)) {
utils.endBlock(); // for the extra level of nil checking, which might be wrong.
Added: incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java?rev=588466&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java (added)
+++ incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/types/SerializationTests.java Thu Oct 25 19:06:47 2007
@@ -0,0 +1,73 @@
+/**
+ * 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.cxf.javascript.types;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.javascript.BasicNameManager;
+import org.apache.cxf.javascript.NameManager;
+import org.apache.cxf.service.Service;
+import org.apache.cxf.service.model.SchemaInfo;
+import org.apache.cxf.service.model.ServiceInfo;
+import org.apache.cxf.test.TestUtilities;
+import org.junit.Test;
+import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
+
+public class SerializationTests extends AbstractDependencyInjectionSpringContextTests {
+ private TestUtilities testUtilities;
+
+ public SerializationTests() {
+ testUtilities = new TestUtilities(getClass());
+ }
+
+ @Override
+ protected String[] getConfigLocations() {
+ return new String[] {"classpath:serializationTestBeans.xml"};
+ }
+
+ @Test
+ public void testSerialization() throws Exception {
+ testUtilities.setBus((Bus)applicationContext.getBean("cxf"));
+ testUtilities.addDefaultNamespaces();
+ Server server = testUtilities.getServerForService(new QName("http://apache.org/type_test/doc",
+ "TypeTestPortTypeService"));
+ Service service = server.getEndpoint().getService();
+ List<ServiceInfo> serviceInfos = service.getServiceInfos();
+ // there can only be one.
+ assertEquals(1, serviceInfos.size());
+ ServiceInfo serviceInfo = serviceInfos.get(0);
+ Collection<SchemaInfo> schemata = serviceInfo.getSchemas();
+ NameManager nameManager = new BasicNameManager(serviceInfo);
+
+ for (SchemaInfo schema : schemata) {
+ SchemaJavascriptBuilder builder = new SchemaJavascriptBuilder(nameManager, schema);
+ String allThatJavascript = builder.generateCodeForSchema(schema);
+ assertNotNull(allThatJavascript);
+ }
+ }
+
+
+
+}
Added: incubator/cxf/trunk/rt/javascript/src/test/resources/serializationTestBeans.xml
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/test/resources/serializationTestBeans.xml?rev=588466&view=auto
==============================================================================
--- incubator/cxf/trunk/rt/javascript/src/test/resources/serializationTestBeans.xml (added)
+++ incubator/cxf/trunk/rt/javascript/src/test/resources/serializationTestBeans.xml Thu Oct 25 19:06:47 2007
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jaxws="http://cxf.apache.org/jaxws"
+ xmlns:http="http://cxf.apache.org/transports/http/configuration"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+ http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
+ http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd">
+
+ <!-- CXF -->
+ <import resource="classpath:META-INF/cxf/cxf.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-extension-jaxws.xml" />
+ <import resource="classpath:META-INF/cxf/cxf-extension-local.xml" />
+
+ <!-- Services. We use the JAXB test server which handles a lot of types. -->
+ <jaxws:server id="TestServer"
+ serviceClass="org.apache.type_test.doc.TypeTestPortType"
+ address="local://TestService">
+ </jaxws:server>
+</beans>
+