/*
* Copyright 2005 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.ccsg;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ws.jaxme.generator.sg.ComplexContentSG;
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.ObjectSG;
import org.apache.ws.jaxme.generator.sg.ParticleSG;
import org.apache.ws.jaxme.generator.sg.SGlet;
import org.apache.ws.jaxme.impl.JMSAXDriver;
import org.apache.ws.jaxme.js.JavaInnerClass;
import org.apache.ws.jaxme.js.JavaMethod;
import org.apache.ws.jaxme.js.JavaQName;
import org.apache.ws.jaxme.js.JavaSource;
import org.apache.ws.jaxme.js.LocalJavaField;
import org.apache.ws.jaxme.js.Parameter;
import org.xml.sax.SAXException;
/** Base implementation of {@link DriverSG} for groups.
*/
public abstract class GroupDriverSG extends DriverSGImpl {
protected final ComplexContentSG ccSG;
protected final GroupSG group;
protected final ParticleSG[] particles;
protected final JavaSource outerGroup;
private final Map groups = new HashMap();
/** Creates a new instance, generating methods for serialization
* of the given type into the given source file.
*/
protected GroupDriverSG(ComplexTypeSG pType, JavaSource pJs) throws SAXException {
super(pType, pJs);
ccSG = pType.getComplexContentSG();
group = ccSG.getGroupSG();
particles = group.getParticles();
if (pJs == null) {
throw new NullPointerException("The outer group must not be null.");
}
outerGroup = pJs;
findGroups(particles);
}
/** Creates a new instance, generating methods for serialization
* of the given type into the given source file.
*/
protected GroupDriverSG(ComplexTypeSG pType, GroupSG pGroup,
JavaSource pOuterGroup, JavaInnerClass pJs)
throws SAXException {
super(pType, pJs);
if (pOuterGroup == null) {
throw new NullPointerException("The outer group must not be null.");
}
outerGroup = pOuterGroup;
ccSG = null;
group = pGroup;
particles = pGroup.getParticles();
findGroups(particles);
}
protected JavaSource getOuterGroup() {
return outerGroup;
}
private GroupDriverSG newGroupDriverSG(GroupSG pGroup, String pName) throws SAXException {
//JavaSource js = getOuterGroup();
//JavaInnerClass jic = js.newJavaInnerClass(pName, JavaSource.PUBLIC);
//jic.addExtends(JMSAXGroupParser.class);
JavaInnerClass jic = null;
if (pGroup.isSequence()) {
return new SequenceDriverSG(ctSG, pGroup, getOuterGroup(), jic);
} else if (pGroup.isChoice()) {
return new ChoiceDriverSG(ctSG, pGroup, getOuterGroup(), jic);
} else if (pGroup.isAll()) {
return new AllDriverSG(ctSG, pGroup, getOuterGroup(), jic);
} else {
throw new IllegalStateException("Invalid group type");
}
}
private GroupDriverSG newGroupDriverSG(GroupSG pGroup) throws SAXException {
JavaSource js = getOuterGroup();
String name = GroupUtil.getGroupName(pGroup);
for (int i = 0; ; i++) {
String n = name;
if (i > 0) {
name += i;
}
n += "Driver";
if (js.getInnerClass(n) == null) {
GroupDriverSG result = newGroupDriverSG(pGroup, n);
return result;
}
}
}
private void findGroups(ParticleSG[] pParticles) throws SAXException {
for (int i = 0; i < pParticles.length; i++) {
ParticleSG particle = pParticles[i];
if (particle.isGroup()) {
GroupSG group = particle.getGroupSG();
if (!groups.containsKey(group)) {
GroupDriverSG driver = newGroupDriverSG(group);
groups.put(group, driver);
}
}
}
}
protected void addNames(List pNames, GroupSG pGroup) throws SAXException {
ParticleSG[] particles = pGroup.getParticles();
for (int i = 0; i < particles.length; i++) {
ParticleSG particle = particles[i];
if (particle.isElement()) {
pNames.add(particle.getObjectSG().getName());
} else if (particle.isGroup()) {
addNames(pNames, particle.getGroupSG());
} else if (particle.isWildcard()) {
throw new IllegalStateException("TODO: Add support for wildcards");
} else {
throw new IllegalStateException("Invalid particle type");
}
}
}
protected List getNames() throws SAXException {
List names = super.getNames();
addNames(names, group);
return names;
}
private void marshalElementParticle(JavaMethod pMethod, Object pValue,
ParticleSG pParticle) throws SAXException {
ObjectSG oSG = pParticle.getObjectSG();
if (oSG.getTypeSG().isComplex()) {
Context cc = oSG.getTypeSG().getComplexTypeSG().getClassContext();
JavaQName serializerClass = cc.getXMLSerializerName();
LocalJavaField driver = pMethod.newJavaField(JMSAXDriver.class);
if (oSG.getTypeSG().isGlobalClass()) {
JavaQName elementInterface;
if (oSG.isGlobal()) {
elementInterface = oSG.getClassContext().getXMLInterfaceName();
} else {
elementInterface = cc.getXMLInterfaceName();
}
driver.addLine(getParamController(),
".getJMMarshaller().getJAXBContextImpl().getManagerS(",
elementInterface, ".class).getDriver()");
} else {
driver.addLine("new ", serializerClass, "();");
}
pMethod.addLine(getParamController(), ".marshal(", driver,
", ", JavaSource.getQuoted(oSG.getName().getNamespaceURI()),
", ", JavaSource.getQuoted(oSG.getName().getLocalName()),
", ", pValue, ");");
} else {
Object value = oSG.getTypeSG().getSimpleTypeSG().getCastToString(pMethod, pValue, getParamController());
pMethod.addLine(getParamController(), ".marshalSimpleChild(this, ",
JavaSource.getQuoted(oSG.getName().getNamespaceURI()), ", ",
JavaSource.getQuoted(oSG.getName().getLocalName()), ", ",
value, ");");
}
}
private GroupDriverSG getDriverSGByGroup(GroupSG pGroup) {
GroupDriverSG driver = (GroupDriverSG) groups.get(pGroup);
if (driver == null) {
throw new IllegalStateException("Unknown group: " + pGroup);
}
return driver;
}
private void marshalGroupParticle(JavaMethod pMethod, LocalJavaField pElement,
ParticleSG pParticle)
throws SAXException {
GroupDriverSG driver = getDriverSGByGroup(pParticle.getGroupSG());
driver.setParamController(getParamController());
driver.setParamElement(getParamElement());
driver.setParamHandler(getParamHandler());
driver.marshalParticles(pMethod, pElement, driver.particles);
}
public JavaMethod newMarshalChildsMethod() throws SAXException {
JavaMethod jm = super.newMarshalChildsMethod();
Parameter paramElement = getParamElement();
JavaQName elementInterface = ctSG.getClassContext().getXMLInterfaceName();
LocalJavaField element = jm.newJavaField(elementInterface);
element.addLine("(", elementInterface, ") ", paramElement);
marshalParticles(jm, element, particles);
return jm;
}
private void marshalParticles(JavaMethod pJm, LocalJavaField pElement,
ParticleSG[] pParticles) throws SAXException {
for (int i = 0; i < pParticles.length; i++) {
final ParticleSG particle = pParticles[i];
if (particle.isElement()) {
SGlet sgLet = new SGlet(){
public void generate(JavaMethod pMethod, Object pValue) throws SAXException {
marshalElementParticle(pMethod, pValue, particle);
}
};
particle.getPropertySG().forAllNonNullValues(pJm, pElement, sgLet);
} else if (particle.isGroup()) {
marshalGroupParticle(pJm, pElement, particle);
} else if (particle.isWildcard()) {
throw new IllegalStateException("TODO: Add support for wildcards");
} else {
throw new IllegalStateException("Invalid particle type");
}
}
}
}