/*
* Copyright 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.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
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.PropertySG;
import org.apache.ws.jaxme.js.DirectAccessible;
import org.apache.ws.jaxme.js.JavaClassInitializer;
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.LocalJavaField;
import org.apache.ws.jaxme.js.Parameter;
import org.apache.ws.jaxme.xs.XSWildcard;
import org.apache.ws.jaxme.xs.xml.XsAnyURI;
import org.apache.ws.jaxme.xs.xml.XsNamespaceList;
import org.apache.ws.jaxme.xs.xml.XsSchemaHeader;
import org.xml.sax.SAXException;
/** <p>PropertySG for attribute wildcards.</p>
*
* @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
*/
public class AnyAttributePropertySG extends JAXBPropertySG {
private final XsNamespaceList namespaceList;
private final XsSchemaHeader schemaHeader;
protected AnyAttributePropertySG(AttributeSG pAttribute, XSWildcard pWildcard) {
super("anyAttribute", pAttribute.getSchema(), pWildcard, null, null);
namespaceList = pWildcard.getNamespaceList();
schemaHeader = pWildcard.getSchemaHeader();
}
protected String getTargetNamespace() {
String targetNamespace = schemaHeader == null ? "" : schemaHeader.getTargetNamespace().toString();
if (targetNamespace == null) {
targetNamespace = "";
}
return targetNamespace;
}
public JavaField getXMLField(PropertySG pController, JavaSource pSource) throws SAXException {
if (pSource.isInterface()) {
return null;
}
JavaQName runtimeType = JavaQNameImpl.getInstance(Map.class);
JavaField jf = pSource.newJavaField(pController.getXMLFieldName(), runtimeType, JavaSource.PRIVATE);
jf.setFinal(true);
jf.addLine("new ", HashMap.class, "()");
return jf;
}
protected JavaField getNamespaces(PropertySG pController, JavaSource pSource) throws SAXException {
if (namespaceList.isAny() || namespaceList.isOther()) {
return null;
}
String namespaces = pController.getXMLFieldName() + "Namespaces";
JavaField jf = pSource.newJavaField(namespaces, Set.class);
jf.setStatic(true);
jf.setFinal(true);
JavaClassInitializer jci = pSource.newJavaClassInitializer();
LocalJavaField set = jci.newJavaField(Set.class);
set.addLine("new ", HashSet.class, "()");
XsAnyURI[] uris = namespaceList.getUris();
for (int i = 0; i < uris.length; i++) {
jci.addLine(set, ".add(", JavaSource.getQuoted(uris[i].toString()), ");");
}
if (namespaceList.isLocalSet()) {
jci.addLine(set, ".add(\"\");");
}
if (namespaceList.isTargetNamespaceSet()) {
jci.addLine(set, ".add(", JavaSource.getQuoted(getTargetNamespace()), ");");
}
jci.addLine(jf, " = ", Collections.class, ".unmodifiableSet(", set, ");");
return jf;
}
protected void getValidNamespaceCheck(PropertySG pController, JavaMethod pMethod, Parameter pName)
throws SAXException {
if (namespaceList.isAny()) {
// No checks for namespace
} else if (namespaceList.isOther()) {
String targetNamespace = getTargetNamespace();
pMethod.addIf(JavaSource.getQuoted(targetNamespace), ".equals(", pName, ".getNamespaceURI())");
pMethod.addThrowNew(IllegalArgumentException.class,
JavaSource.getQuoted("The namespace of the pName argument must not match the target namespace '" +
targetNamespace + "'."));
pMethod.addEndIf();
} else {
String targetNamespace = getTargetNamespace();
String namespaces = pController.getXMLFieldName() + "Namespaces";
pMethod.addIf("!", namespaces, ".contains(", pName, ".getNamespaceURI())");
pMethod.addThrowNew(IllegalArgumentException.class,
JavaSource.getQuoted("The namespace of the pName argument must not match the target namespace '" +
targetNamespace + "'."));
pMethod.addEndIf();
}
}
public JavaMethod getXMLGetMethod(PropertySG pController, JavaSource pSource) throws SAXException {
JavaMethod jm = pSource.newJavaMethod(pController.getXMLGetMethodName(), String.class, JavaSource.PUBLIC);
JavaComment jc = jm.newComment();
jc.addLine("<p>Returns the value of the 'anyAttribute' named <code>pName</code>.</p>");
jc.addLine("@return Attribute value or null, if the attribute is not set.");
jc.addLine("@throws NullPointerException The <code>pName</code> argument is null.");
if (!namespaceList.isAny()) {
jc.addLine("@throws IllegalArgumentException The namespace <code>pName.getNamespaceURI()</code> is invalid.");
}
Parameter pName = jm.addParam(QName.class, "pName");
if (!pSource.isInterface()) {
jm.addIf(pName, " == null");
jm.addThrowNew(NullPointerException.class, JavaSource.getQuoted("The pName argument must not be null."));
jm.addEndIf();
getValidNamespaceCheck(pController, jm, pName);
jm.addLine("return (", String.class, ") ", pController.getXMLFieldName(), ".get(", pName, ");");
}
return jm;
}
public JavaMethod getXMLSetMethod(PropertySG pController, JavaSource pSource) throws SAXException {
JavaMethod jm = pSource.newJavaMethod(pController.getXMLSetMethodName(), void.class, JavaSource.PUBLIC);
JavaComment jc = jm.newComment();
jc.addLine("<p>Sets the 'anyAttribute' named <code>pName</code> to the value <code>pValue</code>.</p>");
if (!namespaceList.isAny()) {
jc.addLine("@throws IllegalArgumentException The namespace <code>pName.getNamespaceURI()</code> is invalid.");
}
jc.addLine("@throws NullPointerException Either of the arguments <code>pName</code> or <code>pValue</code> is null.");
Parameter pName = jm.addParam(QName.class, "pName");
Parameter pValue = jm.addParam(String.class, "pValue");
if (!pSource.isInterface()) {
jm.addIf(pName, " == null");
jm.addThrowNew(NullPointerException.class, JavaSource.getQuoted("The pName argument must not be null."));
jm.addEndIf();
jm.addIf(pValue, " == null");
jm.addThrowNew(NullPointerException.class, JavaSource.getQuoted("The pValue argument must not be null."));
jm.addEndIf();
getValidNamespaceCheck(pController, jm, pName);
jm.addLine(pController.getXMLFieldName(), ".put(", pName, ", ", pValue, ");");
}
return jm;
}
public JavaMethod getXMLUnsetMethod(PropertySG pController, JavaSource pSource) throws SAXException {
JavaMethod jm = pSource.newJavaMethod("un" + pController.getXMLSetMethodName(), boolean.class, JavaSource.PUBLIC);
JavaComment jc = jm.newComment();
jc.addLine("<p>Removes the 'anyAttribute' named <code>pName</code>.</p>");
if (!namespaceList.isAny()) {
jc.addLine("@throws IllegalArgumentException The namespace <code>pName.getNamespaceURI()</code> is invalid.");
}
jc.addLine("@throws NullPointerException Either of the arguments <code>pName</code> or <code>pValue</code> is null.");
jc.addLine("@return True, if the attribute was set, otherwise false.");
Parameter pName = jm.addParam(QName.class, "pName");
if (!pSource.isInterface()) {
jm.addIf(pName, " == null");
jm.addThrowNew(NullPointerException.class, JavaSource.getQuoted("The pName argument must not be null."));
jm.addEndIf();
getValidNamespaceCheck(pController, jm, pName);
jm.addLine("return ", pController.getXMLFieldName(), ".remove(", pName, ") != null;");
}
return jm;
}
public JavaMethod getXMLGetArrayMethod(PropertySG pController, JavaSource pSource) throws SAXException {
JavaMethod jm = pSource.newJavaMethod(pController.getXMLGetMethodName() + "Array", WildcardAttribute[].class, JavaSource.PUBLIC);
JavaComment jc = jm.newComment();
jc.addLine("<p>Returns the array of 'anyAttributes'.</p>");
LocalJavaField size = jm.newJavaField(int.class);
size.addLine(pController.getXMLFieldName(), ".size()");
LocalJavaField result = jm.newJavaField(jm.getType());
result.addLine("new ", WildcardAttribute.class, "[", size, "]");
DirectAccessible iter = jm.addForCollection(new Object[]{pController.getXMLFieldName(), ".entrySet()"});
LocalJavaField entry = jm.newJavaField(Map.Entry.class);
entry.addLine("(", Map.Entry.class, ") ", iter, ".next()");
if (!pSource.isInterface()) {
jm.addLine(result, "[--", size, "] = new ", WildcardAttribute.class, "((",
QName.class, ") ", entry, ".getKey(), (", String.class, ") ",
entry, ".getValue());");
jm.addEndFor();
jm.addLine("return ", result, ";");
}
return jm;
}
public void generate(PropertySG pController, JavaSource pSource) throws SAXException {
super.generate(pController, pSource);
getXMLUnsetMethod(pController, pSource);
getXMLGetArrayMethod(pController, pSource);
if (!pSource.isInterface()) {
getNamespaces(pController, pSource);
}
}
}