/*
* Copyright 2003,2004 The Apache Software Foundation
*
* Licensed 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.ws.jaxme.generator.sg.impl;
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 javax.xml.bind.JAXBException;
import javax.xml.bind.ValidationEvent;
import javax.xml.namespace.QName;
import org.apache.ws.jaxme.JMXmlSerializer;
import org.apache.ws.jaxme.ValidationEvents;
import org.apache.ws.jaxme.WildcardAttribute;
import org.apache.ws.jaxme.generator.SchemaReader;
import org.apache.ws.jaxme.generator.sg.AttributeSG;
import org.apache.ws.jaxme.generator.sg.AttributeSGChain;
import org.apache.ws.jaxme.generator.sg.ComplexContentSG;
import org.apache.ws.jaxme.generator.sg.ComplexContentSGChain;
import org.apache.ws.jaxme.generator.sg.ComplexTypeSG;
import org.apache.ws.jaxme.generator.sg.ComplexTypeSGChain;
import org.apache.ws.jaxme.generator.sg.Context;
import org.apache.ws.jaxme.generator.sg.GroupSG;
import org.apache.ws.jaxme.generator.sg.ParticleSG;
import org.apache.ws.jaxme.generator.sg.SGlet;
import org.apache.ws.jaxme.generator.sg.SimpleContentSG;
import org.apache.ws.jaxme.generator.sg.SimpleContentSGChain;
import org.apache.ws.jaxme.generator.sg.TypeSG;
import org.apache.ws.jaxme.impl.JMHandlerImpl;
import org.apache.ws.jaxme.impl.JMXmlSerializerImpl;
import org.apache.ws.jaxme.js.DirectAccessible;
import org.apache.ws.jaxme.js.JavaField;
import org.apache.ws.jaxme.js.JavaMethod;
import org.apache.ws.jaxme.js.JavaQName;
import org.apache.ws.jaxme.js.JavaQNameImpl;
import org.apache.ws.jaxme.js.JavaSource;
import org.apache.ws.jaxme.js.JavaSourceFactory;
import org.apache.ws.jaxme.js.LocalJavaField;
import org.apache.ws.jaxme.js.Parameter;
import org.apache.ws.jaxme.js.PlaceHolder;
import org.apache.ws.jaxme.logging.Logger;
import org.apache.ws.jaxme.logging.LoggerAccess;
import org.apache.ws.jaxme.xs.XSAttributable;
import org.apache.ws.jaxme.xs.XSAttribute;
import org.apache.ws.jaxme.xs.XSComplexType;
import org.apache.ws.jaxme.xs.XSType;
import org.apache.ws.jaxme.xs.XSWildcard;
import org.apache.ws.jaxme.xs.xml.XsQName;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.AttributesImpl;
/**
* @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
* @author <a href="mailto:iasandcb@tmax.co.kr">Ias</a>
*/
public class JAXBComplexTypeSG implements ComplexTypeSGChain {
private final static Logger log = LoggerAccess.getLogger(JAXBComplexTypeSG.class);
private final TypeSG typeSG;
private final XSType xsType;
private final boolean hasSimpleContent;
private final Context classContext;
private SimpleContentSG simpleContentSG;
private ComplexContentSG complexContentSG;
private AttributeSG[] attributes;
protected JAXBComplexTypeSG(TypeSG pTypeSG, XSType pType) throws SAXException {
final String mName = "<init>(XSType)";
log.finest(mName, "->", new Object[]{pTypeSG, pType});
typeSG = pTypeSG;
xsType = pType;
XSComplexType complexType= pType.getComplexType();
hasSimpleContent = complexType.hasSimpleContent();
String suffix = pTypeSG.isGlobalType() ? null : "Type";
classContext = new GlobalContext(pTypeSG.getName(), pType, null, suffix, pTypeSG.getSchema());
log.finest(mName, "<-", classContext);
}
/** <p>Constructor for a local type, which is embedded into the enclosing
* <code>pContext</code>.</p>
*/
protected JAXBComplexTypeSG(TypeSG pTypeSG, XSType pType, Context pContext) throws SAXException {
final String mName = "<init>(XSType)";
log.finest(mName, "->", new Object[]{pTypeSG, pType, pContext});
typeSG = pTypeSG;
xsType = pType;
XSComplexType complexType= pType.getComplexType();
hasSimpleContent = complexType.hasSimpleContent();
classContext = new LocalContext(pContext, pTypeSG.getName().getLocalName(), pType, null, "Type",
pTypeSG.getSchema());
log.finest(mName, "<-", classContext);
}
public Object newAttributeSG(ComplexTypeSG pController, XSAttribute pAttribute) throws SAXException {
return new JAXBAttributeSG(typeSG.getSchema(), pAttribute, classContext);
}
public Object newAttributeSG(ComplexTypeSG pController, XSWildcard pWildcard) throws SAXException {
return new JAXBAttributeSG(typeSG.getSchema(), pWildcard, classContext);
}
private AttributeSG[] initAttributes(ComplexTypeSG pController) throws SAXException {
XSAttributable[] xsAttributes = xsType.getComplexType().getAttributes();
List attributeList = new ArrayList();
for (int i = 0; i < xsAttributes.length; i++) {
AttributeSGChain attrChain;
if (xsAttributes[i] instanceof XSAttribute) {
XSAttribute attr = (XSAttribute) xsAttributes[i];
attrChain = (AttributeSGChain) pController.newAttributeSG(attr);
} else if (xsAttributes[i] instanceof XSWildcard) {
boolean isSupportingExtensions = false;
SchemaReader schemaReader = pController.getTypeSG().getFactory().getGenerator().getSchemaReader();
if (schemaReader instanceof JAXBSchemaReader) {
isSupportingExtensions = ((JAXBSchemaReader) schemaReader).isSupportingExtensions();
}
if (isSupportingExtensions) {
XSWildcard wildcard = (XSWildcard) xsAttributes[i];
attrChain = (AttributeSGChain) pController.newAttributeSG(wildcard);
} else {
throw new SAXParseException("Extensions must be enabled to support wildcard attributes (JAXB 1.0, App. E.2.1.1)",
((XSWildcard) xsAttributes[i]).getLocator());
}
} else {
throw new IllegalStateException("Unknown attribute type: " + xsAttributes[i].getClass().getName());
}
AttributeSG attrSG = new AttributeSGImpl(attrChain);
attrSG.init();
attributeList.add(attrSG);
}
return (AttributeSG[]) attributeList.toArray(new AttributeSG[attributeList.size()]);
}
public void addAttributeSG(ComplexTypeSG pController, AttributeSG pAttribute) throws SAXException {
AttributeSG[] result = new AttributeSG[attributes.length+1];
System.arraycopy(attributes, 0, result, 0, attributes.length);
result[attributes.length] = pAttribute;
attributes = result;
pAttribute.init();
}
public void init(ComplexTypeSG pController) throws SAXException {
attributes = initAttributes(pController);
if (pController.hasSimpleContent()) {
SimpleContentSGChain chain = (SimpleContentSGChain) pController.newSimpleContentTypeSG();
simpleContentSG = new SimpleContentSGImpl(chain);
simpleContentSG.init();
} else {
ComplexContentSGChain chain = (ComplexContentSGChain) pController.newComplexContentTypeSG();
complexContentSG = new ComplexContentSGImpl(chain);
complexContentSG.init();
}
}
public boolean hasSimpleContent(ComplexTypeSG pController) { return hasSimpleContent; }
public TypeSG getTypeSG(ComplexTypeSG pController) { return typeSG; }
public boolean hasAttributes(ComplexTypeSG pController) {
return attributes.length != 0;
}
public AttributeSG[] getAttributes(ComplexTypeSG pController) {
return attributes;
}
public Context getClassContext(ComplexTypeSG pController) { return classContext; }
public Locator getLocator(ComplexTypeSG pController) { return xsType.getLocator(); }
private void generateProperties(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
AttributeSG[] myAttributes = pController.getAttributes();
for (int i = 0; i < myAttributes.length; i++) {
myAttributes[i].getPropertySG().generate(pSource);
}
if (pController.hasSimpleContent()) {
pController.getSimpleContentSG().getPropertySG().generate(pSource);
} else {
GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
if (groupSG != null) { // Check required, in case the element doesn't have any childs
groupSG.generateProperties(pSource);
}
}
}
public JavaSource getXMLInterface(ComplexTypeSG pController) throws SAXException {
final String mName = "getXMLInterface";
log.finest(mName, "->");
JavaQName qName = pController.getClassContext().getXMLInterfaceName();
JavaSourceFactory jsf = pController.getTypeSG().getSchema().getJavaSourceFactory();
JavaSource js = jsf.newJavaSource(qName, JavaSource.PUBLIC);
js.setType(JavaSource.INTERFACE);
generateProperties(pController, js);
if (!pController.hasSimpleContent()) {
GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
if (groupSG != null) { // Check required, in case the element doesn't have any childs
groupSG.generateXMLInterfaceSubclasses(js);
}
}
log.finest(mName, "<-", js.getQName());
return js;
}
public JavaSource getXMLInterface(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
final String mName = "getXMLInterface(JavaSource)";
log.finest(mName, "->", pSource.getQName());
JavaQName qName = pController.getClassContext().getXMLInterfaceName();
JavaSource js = pSource.newJavaInnerClass(qName.getClassName(), JavaSource.PUBLIC);
js.setType(JavaSource.INTERFACE);
generateProperties(pController, js);
if (!pController.hasSimpleContent()) {
GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
if (groupSG != null) { // Check required, in case the element doesn't have any childs
groupSG.generateXMLInterfaceSubclasses(js);
}
}
log.finest(mName, "<-", js.getQName());
return js;
}
public JavaSource getXMLImplementation(ComplexTypeSG pController) throws SAXException {
final String mName = "getXMLImplementation(JavaQName)";
log.finest(mName, "->", typeSG.getName());
JavaSourceFactory jsf = pController.getTypeSG().getSchema().getJavaSourceFactory();
JavaSource js = jsf.newJavaSource(pController.getClassContext().getXMLImplementationName(), JavaSource.PUBLIC);
js.addImplements(pController.getClassContext().getXMLInterfaceName());
SerializableSG.makeSerializable(pController.getTypeSG().getSchema(), js);
generateProperties(pController, js);
if (!pController.hasSimpleContent()) {
GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
if (groupSG != null) { // Check required, in case the element doesn't have any childs
groupSG.generateXMLImplementationSubclasses(js);
}
}
log.finest(mName, "<-", js.getQName());
return js;
}
public JavaSource getXMLImplementation(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
final String mName = "getXMLImplementation(JavaQName,JavaSource)";
log.finest(mName, "->", pSource.getQName());
JavaSource js = pSource.newJavaInnerClass(pController.getClassContext().getXMLImplementationName().getInnerClassName(), JavaSource.PUBLIC);
js.setStatic(true);
js.addImplements(pController.getClassContext().getXMLInterfaceName());
SerializableSG.makeSerializable(pController.getTypeSG().getSchema(), js);
generateProperties(pController, js);
if (!pController.hasSimpleContent()) {
GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
if (groupSG != null) { // Check required, in case the element doesn't have any childs
groupSG.generateXMLImplementationSubclasses(js);
}
}
log.finest(mName, "<-", js.getQName());
return js;
}
public JavaSource getXMLSerializer(ComplexTypeSG pController) throws SAXException {
final String mName = "getXMLSerializer";
log.finest(mName, "->", typeSG.getName());
JavaQName xmlSerializerName = pController.getClassContext().getXMLSerializerName();
JavaSourceFactory jsf = typeSG.getSchema().getJavaSourceFactory();
JavaSource js = jsf.newJavaSource(xmlSerializerName, JavaSource.PUBLIC);
js.addExtends(JMXmlSerializerImpl.class);
pController.generateXMLSerializerMethods(js);
return js;
}
public JavaSource getXMLSerializer(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
final String mName = "getXMLSerializer(JavaSource)";
log.finest(mName, "->", pSource.getQName());
JavaSource js = pSource.newJavaInnerClass(pController.getClassContext().getXMLSerializerName().getInnerClassName(), JavaSource.PUBLIC);
js.setStatic(true);
js.addExtends(JMXmlSerializerImpl.class);
pController.generateXMLSerializerMethods(js);
log.finest(mName, "<-", js.getQName());
return js;
}
public JavaSource getXMLHandler(ComplexTypeSG pController) throws SAXException {
final String mName = "getXMLHandler";
log.finest(mName, "->", typeSG.getName());
JavaQName xmlSerializerName = pController.getClassContext().getXMLHandlerName();
JavaSourceFactory jsf = typeSG.getSchema().getJavaSourceFactory();
JavaSource js = jsf.newJavaSource(xmlSerializerName, JavaSource.PUBLIC);
js.addExtends(JMHandlerImpl.class);
pController.generateXMLHandlerMethods(js);
return js;
}
public JavaSource getXMLHandler(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
final String mName = "getXMLHandler(JavaSource)";
log.finest(mName, "->", pSource.getQName());
JavaSource js = pSource.newJavaInnerClass(pController.getClassContext().getXMLHandlerName().getInnerClassName(), JavaSource.PUBLIC);
js.setStatic(true);
js.addExtends(JMHandlerImpl.class);
pController.generateXMLHandlerMethods(js);
log.finest(mName, "<-", js.getQName());
return js;
}
public SimpleContentSG getSimpleContentSG(ComplexTypeSG pController) {
if (simpleContentSG == null) {
throw new IllegalStateException("This complex type doesn't have simple content.");
}
return simpleContentSG;
}
public ComplexContentSG getComplexContentSG(ComplexTypeSG pController) {
if (complexContentSG == null) {
throw new IllegalStateException("This complex type doesn't have complex content.");
}
return complexContentSG;
}
public void generateXMLInterfaceMethods(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
generateProperties(pController, pSource);
if (pController.hasSimpleContent()) {
pController.getSimpleContentSG().getPropertySG().generate(pSource);
} else {
GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
groupSG.generateXMLInterfaceSubclasses(pSource);
}
}
public void generateXMLImplementationMethods(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
generateProperties(pController, pSource);
if (pController.hasSimpleContent()) {
pController.getSimpleContentSG().getPropertySG().generate(pSource);
} else {
GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
groupSG.generateXMLImplementationSubclasses(pSource);
}
}
private class XMLSerializerAttributeSGlet implements SGlet {
private AttributeSG attribute;
private final DirectAccessible attributeList;
private final DirectAccessible data;
public XMLSerializerAttributeSGlet(DirectAccessible pAttributeList, DirectAccessible pData) {
attributeList = pAttributeList;
data = pData;
}
public void setAttribute(AttributeSG pAttribute) {
attribute = pAttribute;
}
public void generate(JavaMethod pMethod, Object pValue) throws SAXException {
String uri = JavaSource.getQuoted(attribute.getName().getNamespaceURI());
String localName = JavaSource.getQuoted(attribute.getName().getLocalName());
pMethod.addLine(attributeList, ".addAttribute(", uri, ", ", localName,
", getAttributeQName(pData, ", uri, ", ", localName, "), \"CDATA\", ",
attribute.getTypeSG().getSimpleTypeSG().getCastToString(pMethod, pValue, data), ");");
}
}
private void generateXMLSerializersAttributes(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
final String mName = "generateXMLSerializersAttributes";
log.finest(mName, "->", pSource.getQName());
if (!pController.hasAttributes()) {
log.finest(mName, "<-");
return;
}
JavaMethod jm = pSource.newJavaMethod("getAttributes", AttributesImpl.class, "protected");
DirectAccessible pData = jm.addParam(JavaQNameImpl.getInstance(JMXmlSerializer.Data.class), "pData");
DirectAccessible pElement = jm.addParam(Object.class, "pElement");
jm.addThrows(SAXException.class);
LocalJavaField result = jm.newJavaField(AttributesImpl.class);
result.addLine("super.getAttributes(", pData, ", ", pElement, ")");
JavaQName elementInterface = pController.getClassContext().getXMLInterfaceName();
LocalJavaField element = jm.newJavaField(elementInterface);
element.addLine("(", elementInterface, ") ", pElement);
AttributeSG[] myAttributes = pController.getAttributes();
XMLSerializerAttributeSGlet sgLet = new XMLSerializerAttributeSGlet(result, pData);
for (int i = 0; i < attributes.length; i++) {
AttributeSG attribute = myAttributes[i];
if (attribute.isWildcard()) {
LocalJavaField anyAttributes = jm.newJavaField(WildcardAttribute[].class);
anyAttributes.addLine(element, ".", attribute.getPropertySG().getXMLGetMethodName() + "Array", "()");
DirectAccessible index = jm.addForArray(anyAttributes);
LocalJavaField wildcardAttribute = jm.newJavaField(WildcardAttribute.class);
wildcardAttribute.addLine(anyAttributes, "[", index, "]");
LocalJavaField qName = jm.newJavaField(QName.class);
qName.addLine(wildcardAttribute, ".getName()");
LocalJavaField uri = jm.newJavaField(String.class);
uri.addLine(qName, ".getNamespaceURI()");
LocalJavaField localPart = jm.newJavaField(String.class);
localPart.addLine(qName, ".getLocalPart()");
jm.addLine(result, ".addAttribute(", uri, ", ", localPart,
", getAttributeQName(pData, ", uri, ", ", localPart,
"), \"CDATA\", ", wildcardAttribute, ".getValue());");
jm.addEndFor();
} else {
sgLet.setAttribute(attribute);
attribute.forAllNonNullValues(jm, element, sgLet);
}
}
jm.addLine("return ", result, ";");
}
private JavaMethod getXMLSerializersGetPreferredPrefixMethod(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
Map uris = new HashMap();
List names = new ArrayList();
names.add(pController.getTypeSG().getName());
AttributeSG[] myAttributes = pController.getAttributes();
for (int i = 0; i < myAttributes.length; i++) {
XsQName qName = myAttributes[i].getName();
if (qName != null) {
names.add(qName);
}
}
if (!pController.hasSimpleContent()) {
ComplexContentSG myComplexContentSG = pController.getComplexContentSG();
GroupSG groupSG = myComplexContentSG.getGroupSG();
if (groupSG != null) { // Check required, in case the element doesn't have any childs.
ParticleSG[] particles = groupSG.getParticles();
for (int i = 0; i < particles.length; i++) {
if (particles[i].isElement()) {
names.add(particles[i].getObjectSG().getName());
}
}
}
}
for (Iterator iter = names.iterator(); iter.hasNext(); ) {
XsQName qName = (XsQName) iter.next();
String prefix = qName.getPrefix();
if (prefix != null) {
String uri = qName.getNamespaceURI();
if (uri == null) uri = "";
if (!uris.containsKey(uri)) {
uris.put(uri, prefix);
}
}
}
if (uris.isEmpty()) {
return null;
}
JavaMethod jm = pSource.newJavaMethod("getPreferredPrefix", String.class, JavaSource.PUBLIC);
DirectAccessible pURI = jm.addParam(String.class, "pURI");
jm.addIf(pURI, " == null");
jm.addLine(pURI, " = \"\";");
jm.addEndIf();
boolean first = true;
for (Iterator iter = uris.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry entry = (Map.Entry) iter.next();
String uri = (String) entry.getKey();
String prefix = (String) entry.getValue();
jm.addIf(first, pURI, ".equals(", JavaSource.getQuoted(uri), ")");
jm.addLine("return ", JavaSource.getQuoted(prefix), ";");
first = false;
}
jm.addEndIf();
jm.addLine("return super.getPreferredPrefix(", pURI, ");");
return jm;
}
protected JavaMethod getXMLSerializersMarshalChildsMethod(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
JavaMethod jm = pSource.newJavaMethod("marshalChilds", void.class, JavaSource.PUBLIC);
jm.addThrows(SAXException.class);
Parameter pData = jm.addParam(JMXmlSerializer.Data.class, "pData");
Parameter pElement = jm.addParam(Object.class, "pElement");
JavaQName elementInterface = pController.getClassContext().getXMLInterfaceName();
LocalJavaField element = jm.newJavaField(elementInterface);
element.addLine("(", elementInterface, ") ", pElement);
LocalJavaField chars = jm.newJavaField(String.class);
SimpleContentSG simpleContent = pController.getSimpleContentSG();
Object value = simpleContent.getPropertySG().getValue(element);
chars.addLine(simpleContent.getContentTypeSG().getSimpleTypeSG().getCastToString(jm, value, pData));
jm.addIf(chars, ".length() > 0");
LocalJavaField charArray = jm.newJavaField(char[].class);
charArray.addLine(chars, ".toCharArray()");
jm.addLine(pData, ".getContentHandler().characters(", charArray, ", 0, ", charArray, ".length);");
jm.addEndIf();
return jm;
}
public void generateXMLSerializerMethods(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
generateXMLSerializersAttributes(pController, pSource);
getXMLSerializersGetPreferredPrefixMethod(pController, pSource);
if (pController.hasSimpleContent()) {
getXMLSerializersMarshalChildsMethod(pController, pSource);
} else {
GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
if (groupSG != null) { // Check required, in case of empty content
groupSG.generateXMLSerializersElements(pSource);
}
}
}
private JavaMethod getXMLHandlersStartDocumentMethod(ComplexTypeSG pController, JavaSource pSource,
DirectAccessible pLevelVar) {
JavaMethod jm = pSource.newJavaMethod("startDocument", JavaQNameImpl.VOID, JavaSource.PUBLIC);
jm.addThrows(SAXException.class);
jm.addLine(pLevelVar, " = 0;");
return jm;
}
private Set createSetOfExplicitURIs(AttributeSG[] pAttributes) {
Set result = new HashSet();
for (int i = 0; i < pAttributes.length; i++) {
AttributeSG attr = pAttributes[i];
if (attr.isWildcard()) {
continue;
}
String uri = attr.getName().getNamespaceURI();
if (uri == null) { uri = ""; }
result.add(uri);
}
return result;
}
private JavaMethod getXMLHandlersAddAttributeMethod(ComplexTypeSG pController, JavaSource pSource)
throws SAXException {
AttributeSG[] myAttributes = pController.getAttributes();
if (myAttributes.length == 0) {
return null;
}
JavaMethod jm = pSource.newJavaMethod("addAttribute", JavaQNameImpl.VOID, JavaSource.PUBLIC);
DirectAccessible pURI = jm.addParam(String.class, "pURI");
DirectAccessible pLocalName = jm.addParam(String.class, "pLocalName");
DirectAccessible pValue = jm.addParam(String.class, "pValue");
jm.addThrows(SAXException.class);
jm.addIf(pURI, " == null");
jm.addLine(pURI, " = \"\";");
jm.addEndIf();
JavaQName resultType = pController.getClassContext().getXMLInterfaceName();
LocalJavaField result = jm.newJavaField(resultType);
result.addLine("(", resultType, ") getResult()");
Set uris = createSetOfExplicitURIs(myAttributes);
boolean first = true;
for (Iterator iter = uris.iterator(); iter.hasNext(); ) {
String uri = (String) iter.next();
jm.addIf(first, JavaSource.getQuoted(uri), ".equals(", pURI, ")");
first = false;
boolean firstInNamespace = true;
for (int i = 0; i < myAttributes.length; i++) {
AttributeSG attr = myAttributes[i];
if (attr.isWildcard()) {
continue;
}
String jUri = attr.getName().getNamespaceURI();
if (jUri == null) { jUri = ""; }
if (!uri.equals(jUri)) {
continue;
}
jm.addIf(firstInNamespace, JavaSource.getQuoted(attr.getName().getLocalName()), ".equals(", pLocalName, ")");
firstInNamespace = false;
Object v = myAttributes[i].getTypeSG().getSimpleTypeSG().getCastFromString(jm, pValue, "getData()");
attr.getPropertySG().setValue(jm, result, v, null);
jm.addLine("return;");
}
if (!firstInNamespace) {
jm.addEndIf();
}
}
if (!first) {
jm.addEndIf();
}
AttributeSG wildcard = null;
for (int i = 0; i < myAttributes.length; i++) {
if (myAttributes[i].isWildcard()) {
wildcard = myAttributes[i];
break;
}
}
if (wildcard == null) {
jm.addLine("super.addAttribute(", pURI, ", ", pLocalName, ", ", pValue, ");");
} else {
jm.addTry();
jm.addLine(result, ".", wildcard.getPropertySG().getXMLSetMethodName(), "(new ",
QName.class, "(", pURI, ", ", pLocalName, "), ", pValue, ");");
jm.addCatch(IllegalArgumentException.class);
jm.addLine("validationEvent(", ValidationEvent.class, ".ERROR, ",
JavaSource.getQuoted("Invalid namespace for anyAttribute: '"),
" + ", pURI, " + ", JavaSource.getQuoted("', attribute name is '"),
" + ", pLocalName, " + ", JavaSource.getQuoted("'"),
", ", ValidationEvents.class, ".EVENT_UNKNOWN_ANY_ATTRIBUTE);");
jm.addEndTry();
}
return jm;
}
protected JavaMethod getXMLHandlersNewResultMethod(ComplexTypeSG pController, JavaSource pSource) {
JavaQName elementInterfaceClass = pController.getClassContext().getXMLInterfaceName();
JavaMethod jm = pSource.newJavaMethod("newResult", elementInterfaceClass, JavaSource.PROTECTED);
jm.addThrows(SAXException.class);
if (pController.getClassContext().isGlobal()) {
jm.addTry();
jm.addLine("return (", elementInterfaceClass, ") getData().getFactory().getElement(",
elementInterfaceClass, ".class);");
DirectAccessible e = jm.addCatch(JAXBException.class);
jm.addThrowNew(SAXException.class, e);
jm.addEndTry();
} else {
JavaQName elementImplClass = pController.getClassContext().getXMLImplementationName();
jm.addLine("return new ", elementImplClass, "();");
}
return jm;
}
public JavaMethod getXMLHandlersEndElementMethod(ComplexTypeSG pController, JavaSource pSource,
DirectAccessible pLevelVar)
throws SAXException {
if (!pController.hasSimpleContent() && pController.getComplexContentSG().getGroupSG() != null) {
return null; // GroupSG creates method
}
JavaMethod jm = pSource.newJavaMethod("endElement", void.class, JavaSource.PUBLIC);
DirectAccessible pNamespaceURI = jm.addParam(String.class, "pNamespaceURI");
DirectAccessible pLocalName = jm.addParam(String.class, "pLocalName");
DirectAccessible pQName = jm.addParam(String.class, "pQName");
jm.addThrows(SAXException.class);
jm.addSwitch("--", pLevelVar);
jm.addCase("0");
if (pController.hasSimpleContent()) {
JavaQName elementInterface = pController.getClassContext().getXMLInterfaceName();
LocalJavaField element = jm.newJavaField(elementInterface);
element.addLine("(", elementInterface, ") getResult()");
SimpleContentSG simpleContent = pController.getSimpleContentSG();
Object value = simpleContent.getContentTypeSG().getSimpleTypeSG().getCastFromString(jm, "__content.toString()", "getData()");
simpleContent.getPropertySG().setValue(jm, element, value, null);
}
jm.addBreak();
if (pController.hasSimpleContent()) {
jm.addDefault();
jm.addLine("super.endElement(pNamespaceURI, pLocalName, pQName);");
jm.addBreak();
} else {
PlaceHolder placeHolder = jm.newPlaceHolder("GroupSG", true);
placeHolder.setProperty("pNamespaceURI", pNamespaceURI);
placeHolder.setProperty("pLocalName", pLocalName);
placeHolder.setProperty("pQName", pQName);
}
jm.addEndSwitch();
return jm;
}
public JavaMethod getXMLHandlersStartElementMethod(ComplexTypeSG pController, JavaSource pSource,
DirectAccessible pLevelVar)
throws SAXException {
JavaMethod jm = pSource.newJavaMethod("startElement", void.class, JavaSource.PUBLIC);
DirectAccessible pNamespaceURI = jm.addParam(String.class, "pNamespaceURI");
DirectAccessible pLocalName = jm.addParam(String.class, "pLocalName");
DirectAccessible pQName = jm.addParam(String.class, "pQName");
DirectAccessible pAttr = jm.addParam(Attributes.class, "pAttr");
jm.addThrows(SAXException.class);
jm.addSwitch(pLevelVar, "++");
jm.addCase("0");
jm.addLine("setResult(newResult());");
jm.addIf(pAttr, " != null");
String iVar = jm.getLocalVariableName();
jm.addFor("int ", iVar, " = 0; ", iVar, " < pAttr.getLength(); ", iVar, "++");
AttributeSG[] myAttributes = pController.getAttributes();
if (myAttributes.length == 0) {
jm.addLine("super.addAttribute(", pAttr, ".getURI(", iVar, "), ", pAttr, ".getLocalName(", iVar,
"), ", pAttr, ".getValue(", iVar, "));");
} else {
jm.addLine("addAttribute(", pAttr, ".getURI(", iVar, "), ", pAttr, ".getLocalName(", iVar,
"), ", pAttr, ".getValue(", iVar, "));");
}
jm.addEndFor();
jm.addEndIf();
if (pController.hasSimpleContent()) {
JavaField jf = pSource.newJavaField("__content", StringBuffer.class, JavaSource.PRIVATE);
jm.addLine(jf, " = new ", StringBuffer.class, "();");
}
jm.addBreak();
if (pController.hasSimpleContent()) {
jm.addDefault();
jm.addLine("super.startElement(pNamespaceURI, pLocalName, pQName, pAttr);");
jm.addBreak();
} else {
PlaceHolder placeHolder = jm.newPlaceHolder("GroupSG", true);
placeHolder.setProperty("pNamespaceURI", pNamespaceURI);
placeHolder.setProperty("pLocalName", pLocalName);
placeHolder.setProperty("pQName", pQName);
placeHolder.setProperty("pAttr", pAttr);
}
jm.addEndSwitch();
return jm;
}
private JavaField getXMLHandlersLevelField(ComplexTypeSG pController, JavaSource pSource) {
JavaField jf = pSource.newJavaField("__level", int.class, JavaSource.PRIVATE);
jf.newComment().addLine("The current level of nested elements. 0, if outside the root element.");
return jf;
}
protected JavaMethod getXMLHandlersCharactersMethod(ComplexTypeSG pController, JavaSource pSource,
JavaField pLevelVar) throws SAXException {
if (!pController.hasSimpleContent()) {
return null;
}
JavaMethod jm = pSource.newJavaMethod("characters", void.class, JavaSource.PUBLIC);
Parameter buffer = jm.addParam(char[].class, "pChars");
Parameter offset = jm.addParam(int.class, "pOffset");
Parameter length = jm.addParam(int.class, "pLength");
jm.addThrows(SAXException.class);
jm.addIf(pLevelVar, " == 1");
jm.addLine("__content.append(", buffer, ", ", offset, ", ", length, ");");
jm.addEndIf();
return jm;
}
public void generateXMLHandlerMethods(ComplexTypeSG pController, JavaSource pSource) throws SAXException {
JavaField levelVar = getXMLHandlersLevelField(pController, pSource);
getXMLHandlersStartDocumentMethod(pController, pSource, levelVar);
getXMLHandlersAddAttributeMethod(pController, pSource);
getXMLHandlersNewResultMethod(pController, pSource);
getXMLHandlersStartElementMethod(pController, pSource, levelVar);
getXMLHandlersEndElementMethod(pController, pSource, levelVar);
getXMLHandlersCharactersMethod(pController, pSource, levelVar);
if (!pController.hasSimpleContent()) {
GroupSG groupSG = pController.getComplexContentSG().getGroupSG();
if (groupSG != null) { // Check required, in case the element doesn't have any childs.
groupSG.generateXMLHandlersElements(pSource, levelVar);
}
}
}
public Object newComplexContentTypeSG(ComplexTypeSG pController) throws SAXException {
return new JAXBComplexContentTypeSG(pController, xsType);
}
public Object newSimpleContentTypeSG(ComplexTypeSG pController) throws SAXException {
return new JAXBSimpleContentTypeSG(pController, xsType);
}
}