/*
* 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.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.SGlet;
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.js.Parameter;
import org.apache.ws.jaxme.xs.xml.XsQName;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/** Base implementation of {@link DriverSG}, for
* derivation of subclasses.
*/
public abstract class DriverSGImpl implements DriverSG {
private final JavaSource javaSource;
protected final ComplexTypeSG ctSG;
private Parameter paramElement, paramHandler, paramController;
/** Returns the <code>pController</code> parameter for the
* method
* {@link org.apache.ws.jaxme.impl.JMSAXDriver#marshalChilds(JMSAXDriverController, ContentHandler, Object)}.
*/
protected Parameter getParamController() {
return paramController;
}
/** Sets the <code>pController</code> parameter for the
* method
* {@link org.apache.ws.jaxme.impl.JMSAXDriver#marshalChilds(JMSAXDriverController, ContentHandler, Object)}.
*/
protected void setParamController(Parameter pController) {
paramController = pController;
}
/** Returns the <code>pHandler</code> parameter for the
* method
* {@link org.apache.ws.jaxme.impl.JMSAXDriver#marshalChilds(JMSAXDriverController, ContentHandler, Object)}.
*/
protected Parameter getParamHandler() {
return paramHandler;
}
/** Sets the <code>pHandler</code> parameter for the
* method
* {@link org.apache.ws.jaxme.impl.JMSAXDriver#marshalChilds(JMSAXDriverController, ContentHandler, Object)}.
*/
protected void setParamHandler(Parameter pHandler) {
paramHandler = pHandler;
}
/** Returns the <code>pObject</code> parameter for the
* method
* {@link org.apache.ws.jaxme.impl.JMSAXDriver#marshalChilds(JMSAXDriverController, ContentHandler, Object)}.
*/
protected Parameter getParamElement() {
return paramElement;
}
/** Sets the <code>pElement</code> parameter for the
* method
* {@link org.apache.ws.jaxme.impl.JMSAXDriver#marshalChilds(JMSAXDriverController, ContentHandler, Object)}.
*/
protected void setParamElement(Parameter pElement) {
paramElement = pElement;
}
protected DriverSGImpl(ComplexTypeSG pType, JavaSource pJs) {
javaSource = pJs;
ctSG = pType;
}
public JavaSource getJavaSource() { return javaSource; }
public ComplexTypeSG getType() { return ctSG; }
public JavaMethod newGetAttributesMethod() throws SAXException {
JavaMethod jm = getJavaSource().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 = ctSG.getAttributes();
if (myAttributes.length > 0) {
JavaQName elementInterface = ctSG.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;
}
public JavaMethod newMarshalChildsMethod() throws SAXException {
JavaMethod jm = getJavaSource().newJavaMethod("marshalChilds", void.class, JavaSource.PUBLIC);
jm.addThrows(SAXException.class);
Parameter pController = jm.addParam(JMSAXDriverController.class, "pController");
Parameter pHandler = jm.addParam(ContentHandler.class, "pHandler");
Parameter pElement = jm.addParam(Object.class, "pObject");
setParamController(pController);
setParamHandler(pHandler);
setParamElement(pElement);
return jm;
}
public void generate() throws SAXException {
newGetAttributesMethod();
newGetPreferredPrefixMethod();
newMarshalChildsMethod();
}
/** 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() throws SAXException {
List names = new ArrayList();
AttributeSG[] myAttributes = ctSG.getAttributes();
for (int i = 0; i < myAttributes.length; i++) {
XsQName qName = myAttributes[i].getName();
if (qName != null) {
names.add(qName);
}
}
return names;
}
public JavaMethod newGetPreferredPrefixMethod() throws SAXException {
List names = getNames();
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 = getJavaSource().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;
}
}