/*
* 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.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
import org.apache.ws.jaxme.JMElement;
import org.apache.ws.jaxme.JMHandler;
import org.apache.ws.jaxme.JMXmlSerializer;
import org.apache.ws.jaxme.generator.sg.ComplexTypeSG;
import org.apache.ws.jaxme.generator.sg.Context;
import org.apache.ws.jaxme.generator.sg.GroupSG;
import org.apache.ws.jaxme.generator.sg.GroupSGChain;
import org.apache.ws.jaxme.generator.sg.ObjectSG;
import org.apache.ws.jaxme.generator.sg.ParticleSG;
import org.apache.ws.jaxme.generator.sg.ParticleSGChain;
import org.apache.ws.jaxme.generator.sg.PropertySG;
import org.apache.ws.jaxme.generator.sg.SGFactory;
import org.apache.ws.jaxme.generator.sg.SGlet;
import org.apache.ws.jaxme.generator.sg.SchemaSG;
import org.apache.ws.jaxme.generator.sg.TypeSG;
import org.apache.ws.jaxme.impl.JAXBContextImpl;
import org.apache.ws.jaxme.js.DirectAccessible;
import org.apache.ws.jaxme.js.JavaComment;
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.XSGroup;
import org.apache.ws.jaxme.xs.XSParticle;
import org.apache.ws.jaxme.xs.xml.XsQName;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
/**
* @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
*/
public class JAXBGroupSG extends JAXBSGItem implements GroupSGChain {
private static final Logger log = LoggerAccess.getLogger(JAXBGroupSG.class);
private ParticleSG[] particles;
private final boolean isGlobal, isAll, isSequence, isChoice;
private final Context classContext;
/** <p>Creates a new, global group.</p>
*/
protected JAXBGroupSG(SGFactory pFactory, SchemaSG pSchema, XSGroup pGroup) throws SAXException {
super(pFactory, pSchema, pGroup);
isGlobal = true;
isAll = pGroup.isAll();
isSequence = pGroup.isSequence();
isChoice = pGroup.isChoice();
classContext = new GlobalContext(pGroup.getName(), pGroup, null, "Group", pSchema);
}
/** <p>Creates a new, local group.</p>
*/
protected JAXBGroupSG(SGFactory pFactory, SchemaSG pSchema, XSGroup pGroup, Context pContext)
throws SAXException {
super(pFactory, pSchema, pGroup);
isGlobal = false;
isAll = pGroup.isAll();
isSequence = pGroup.isSequence();
isChoice = pGroup.isChoice();
classContext = pContext;
}
public Object newParticleSG(GroupSG pController, XSParticle pParticle) throws SAXException {
return new JAXBParticleSG(pController, pParticle, classContext);
}
public Context getClassContext(GroupSG pController) { return classContext; }
public SGFactory getFactory(GroupSG pController) { return getFactory(); }
public SchemaSG getSchema(GroupSG pController) { return getSchema(); }
public Locator getLocator(GroupSG pController) { return getLocator(); }
public ParticleSG[] getParticles(GroupSG pController) throws SAXException {
if (particles == null) {
XSParticle[] xsParticles = ((XSGroup) getXSObject()).getParticles();
particles = new ParticleSG[xsParticles.length];
for (int i = 0; i < xsParticles.length; i++) {
ParticleSGChain chain = (ParticleSGChain) pController.newParticleSG(xsParticles[i]);
ParticleSG particle = new ParticleSGImpl(chain);
particle.init();
particles[i] = particle;
}
}
return particles;
}
public void init(GroupSG pController) throws SAXException {
}
public boolean isAll(GroupSG pController) { return isAll; }
public boolean isGlobal(GroupSG pController) { return isGlobal; }
public boolean isChoice(GroupSG pController) { return isChoice; }
public boolean isSequence(GroupSG pController) { return isSequence; }
public JavaSource getXMLInterface(GroupSG pController) throws SAXException {
JavaQName qName = pController.getClassContext().getXMLInterfaceName();
JavaSourceFactory jsf = getSchema().getJavaSourceFactory();
JavaSource js = jsf.newJavaSource(qName, JavaSource.PUBLIC);
js.setType(JavaSource.INTERFACE);
pController.generateProperties(js);
return js;
}
public JavaSource getXMLImplementation(GroupSG pController) throws SAXException {
JavaQName qName = pController.getClassContext().getXMLImplementationName();
JavaSourceFactory jsf = getSchema().getJavaSourceFactory();
JavaSource js = jsf.newJavaSource(qName, JavaSource.PUBLIC);
js.addImplements(pController.getClassContext().getXMLInterfaceName());
SerializableSG.makeSerializable(pController.getSchema(), js);
pController.generateProperties(js);
return js;
}
/** <p>Called to fill the given {@link JavaSource} instance with
* getters and setters, matching the properties.</p>
*/
public void generateProperties(GroupSG pController, JavaSource pSource) throws SAXException {
final String mName = "generateProperties(JavaSource)";
log.finest(mName, "->", pSource.getQName());
ParticleSG[] myParticles = pController.getParticles();
for (int i = 0; i < particles.length; i++) {
ParticleSG particle = myParticles[i];
if (particle.isElement()) {
PropertySG elementSG = particle.getPropertySG();
elementSG.generate(pSource);
} else if (particle.isGroup()) {
GroupSG groupSG = particle.getGroupSG();
groupSG.generateProperties(pSource);
} else if (particle.isWildcard()) {
PropertySG wildcardSG = particle.getPropertySG();
wildcardSG.generate(pSource);
} else {
throw new IllegalStateException("Unknown particle type: Neither of element, group, or wildcard");
}
}
log.finest(mName, "<-");
}
public void generateXMLInterfaceSubclasses(GroupSG pController, JavaSource pSource) throws SAXException {
final String mName = "generateSubClasses(JavaSource)";
log.finest(mName, "->", pSource.getQName());
ParticleSG[] myParticles = pController.getParticles();
for (int i = 0; i < particles.length; i++) {
ParticleSG particle = myParticles[i];
if (particle.isElement()) {
ObjectSG elementSG = particle.getObjectSG();
TypeSG typeSG = elementSG.getTypeSG();
if (!typeSG.isGlobalType() && !typeSG.isGlobalClass() && typeSG.isComplex()) {
ComplexTypeSG complexTypeSG = typeSG.getComplexTypeSG();
complexTypeSG.getXMLInterface(pSource);
}
} else if (particle.isGroup()) {
GroupSG groupSG = particle.getGroupSG();
groupSG.generateXMLInterfaceSubclasses(pSource);
} else if (particle.isWildcard()) {
// Do nothing
} else {
throw new IllegalStateException("Unknown particle type: Neither of element, group, or wildcard");
}
}
log.finest(mName, "<-");
}
public void generateXMLImplementationSubclasses(GroupSG pController, JavaSource pSource) throws SAXException {
final String mName = "generateSubClasses(JavaSource,JavaQName)";
log.finest(mName, "->", new Object[]{pSource.getQName()});
ParticleSG[] myParticles = pController.getParticles();
for (int i = 0; i < particles.length; i++) {
ParticleSG particle = myParticles[i];
if (particle.isElement()) {
ObjectSG elementSG = particle.getObjectSG();
TypeSG typeSG = elementSG.getTypeSG();
if (!typeSG.isGlobalType() && !typeSG.isGlobalClass() && typeSG.isComplex()) {
ComplexTypeSG complexTypeSG = typeSG.getComplexTypeSG();
complexTypeSG.getXMLImplementation(pSource);
}
} else if (particle.isGroup()) {
GroupSG groupSG = particle.getGroupSG();
groupSG.generateXMLImplementationSubclasses(pSource);
} else if (particle.isWildcard()) {
// Do nothing
} else {
throw new IllegalStateException("Unknown particle type: Neither of element, group, or wildcard");
}
}
log.finest(mName, "<-");
}
private String getXMLSerializersFieldName(PropertySG pChild) throws SAXException {
return "__ser_" + pChild.getXMLFieldName();
}
private JavaMethod getXMLSerializersInitMethod(GroupSG pController, JavaSource pSource) throws SAXException {
ParticleSG[] myParticles = pController.getParticles();
JavaMethod jm = null;
DirectAccessible pFactory = null;
for (int i = 0; i < myParticles.length; i++) {
ParticleSG particle = myParticles[i];
if (!particle.isElement()) {
continue;
}
ObjectSG child = particle.getObjectSG();
if (!child.getTypeSG().isComplex()) {
continue;
}
if (jm == null) {
jm = pSource.newJavaMethod("init", JavaQNameImpl.VOID, JavaSource.PUBLIC);
pFactory = jm.addParam(JAXBContextImpl.class, "pFactory");
jm.addLine("super.init(", pFactory, ");");
jm.addThrows(JAXBException.class);
}
String serializerName = getXMLSerializersFieldName(particle.getPropertySG());
Context myClassContext = child.getTypeSG().getComplexTypeSG().getClassContext();
JavaQName serializerClass = myClassContext.getXMLSerializerName();
pSource.newJavaField(serializerName, serializerClass, JavaSource.PRIVATE);
}
return jm;
}
private static class XMLSerializersMarshalChildsSGlet implements SGlet.TypedSGlet {
private ParticleSG child;
private String fieldName;
private final DirectAccessible data;
public XMLSerializersMarshalChildsSGlet(DirectAccessible pData) {
data = pData;
}
public void setChild(ParticleSG pChild) {
child = pChild;
}
public JavaQName getType() {
if (child.getObjectSG().getTypeSG().isComplex()) {
return JavaQNameImpl.getInstance(JMElement.class);
} else {
return null;
}
}
public void setFieldName(String pFieldName) {
fieldName = pFieldName;
}
public boolean isCasting() { return !child.getObjectSG().getTypeSG().isComplex(); }
public void generate(JavaMethod pMethod, Object pValue) throws SAXException {
ObjectSG objectSG = child.getObjectSG();
JavaField f = pMethod.getJavaSource().newJavaField(fieldName + "_qname", QName.class);
f.setStatic(true);
f.setFinal(true);
f.addLine("new ", QName.class, "(", JavaSource.getQuoted(objectSG.getName().getNamespaceURI()),
", ", JavaSource.getQuoted(objectSG.getName().getLocalName()), ");");
if (objectSG.getTypeSG().isComplex()) {
Context myClassContext =
child.getObjectSG().getTypeSG().getComplexTypeSG().getClassContext();
JavaQName serializerClass = myClassContext.getXMLSerializerName();
pMethod.addIf(fieldName + " == null");
pMethod.addTry();
if (child.getObjectSG().getTypeSG().isGlobalClass()) {
JavaQName elementInterface;
if (objectSG.isGlobal()) {
elementInterface = objectSG.getClassContext().getXMLInterfaceName();
} else {
elementInterface = myClassContext.getXMLInterfaceName();
}
pMethod.addLine(fieldName + " = ("+ serializerClass+ ") ",
"getFactory().getJMXmlSerializer(", elementInterface,
".class);");
} else {
pMethod.addLine(fieldName + " = new ", serializerClass, "();");
pMethod.addLine(fieldName + ".init(getFactory());");
}
DirectAccessible e = pMethod.addCatch(JAXBException.class);
pMethod.addThrowNew(SAXException.class, e);
pMethod.addEndTry();
pMethod.addEndIf();
pMethod.addLine(fieldName, ".marshal(", data, ", ", f, ", ", pValue, ");");
} else {
Object v = child.getObjectSG().getTypeSG().getSimpleTypeSG().getCastToString(pMethod, pValue, data);
pMethod.addLine("marshalAtomicChild(", data, ", ", f, ", ", v, ");");
}
}
}
private JavaMethod getXMLSerializersMarshalChildsMethod(GroupSG pController, JavaSource pSource) throws SAXException {
final String mName = "getXMLSerializersMarshalChildsMethod";
log.finest(mName, "->", pSource.getQName());
ParticleSG[] myParticles = pController.getParticles();
JavaMethod jm = null;
LocalJavaField pElement = null;
XMLSerializersMarshalChildsSGlet sgLet = null;
for (int i = 0; i < myParticles.length; i++) {
ParticleSG particle = myParticles[i];
if (jm == null) {
jm = pSource.newJavaMethod("marshalChilds", JavaQNameImpl.VOID, JavaSource.PROTECTED);
DirectAccessible pData = jm.addParam(JavaQNameImpl.getInstance(JMXmlSerializer.Data.class), "pData");
sgLet = new XMLSerializersMarshalChildsSGlet(pData);
JavaQName elementInterface = pController.getClassContext().getXMLInterfaceName();
DirectAccessible pObject = jm.addParam(Object.class, "pObject");
pElement = jm.newJavaField(elementInterface);
pElement.addLine("(", elementInterface, ") ", pObject);
jm.addThrows(SAXException.class);
}
if (!particle.isElement()) {
// TODO: Implement handling for wildcards and subgroups
//throw new IllegalStateException("Wildcards and subgroups are not implemented.");
return jm;
}
sgLet.setChild(particle);
sgLet.setFieldName(getXMLSerializersFieldName(particle.getPropertySG()));
particle.getPropertySG().forAllNonNullValues(jm, pElement, sgLet);
}
log.finest(mName, "<-");
return jm;
}
public void generateXMLSerializersElements(GroupSG pController, JavaSource pSource) throws SAXException {
final String mName = "generateXMLSerializersElements";
log.finest(mName, "->", pSource.getQName());
getXMLSerializersInitMethod(pController, pSource);
getXMLSerializersMarshalChildsMethod(pController, pSource);
ParticleSG[] myParticles = pController.getParticles();
for (int i = 0; i < myParticles.length; i++) {
ParticleSG particle = myParticles[i];
if (particle.isElement()) {
ObjectSG objectSG = particle.getObjectSG();
TypeSG typeSG = objectSG.getTypeSG();
if (typeSG.isComplex() && !typeSG.isGlobalClass()) {
typeSG.getComplexTypeSG().getXMLSerializer(pSource);
}
}
}
log.finest(mName, "<-");
}
private void getXMLHandlersElements(GroupSG pController, JavaSource pSource) throws SAXException {
ParticleSG[] myParticles = pController.getParticles();
for (int i = 0; i < myParticles.length; i++) {
ParticleSG particle = myParticles[i];
if (particle.isElement()) {
ObjectSG objectSG = particle.getObjectSG();
TypeSG typeSG = objectSG.getTypeSG();
if (typeSG.isComplex() && !typeSG.isGlobalClass()) {
typeSG.getComplexTypeSG().getXMLHandler(pSource);
}
}
}
}
private String getXMLHandlersMethodName(PropertySG pPropertySG) throws SAXException {
String f = pPropertySG.getXMLFieldName();
return "getHandlerFor" + Character.toUpperCase(f.charAt(0)) + f.substring(1);
}
private JavaMethod getXMLHandlersInitMethod(GroupSG pController, JavaSource pSource) throws SAXException {
JavaMethod jm = null;
DirectAccessible pData = null;
ParticleSG[] myParticles = pController.getParticles();
for (int i = 0; i < myParticles.length; i++) {
ParticleSG particle = myParticles[i];
if (particle.isElement()) {
ObjectSG objectSG = particle.getObjectSG();
TypeSG typeSG = objectSG.getTypeSG();
if (typeSG.isComplex()) {
if (jm == null) {
jm = pSource.newJavaMethod("init", JavaQNameImpl.VOID, JavaSource.PUBLIC);
pData = jm.addParam(JMHandler.Data.class, "pData");
jm.addThrows(JAXBException.class);
jm.addLine("super.init(", pData, ");");
}
String f = particle.getPropertySG().getXMLFieldName();
String handlerFieldName = "__handler_" + f;
String handlerMethodName = getXMLHandlersMethodName(particle.getPropertySG());
JavaField jf = pSource.newJavaField(handlerFieldName, JMHandler.class, JavaSource.PRIVATE);
JavaMethod jm2 = pSource.newJavaMethod(handlerMethodName, JMHandler.class, "protected");
jm2.addThrows(SAXException.class);
jm2.addIf(handlerFieldName, " == null");
ComplexTypeSG childSG = typeSG.getComplexTypeSG();
JavaQName handlerClassName = childSG.getClassContext().getXMLHandlerName();
jm2.addTry();
if (typeSG.isGlobalClass()) {
JavaQName interfaceName;
if (objectSG.isGlobal()) {
interfaceName = objectSG.getClassContext().getXMLInterfaceName();
} else {
interfaceName = childSG.getClassContext().getXMLInterfaceName();
}
jm2.addLine(handlerFieldName, " = getData().getFactory().getJMHandler(",
interfaceName, ".class);");
} else {
jm2.addLine(jf, " = new ", handlerClassName, "();");
}
jm2.addLine(jf, ".init(getData());");
DirectAccessible e = jm2.addCatch(JAXBException.class);
jm2.addThrowNew(SAXException.class, e);
jm2.addEndTry();
jm2.addEndIf();
jm2.addLine("return ", jf, ";");
jm.addIf(jf, " != null");
jm.addLine(jf, ".init(", pData, ");");
jm.addEndIf();
}
}
}
return jm;
}
private JavaField getXMLHandlersStateField(GroupSG pController, JavaSource pSource) throws SAXException {
ParticleSG[] myParticles = pController.getParticles();
if (myParticles.length > 0) {
JavaField jf = pSource.newJavaField("__state", int.class, JavaSource.PRIVATE);
JavaComment jc = jf.newComment();
jc.addLine("The current state. The following values are valid states:");
jc.addLine(" 0 = Before parsing the element");
jc.addLine(" 1 = Parsing an unknown element");
jc.addLine(" 2 = After parsing the element");
for (int i = 0; i < myParticles.length; i++) {
ParticleSG particle = myParticles[i];
if (particle.isGroup()) {
// TODO: process group case properly.
continue;
} else if (particle.isElement()) {
jc.addLine(" " + (3+i) + " = While parsing the child element " + myParticles[i].getObjectSG().getName());
} else if (particle.isWildcard()) {
jc.addLine(" " + (3+i) + " = While parsing the wildcard");
} else {
throw new IllegalStateException("Invalid particle type.");
}
}
JavaMethod[] methods = pSource.getMethods();
boolean ok = false;
for (int i = 0; i < methods.length; i++) {
if ("startDocument".equals(methods[i].getName())) {
methods[i].addLine(jf, " = 0;");
ok = true;
break;
}
}
if (!ok) {
throw new IllegalStateException("Unable to find the handlers 'startDocument' method.");
}
return jf;
}
return null;
}
private JavaField getXMLHandlersHandlerField(GroupSG pController, JavaSource pSource) throws SAXException {
ParticleSG[] myParticles = pController.getParticles();
if (myParticles.length > 0) {
JavaField jf = pSource.newJavaField("__handler", JMHandler.class, JavaSource.PRIVATE);
jf.newComment().addLine("The current handler for parsing child elements or simple content.");
return jf;
}
return null;
}
private void extendXMLHandlersStartDocumentMethod(GroupSG pController, JavaSource pSource,
DirectAccessible pStateVar,
DirectAccessible pHandlerVar) throws SAXException {
JavaMethod[] methods = pSource.getMethods();
boolean ok = false;
for (int i = 0; i < methods.length; i++) {
if ("startDocument".equals(methods[i].getName())) {
methods[i].addLine(pStateVar, " = 0;");
methods[i].addLine(pHandlerVar, " = null;");
ok = true;
break;
}
}
if (!ok) {
throw new IllegalStateException("Unable to find the handlers 'startDocument' method.");
}
}
private void extendXMLHandlersStartElementMethodAddNamespace(GroupSG pController,
DirectAccessible pHandlerVar,
DirectAccessible pStateVar,
JavaMethod pMethod,
String pURI,
Parameter pNamespaceURI,
Parameter pQName,
Parameter pLocalName,
Parameter pAttr,
ParticleSG[] pParticles) throws SAXException {
// Now handle all elements with the namespace uri
boolean first = true;
for (int j = 0; j < pParticles.length; j++) {
ParticleSG child = pParticles[j];
if (!child.isElement()) {
continue;
}
XsQName name = child.getObjectSG().getName();
if (!name.getNamespaceURI().equals(pURI)) {
continue;
}
pMethod.addIf(first, JavaSource.getQuoted(name.getLocalName()), ".equals(", pLocalName, ")");
first = false;
List validStates = new ArrayList();
if (child.isMultiple()) {
validStates.add(new Integer(j+3));
}
if (pController.isChoice()) {
validStates.add(new Integer(0));
} else if (pController.isSequence()) {
boolean stateZeroIsValid = true;
for (int k = j-1; k >= 0; k--) {
ParticleSG kChild = pParticles[k];
validStates.add(new Integer(k+3));
if (kChild.getMinOccurs() > 0) {
stateZeroIsValid = false;
break;
}
}
if (stateZeroIsValid) {
validStates.add(new Integer(0));
}
} else if (pController.isAll()) {
validStates.add(new Integer(0));
for (int k = 0; k <= pParticles.length; k++) {
validStates.add(new Integer(k+3));
}
} else {
throw new IllegalStateException("Don't know how to handle type which is neither sequence nor choice, or all.");
}
Collections.sort(validStates);
pMethod.addSwitch(pStateVar);
for (int k = 0; k < validStates.size(); k++) {
pMethod.addCase(validStates.get(k));
}
pMethod.addLine(pStateVar, " = " + (j+3) + ";");
if (child.getObjectSG().getTypeSG().isComplex()) {
String handlerMethodName = getXMLHandlersMethodName(child.getPropertySG());
pMethod.addLine(pHandlerVar, " = ", handlerMethodName, "();");
} else {
pMethod.addLine(pHandlerVar, " = getData().getAtomicHandler();");
}
pMethod.addLine(pHandlerVar, ".startDocument();");
pMethod.addLine(pHandlerVar, ".startElement(pNamespaceURI, pLocalName, pQName, pAttr);");
pMethod.addBreak();
pMethod.addDefault();
pMethod.addLine("super.startElement(", pNamespaceURI, ", ", pLocalName, ", ", pQName, ", ", pAttr, ");");
pMethod.addBreak();
pMethod.addEndSwitch();
}
if (!first) {
pMethod.addElse();
}
pMethod.addLine("super.startElement(", pNamespaceURI, ", ", pLocalName, ", ", pQName, ", ", pAttr, ");");
if (!first) {
pMethod.addEndIf();
}
}
private void extendXMLHandlersStartElementMethod(GroupSG pController, JavaSource pSource,
DirectAccessible pStateVar,
DirectAccessible pHandlerVar) throws SAXException {
ParticleSG[] myParticles = pController.getParticles();
if (myParticles.length == 0) {
return;
}
JavaQName STRING_TYPE = JavaQNameImpl.getInstance(String.class);
JavaQName ATTRIBUTES_TYPE = JavaQNameImpl.getInstance(Attributes.class);
JavaMethod jm = pSource.getMethod("startElement", new JavaQName[]{STRING_TYPE,
STRING_TYPE,
STRING_TYPE,
ATTRIBUTES_TYPE});
if (jm == null) {
throw new IllegalStateException("No such method: 'startElement' in '" + pSource.getQName() + "'.");
}
PlaceHolder placeHolder = jm.getPlaceHolder("GroupSG");
if (placeHolder == null) {
throw new IllegalStateException("No such placeholder: 'GroupSG' in method 'startElement'");
}
placeHolder.remove();
Parameter[] parameters = jm.getParams();
Parameter pNamespaceURI = parameters[0];
Parameter pLocalName = parameters[1];
Parameter pQName = parameters[2];
Parameter pAttr = parameters[3];
jm.addCase("1");
Set namespaces = new HashSet();
for (int i = 0; i < myParticles.length; i++) {
ParticleSG child = myParticles[i];
if (child.isGroup()) {
// TODO: Process group case properly
} else if (child.isWildcard()) {
throw new IllegalStateException("Wildcards aren't implemented yet.");
} else if (child.isElement()) {
namespaces.add(child.getObjectSG().getName().getNamespaceURI());
} else {
throw new IllegalStateException("Unknown particle type");
}
}
boolean firstNamespace = true;
for (Iterator iter = namespaces.iterator(); iter.hasNext(); ) {
String uri = (String) iter.next();
if ("".equals(uri)) {
jm.addIf(firstNamespace, pNamespaceURI, " == null || ", pNamespaceURI, ".length() == 0");
} else {
jm.addIf(firstNamespace, JavaSource.getQuoted(uri), ".equals(", pNamespaceURI, ")");
}
firstNamespace = false;
extendXMLHandlersStartElementMethodAddNamespace(pController, pHandlerVar, pStateVar,
jm, uri, pNamespaceURI,
pQName, pLocalName, pAttr,
myParticles);
}
if (!firstNamespace) {
jm.addElse();
}
jm.addLine("super.startElement(", pNamespaceURI, ", ", pLocalName, ", ", pQName, ", ", pAttr, ");");
if (!firstNamespace) {
jm.addEndIf();
}
jm.addBreak();
jm.addDefault();
jm.addIf(pHandlerVar, " == null");
jm.addLine("super.startElement(", pNamespaceURI, ", ", pLocalName, ", ", pQName, ", ", pAttr, ");");
jm.addElse();
jm.addLine(pHandlerVar, ".startElement(", pNamespaceURI, ", ", pLocalName, ", ", pQName, ", ", pAttr, ");");
jm.addEndIf();
}
public JavaMethod getXMLHandlersEndElementMethod(GroupSG pController, JavaSource pSource,
DirectAccessible pLevelVar,
DirectAccessible pStateVar,
DirectAccessible pHandlerVar)
throws SAXException {
ParticleSG[] myParticles = pController.getParticles();
if (myParticles.length == 0) {
return null;
}
JavaMethod jm = pSource.newJavaMethod("endElement", JavaQNameImpl.VOID, 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.addIf(pHandlerVar, " == null");
jm.addIf(pLevelVar, " > 1");
jm.addLine("super.endElement(", pNamespaceURI, ", ", pLocalName, ", ", pQName, ");");
jm.addEndIf();
jm.addElse();
jm.addLine(pHandlerVar, ".endElement(", pNamespaceURI, ", ", pLocalName, ", ", pQName, ");");
jm.addEndIf();
jm.addSwitch("--", pLevelVar);
jm.addCase("0");
jm.addBreak();
jm.addCase("1");
JavaQName elementInterface = pController.getClassContext().getXMLInterfaceName();
LocalJavaField element = jm.newJavaField(elementInterface);
element.addLine("(", elementInterface, ") getResult()");
jm.addSwitch(pStateVar);
for (int i = 0; i < myParticles.length; i++) {
ParticleSG child = myParticles[i];
// TODO: process group case properly.
if (myParticles[i].isGroup()) continue;
ObjectSG osg = child.getObjectSG();
TypeSG childType = osg.getTypeSG();
jm.addCase(Integer.toString(3+i));
jm.addIf(pHandlerVar, " != null");
jm.addLine(pHandlerVar, ".endDocument();");
jm.addEndIf();
Object v;
JavaQName type;
if (childType.isComplex()) {
type = childType.getComplexTypeSG().getClassContext().getXMLInterfaceName();
v = new Object[]{pHandlerVar, ".getResult()"};
} else {
type = null;
v = new Object[]{"(", String.class, ") ", pHandlerVar, ".getResult()"};
Object castedValue = childType.getSimpleTypeSG().getCastFromString(jm, v, "getData()");
if (v == castedValue) {
v = new Object[]{pHandlerVar, ".getResult()"};
type = JavaQNameImpl.getInstance(String.class);
} else {
v = castedValue;
type = null;
}
}
child.getPropertySG().addValue(jm, element, v, type);
jm.addBreak();
}
jm.addDefault();
jm.addThrowNew(IllegalStateException.class, JavaSource.getQuoted("Illegal state: "), " + ", pStateVar);
jm.addEndSwitch();
jm.addEndSwitch();
return jm;
}
public JavaMethod getXMLHandlersCharactersMethod(GroupSG pController, JavaSource pSource,
DirectAccessible pHandlerVar)
throws SAXException {
JavaMethod jm = pSource.newJavaMethod("characters", JavaQNameImpl.VOID, JavaSource.PUBLIC);
DirectAccessible pChars = jm.addParam(char[].class, "pChars");
DirectAccessible pOffset = jm.addParam(int.class, "pOffset");
DirectAccessible pLen = jm.addParam(int.class, "pLen");
jm.addThrows(SAXException.class);
jm.addIf(pHandlerVar, " == null");
jm.addLine("super.characters(", pChars,", ", pOffset, ", ", pLen, ");");
jm.addElse();
jm.addLine(pHandlerVar, ".characters(", pChars, ", ", pOffset, ", ", pLen, ");");
jm.addEndIf();
return jm;
}
public void generateXMLHandlersElements(GroupSG pController, JavaSource pSource, DirectAccessible pLevelVar)
throws SAXException {
JavaField stateVar = getXMLHandlersStateField(pController, pSource);
JavaField handlerVar = getXMLHandlersHandlerField(pController, pSource);
extendXMLHandlersStartDocumentMethod(pController, pSource, stateVar, handlerVar);
extendXMLHandlersStartElementMethod(pController, pSource, stateVar, handlerVar);
getXMLHandlersEndElementMethod(pController, pSource, pLevelVar, stateVar, handlerVar);
getXMLHandlersCharactersMethod(pController, pSource, handlerVar);
getXMLHandlersElements(pController, pSource);
getXMLHandlersInitMethod(pController, pSource);
}
public void generate(GroupSG pController) throws SAXException {
final String mName = "generate";
log.finest(mName, "->", pController.isGlobal() ? pController.getClassContext().toString() : "Local group");
log.finest(mName, "<-");
}
}