package org.apache.ws.jaxme.generator.sg.impl.ccsg;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.ws.jaxme.WildcardAttribute;
import org.apache.ws.jaxme.generator.sg.AttributeSG;
import org.apache.ws.jaxme.generator.sg.ComplexTypeSG;
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.TypeSG;
import org.apache.ws.jaxme.impl.JMSAXDriverController;
import org.apache.ws.jaxme.js.DirectAccessible;
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.xs.xml.XsQName;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/** Implementation of
* {@link org.apache.ws.jaxme.generator.sg.impl.ccsg.ParticleVisitor}
* for generating the driver class.
*/
public class DriverGeneratingVisitor extends ParticleVisitorImpl {
private final JavaSource js;
/** Creates a new instance, which writes methods into the
* given class.
*/
public DriverGeneratingVisitor(JavaSource pJs) {
js = pJs;
}
/** This method builds a list of the names, which are being
* used in the element. The list is used for generating the
* method
* {@link org.apache.ws.jaxme.impl.JMSAXDriver#getPreferredPrefix(String)}.
* @throws SAXException
*/
protected List getNames(ComplexTypeSG pType) throws SAXException {
final List names = new ArrayList();
ParticleVisitor visitor = new ParticleVisitorImpl(){
private void addAttributes(ComplexTypeSG pType) {
AttributeSG[] myAttributes = pType.getAttributes();
for (int i = 0; i < myAttributes.length; i++) {
XsQName qName = myAttributes[i].getName();
if (qName != null) {
names.add(qName);
}
}
}
public void emptyType(ComplexTypeSG pType) {
addAttributes(pType);
}
public void simpleContent(ComplexTypeSG pType) {
addAttributes(pType);
}
public void startComplexContent(ComplexTypeSG pType) {
addAttributes(pType);
}
public void simpleElementParticle(GroupSG pGroup, ParticleSG pParticle) throws SAXException {
names.add(pParticle.getObjectSG().getName());
}
public void complexElementParticle(GroupSG pGroup, ParticleSG pParticle) throws SAXException {
names.add(pParticle.getObjectSG().getName());
}
};
new ParticleWalker(visitor).walk(pType);
return names;
}
private JavaMethod newGetPreferredPrefixMethod(ComplexTypeSG pType) throws SAXException {
List names = getNames(pType);
Map uris = new HashMap();
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);
}
}
}
JavaMethod jm = js.newJavaMethod("getPreferredPrefix", String.class, JavaSource.PUBLIC);
DirectAccessible pURI = jm.addParam(String.class, "pURI");
if (!uris.isEmpty()) {
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 null;");
return jm;
}
private JavaMethod newGetAttributesMethod(ComplexTypeSG pType) throws SAXException {
JavaMethod jm = js.newJavaMethod("getAttributes", AttributesImpl.class, JavaSource.PUBLIC);
final DirectAccessible pController = jm.addParam(JMSAXDriverController.class, "pController");
DirectAccessible pObject = jm.addParam(Object.class, "pObject");
jm.addThrows(SAXException.class);
final LocalJavaField result = jm.newJavaField(AttributesImpl.class);
result.addLine("new ", AttributesImpl.class, "()");
AttributeSG[] myAttributes = pType.getAttributes();
if (myAttributes.length > 0) {
JavaQName elementInterface = pType.getClassContext().getXMLInterfaceName();
LocalJavaField element = jm.newJavaField(elementInterface);
element.addLine("(", elementInterface, ") ", pObject);
for (int i = 0; i < myAttributes.length; i++) {
final 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,
", ", pController, ".getAttrQName(this, ", uri, ", ", localPart,
"), \"CDATA\", ", wildcardAttribute, ".getValue());");
jm.addEndFor();
} else {
SGlet sgLet = new SGlet(){
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(result, ".addAttribute(", uri, ", ", localName,
", ", pController, ".getAttrQName(this, ", uri, ", ", localName, "), \"CDATA\", ",
attribute.getTypeSG().getSimpleTypeSG().getCastToString(pMethod, pValue, pController), ");");
}
};
attribute.forAllNonNullValues(jm, element, sgLet);
}
}
}
jm.addLine("return ", result, ";");
return jm;
}
private JavaMethod newMarshalChildsMethod(ComplexTypeSG pType) throws SAXException {
MarshalChildsMethodGeneratingVisitor visitor = new MarshalChildsMethodGeneratingVisitor(js);
new ParticleWalker(visitor).walk(pType);
return visitor.getMethod();
}
private void generate(ComplexTypeSG pType) throws SAXException {
newGetAttributesMethod(pType);
newGetPreferredPrefixMethod(pType);
newMarshalChildsMethod(pType);
}
public void emptyType(ComplexTypeSG pType) throws SAXException {
generate(pType);
}
public void simpleContent(ComplexTypeSG pType) throws SAXException {
generate(pType);
}
public void startComplexContent(ComplexTypeSG pType) throws SAXException {
generate(pType);
}
public void complexElementParticle(GroupSG pGroup, ParticleSG pParticle) throws SAXException {
TypeSG tSG = pParticle.getObjectSG().getTypeSG();
if (tSG.isComplex() && !tSG.isGlobalClass()) {
tSG.getComplexTypeSG().getXMLSerializer(js);
}
}
}