/*
* 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.List;
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.SimpleContentSG;
import org.apache.ws.jaxme.generator.sg.SimpleContentSGChain;
import org.apache.ws.jaxme.generator.sg.TypeSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.AllHandlerSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.AllDriverSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.BeanSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.ChoiceHandlerSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.ChoiceDriverSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.EmptyElementBeanSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.EmptyElementHandlerSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.EmptyElementDriverSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.HandlerSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.SequenceHandlerSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.SequenceDriverSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.DriverSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.SimpleContentBeanSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.SimpleContentHandlerSG;
import org.apache.ws.jaxme.generator.sg.impl.ccsg.SimpleContentDriverSG;
import org.apache.ws.jaxme.impl.JMSAXDriver;
import org.apache.ws.jaxme.impl.JMSAXElementParser;
import org.apache.ws.jaxme.js.JavaQName;
import org.apache.ws.jaxme.js.JavaSource;
import org.apache.ws.jaxme.js.JavaSourceFactory;
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.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* @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(); }
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);
createXMLBean(pController, js);
log.finest(mName, "<-", js.getQName());
return js;
}
private void createXMLBean(ComplexTypeSG pController, JavaSource pJs)
throws SAXException {
BeanSG beanSG = newBeanSG(pController, pJs);
if (!pJs.isInterface()) {
SerializableSG.makeSerializable(pController.getTypeSG().getSchema(), pJs);
}
beanSG.generate();
}
private BeanSG newBeanSG(ComplexTypeSG pController, JavaSource pJs)
throws SAXException {
if (pController.hasSimpleContent()) {
return new SimpleContentBeanSG(pController, pJs);
} else {
ComplexContentSG ccSG = pController.getComplexContentSG();
if (ccSG.isEmpty()) {
return new EmptyElementBeanSG(pController, pJs);
} else {
GroupSG group = ccSG.getGroupSG();
if (group.isAll()) {
return new AllBeanSG(pController, pJs);
} else if (group.isChoice()) {
return new ChoiceBeanSG(pController, pJs);
} else if (group.isSequence()) {
return new SequenceBeanSG(pController, pJs);
} else {
throw new IllegalStateException("Invalid particle type");
}
}
}
}
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);
createXMLBean(pController, 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());
createXMLBean(pController, 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());
createXMLBean(pController, js);
log.finest(mName, "<-", js.getQName());
return js;
}
private DriverSG newSerializerSG(ComplexTypeSG pController, JavaSource pSource)
throws SAXException {
if (pController.hasSimpleContent()) {
return new SimpleContentDriverSG(pController, pSource);
} else {
ComplexContentSG ccSG = pController.getComplexContentSG();
if (ccSG.isEmpty()) {
return new EmptyElementDriverSG(pController, pSource);
} else {
GroupSG group = ccSG.getGroupSG();
if (group.isSequence()) {
return new SequenceDriverSG(pController, pSource);
} else if (group.isChoice()) {
return new ChoiceDriverSG(pController, pSource);
} else if (group.isAll()) {
return new AllDriverSG(pController, pSource);
} else {
throw new IllegalStateException("Invalid group type");
}
}
}
}
private void createXMLSerializer(ComplexTypeSG pController, JavaSource pSource)
throws SAXException {
pSource.addImplements(JMSAXDriver.class);
DriverSG serializerSG = newSerializerSG(pController, pSource);
serializerSG.generate();
if (!pController.hasSimpleContent()) {
ComplexContentSG ccSG = pController.getComplexContentSG();
ParticleSG[] particles = ccSG.getElementParticles();
for (int i = 0; i < particles.length; i++) {
ParticleSG particle = particles[i];
TypeSG tSG = particle.getObjectSG().getTypeSG();
if (tSG.isComplex() && !tSG.isGlobalClass()) {
tSG.getComplexTypeSG().getXMLSerializer(pSource);
}
}
}
}
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);
createXMLSerializer(pController, js);
log.finest(mName, "<-", js.getQName());
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);
createXMLSerializer(pController, js);
log.finest(mName, "<-", js.getQName());
return js;
}
private HandlerSG newHandlerSG(ComplexTypeSG pController,
JavaSource pJs)
throws SAXException {
if (pController.hasSimpleContent()) {
return new SimpleContentHandlerSG(pController, pJs);
} else {
ComplexContentSG ccSG = pController.getComplexContentSG();
if (ccSG.isEmpty()) {
return new EmptyElementHandlerSG(pController, pJs);
} else {
GroupSG group = ccSG.getGroupSG();
if (group.isSequence()) {
return new SequenceHandlerSG(pController, pJs);
} else if (group.isChoice()) {
return new ChoiceHandlerSG(pController, pJs);
} else if (group.isAll()) {
return new AllHandlerSG(pController, pJs);
} else {
throw new IllegalStateException("Invalid group type");
}
}
}
}
private void createXMLHandler(ComplexTypeSG pController, JavaSource pJs) throws SAXException {
pJs.addExtends(JMSAXElementParser.class);
HandlerSG handlerSG = newHandlerSG(pController, pJs);
handlerSG.generate();
if (!pController.hasSimpleContent()) {
ComplexContentSG ccSG = pController.getComplexContentSG();
ParticleSG[] particles = ccSG.getElementParticles();
for (int i = 0; i < particles.length; i++) {
ParticleSG particle = particles[i];
TypeSG tSG = particle.getObjectSG().getTypeSG();
if (tSG.isComplex() && !tSG.isGlobalClass()) {
tSG.getComplexTypeSG().getXMLHandler(pJs);
}
}
}
}
public JavaSource getXMLHandler(ComplexTypeSG pController, JavaQName pQName) throws SAXException {
final String mName = "getXMLHandler";
log.finest(mName, "->", typeSG.getName());
JavaSourceFactory jsf = typeSG.getSchema().getJavaSourceFactory();
JavaSource js = jsf.newJavaSource(pQName, JavaSource.PUBLIC);
createXMLHandler(pController, js);
log.finest(mName, "<-", js.getQName());
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);
createXMLHandler(pController, 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 Object newComplexContentTypeSG(ComplexTypeSG pController) throws SAXException {
return new JAXBComplexContentTypeSG(pController, xsType);
}
public Object newSimpleContentTypeSG(ComplexTypeSG pController) throws SAXException {
return new JAXBSimpleContentTypeSG(pController, xsType);
}
}