blob: 575af472410f79f5d4737812a26ecb2f271189fb [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans.impl.schema;
import java.io.Writer;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import javax.xml.namespace.QName;
import org.apache.xmlbeans.impl.common.NameUtil;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.SchemaTypeSystem;
import org.apache.xmlbeans.SchemaProperty;
import org.apache.xmlbeans.SchemaStringEnumEntry;
import org.apache.xmlbeans.XmlObject;
/**
* Prints the java code for a single schema type
*/
public final class SchemaTypeCodePrinter
{
Writer _writer;
int _indent;
static final String LINE_SEPARATOR =
System.getProperty("line.separator") == null
? "\n"
: System.getProperty("line.separator");
static final String MAX_SPACES = " ";
static final int INDENT_INCREMENT = 4;
public static final String INDEX_CLASSNAME = "TypeSystemHolder";
public SchemaTypeCodePrinter ( Writer writer )
{
_writer = writer;
_indent = 0;
}
void indent()
{
_indent += INDENT_INCREMENT;
}
void outdent()
{
_indent -= INDENT_INCREMENT;
}
String encodeString ( String s )
{
StringBuffer sb = new StringBuffer();
sb.append( '"' );
for ( int i = 0 ; i < s.length() ; i++ )
{
char ch = s.charAt( i );
if (ch == '"')
{
sb.append( '\\' );
sb.append( '\"' );
}
else if (ch == '\\')
{
sb.append( '\\' );
sb.append( '\\' );
}
else if (ch == '\r')
{
sb.append( '\\' );
sb.append( 'r' );
}
else if (ch == '\n')
{
sb.append( '\\' );
sb.append( 'n' );
}
else if (ch == '\t')
{
sb.append( '\\' );
sb.append( 't' );
}
else
sb.append( ch );
}
sb.append( '"' );
return sb.toString();
}
void emit(String s) throws IOException
{
int indent = _indent;
if (indent > MAX_SPACES.length() / 2)
indent = MAX_SPACES.length() / 4 + indent / 2;
if (indent > MAX_SPACES.length())
indent = MAX_SPACES.length();
_writer.write(MAX_SPACES.substring(0, indent));
_writer.write(s);
_writer.write(LINE_SEPARATOR);
// System.out.print(MAX_SPACES.substring(0, indent));
// System.out.println(s);
}
public static void printTypeImpl ( Writer writer, SchemaType sType )
throws IOException
{
new SchemaTypeCodePrinter( writer ).printTypeImpl( sType, sType.getTypeSystem() );
}
public static void printType ( Writer writer, SchemaType sType )
throws IOException
{
new SchemaTypeCodePrinter( writer ). printType( sType, sType.getTypeSystem() );
}
public static void printLoader ( Writer writer, SchemaTypeSystem system )
throws IOException
{
new SchemaTypeCodePrinter( writer ).printIndexType( system );
}
void printType(SchemaType sType, SchemaTypeSystem system) throws IOException
{
printTopComment(sType);
printPackage(sType, true);
emit("");
printInnerType(sType, system);
_writer.flush();
}
void printTypeImpl(SchemaType sType, SchemaTypeSystem system) throws IOException
{
printTopComment(sType);
printPackage(sType, false);
printInnerTypeImpl(sType, system, false);
}
/**
* Since not all schema types have java types, this skips
* over any that don't and gives you the nearest java base type.
*/
String findJavaType ( SchemaType sType )
{
while ( sType.getFullJavaName() == null )
sType = sType.getBaseType();
return sType.getFullJavaName();
}
static String prettyQName(QName qname)
{
String result = qname.getLocalPart();
if (qname.getNamespaceURI() != null)
result += "(@" + qname.getNamespaceURI() + ")";
return result;
}
void printInnerTypeJavaDoc(SchemaType sType) throws IOException
{
QName name = sType.getName();
if (name == null)
{
if (sType.isDocumentType())
name = sType.getDocumentElementName();
else if (sType.isAttributeType())
name = sType.getAttributeTypeAttributeName();
else if (sType.getContainerField() != null)
name = sType.getContainerField().getName();
}
emit("/**");
if (sType.isDocumentType())
emit(" * A document containing one " + prettyQName(name) + " element.");
else if (sType.isAttributeType())
emit(" * A document containing one " + prettyQName(name) + " attribute.");
else if (name != null)
emit(" * An XML " + prettyQName(name) + ".");
else
emit(" * An anonymous inner XML type.");
emit(" *");
switch (sType.getSimpleVariety())
{
case SchemaType.NOT_SIMPLE:
emit(" * This is a complex type.");
break;
case SchemaType.ATOMIC:
emit(" * This is an atomic type that is a restriction of " + sType.getBaseType().getFullJavaName() + ".");
break;
case SchemaType.LIST:
emit(" * This is a list type whose items are " + sType.getListItemType().getFullJavaName() + ".");
break;
case SchemaType.UNION:
emit(" * This is a union type. Instances are of one of the following types:");
SchemaType[] members = sType.getUnionConstituentTypes();
for (int i = 0; i < members.length; i++)
emit(" * " + members[i].getFullJavaName());
break;
}
emit(" */");
}
public static String indexClassForSystem(SchemaTypeSystem system)
{
String name = system.getName();
return name + "." + INDEX_CLASSNAME;
}
static String shortIndexClassForSystem(SchemaTypeSystem system)
{
return INDEX_CLASSNAME;
}
void printStaticTypeDeclaration(SchemaType sType, SchemaTypeSystem system) throws IOException
{
emit("public static final org.apache.xmlbeans.SchemaType type = (org.apache.xmlbeans.SchemaType)" +
indexClassForSystem(system) +
".typeSystem.resolveHandle(\"" +
((SchemaTypeSystemImpl)system).handleForType(sType) + "\");");
}
void printIndexType(SchemaTypeSystem system) throws IOException
{
String shortName = shortIndexClassForSystem(system);
emit("package " + system.getName() + ";");
emit("");
emit("public final class " + shortName);
emit("{");
indent();
emit("private " + shortName + "() { }");
emit("public static final org.apache.xmlbeans.SchemaTypeSystem typeSystem = loadTypeSystem();");
emit("static { typeSystem.resolve(); }");
emit("private static final org.apache.xmlbeans.SchemaTypeSystem loadTypeSystem()");
emit("{");
indent();
emit("try { return (org.apache.xmlbeans.SchemaTypeSystem)Class.forName(\"org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl\", true, " + shortName + ".class.getClassLoader()).getConstructor(new Class[] { Class.class }).newInstance(new Object[] { " + shortName + ".class }); }");
emit("catch (ClassNotFoundException e) { throw new RuntimeException(\"Cannot load org.apache.xmlbeans.impl.SchemaTypeSystemImpl: make sure xbean.jar is on the classpath.\", e); }");
emit("catch (Exception e) { throw new RuntimeException(\"Could not instantiate SchemaTypeSystemImpl (\" + e.toString() + \"): is the version of xbean.jar correct?\", e); }");
outdent();
emit("}");
outdent();
emit("}");
}
void printInnerType(SchemaType sType, SchemaTypeSystem system) throws IOException
{
emit("");
printInnerTypeJavaDoc(sType);
startInterface(sType);
printStaticTypeDeclaration(sType, system);
if (sType.isSimpleType())
{
if (sType.hasStringEnumValues())
printStringEnumeration(sType);
}
else
{
SchemaProperty[] props = sType.getDerivedProperties();
for (int i = 0; i < props.length; i++)
{
SchemaProperty prop = props[i];
printPropertyGetters(
prop.getName(),
prop.isAttribute(),
prop.getJavaPropertyName(),
prop.getJavaTypeCode(),
javaTypeForProperty(prop),
xmlTypeForProperty(prop),
prop.hasNillable() != SchemaProperty.NEVER,
prop.extendsJavaOption(),
prop.extendsJavaArray(),
prop.extendsJavaSingleton()
);
if (!prop.isReadOnly())
{
printPropertySetters(
prop.getName(),
prop.isAttribute(),
prop.getJavaPropertyName(),
prop.getJavaTypeCode(),
javaTypeForProperty(prop),
xmlTypeForProperty(prop),
prop.hasNillable() != SchemaProperty.NEVER,
prop.extendsJavaOption(),
prop.extendsJavaArray(),
prop.extendsJavaSingleton()
);
}
}
}
printNestedInnerTypes(sType, system);
printFactory(sType);
endBlock();
}
void printFactory(SchemaType sType) throws IOException
{
// Only need full factories for top-level types
boolean fullFactory = true;
if (sType.isAnonymousType() && ! sType.isDocumentType() && !sType.isAttributeType())
fullFactory = false;
String fullName = sType.getFullJavaName().replace('$', '.');
emit("");
emit("/**");
emit(" * A factory class with static methods for creating instances");
emit(" * of this type.");
emit(" */");
emit("");
// BUGBUG - Can I use the name loader here? could it be a
// nested type name? It is lower case!
emit("public static final class Factory");
emit("{");
indent();
if (sType.isSimpleType())
{
emit("public static " + fullName + " newValue(java.lang.Object obj) {");
emit(" return (" + fullName + ") type.newValue( obj ); }");
emit("");
}
emit("public static " + fullName + " newInstance() {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, null ); }");
emit("");
emit("public static " + fullName + " newInstance(org.apache.xmlbeans.XmlOptions options) {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newInstance( type, options ); }");
emit("");
if (fullFactory)
{
emit("public static " + fullName + " parse(java.lang.String s) throws org.apache.xmlbeans.XmlException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( s, type, null ); }");
emit("");
emit("public static " + fullName + " parse(java.lang.String s, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( s, type, options ); }");
emit("");
emit("public static " + fullName + " parse(java.io.File f) throws org.apache.xmlbeans.XmlException, java.io.IOException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( f, type, null ); }");
emit("");
emit("public static " + fullName + " parse(java.io.File f, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( f, type, options ); }");
emit("");
emit("public static " + fullName + " parse(java.net.URL u) throws org.apache.xmlbeans.XmlException, java.io.IOException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, null ); }");
emit("");
emit("public static " + fullName + " parse(java.net.URL u, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( u, type, options ); }");
emit("");
emit("public static " + fullName + " parse(java.io.InputStream is) throws org.apache.xmlbeans.XmlException, java.io.IOException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, null ); }");
emit("");
emit("public static " + fullName + " parse(java.io.InputStream is, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( is, type, options ); }");
emit("");
emit("public static " + fullName + " parse(java.io.Reader r) throws org.apache.xmlbeans.XmlException, java.io.IOException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, null ); }");
emit("");
emit("public static " + fullName + " parse(java.io.Reader r, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, java.io.IOException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( r, type, options ); }");
emit("");
emit("public static " + fullName + " parse(org.w3c.dom.Node node) throws org.apache.xmlbeans.XmlException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, null ); }");
emit("");
emit("public static " + fullName + " parse(org.w3c.dom.Node node, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( node, type, options ); }");
emit("");
emit("public static " + fullName + " parse(weblogic.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, weblogic.xml.stream.XMLStreamException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, null ); }");
emit("");
emit("public static " + fullName + " parse(weblogic.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, weblogic.xml.stream.XMLStreamException {");
emit(" return (" + fullName + ") org.apache.xmlbeans.XmlBeans.getContextTypeLoader().parse( xis, type, options ); }");
emit("");
emit("public static weblogic.xml.stream.XMLInputStream newValidatingXMLInputStream(weblogic.xml.stream.XMLInputStream xis) throws org.apache.xmlbeans.XmlException, weblogic.xml.stream.XMLStreamException {");
emit(" return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, null ); }");
emit("");
emit("public static weblogic.xml.stream.XMLInputStream newValidatingXMLInputStream(weblogic.xml.stream.XMLInputStream xis, org.apache.xmlbeans.XmlOptions options) throws org.apache.xmlbeans.XmlException, weblogic.xml.stream.XMLStreamException {");
emit(" return org.apache.xmlbeans.XmlBeans.getContextTypeLoader().newValidatingXMLInputStream( xis, type, options ); }");
emit("");
}
emit("private Factory() { } // No instance of this class allowed");
outdent();
emit("}");
}
void printNestedInnerTypes(SchemaType sType, SchemaTypeSystem system) throws IOException
{
SchemaType[] anonTypes = sType.getAnonymousTypes();
for (int i = 0; i < anonTypes.length; i++)
{
if (anonTypes[i].isSkippedAnonymousType())
printNestedInnerTypes(anonTypes[i], system);
else
printInnerType(anonTypes[i], system);
}
}
void printTopComment(SchemaType sType) throws IOException
{
emit("/*");
if (sType.getName() != null)
{
emit(" * XML Type: " + sType.getName().getLocalPart());
emit(" * Namespace: " + sType.getName().getNamespaceURI());
}
else
{
QName thename = null;
if (sType.isDocumentType())
{
thename = sType.getDocumentElementName();
emit(" * An XML document type.");
}
else if (sType.isAttributeType())
{
thename = sType.getAttributeTypeAttributeName();
emit(" * An XML attribute type.");
}
else
assert false;
assert( thename != null );
emit(" * Localname: " + thename.getLocalPart());
emit(" * Namespace: " + thename.getNamespaceURI());
}
emit(" * Java type: " + sType.getFullJavaName());
emit(" *");
emit(" * Automatically generated - do not modify.");
emit(" */");
}
void printPackage(SchemaType sType, boolean intf) throws IOException
{
String fqjn;
if (intf)
fqjn = sType.getFullJavaName();
else
fqjn = sType.getFullJavaImplName();
int lastdot = fqjn.lastIndexOf('.');
if (lastdot < 0)
return;
String pkg = fqjn.substring(0, lastdot);
emit("package " + pkg + ";");
}
void startInterface(SchemaType sType) throws IOException
{
String shortName = sType.getShortJavaName();
String baseInterface = findJavaType(sType.getBaseType());
/*
StringBuffer specializedInterfaces = new StringBuffer();
if (sType.getSimpleVariety() == SchemaType.ATOMIC &&
sType.getPrimitiveType().getBuiltinTypeCode() == SchemaType.BTC_DECIMAL)
{
int bits = sType.getDecimalSize();
if (bits == SchemaType.SIZE_BIG_INTEGER)
specializedInterfaces.append(", org.apache.xmlbeans.BigIntegerValue");
if (bits == SchemaType.SIZE_LONG)
specializedInterfaces.append(", org.apache.xmlbeans.LongValue");
if (bits <= SchemaType.SIZE_INT)
specializedInterfaces.append(", org.apache.xmlbeans.IntValue");
}
if (sType.getSimpleVariety() == SchemaType.LIST)
specializedInterfaces.append(", org.apache.xmlbeans.ListValue");
if (sType.getSimpleVariety() == SchemaType.UNION)
{
SchemaType ctype = sType.getUnionCommonBaseType();
String javaTypeHolder = javaTypeHolderForType(ctype);
if (javaTypeHolder != null)
specializedInterfaces.append(", " + javaTypeHolder);
}
*/
emit("public interface " + shortName + " extends " + baseInterface);
emit("{");
indent();
emitSpecializedAccessors(sType);
}
private void emitSpecializedAccessors(SchemaType sType) throws IOException
{
if (sType.getSimpleVariety() == SchemaType.ATOMIC &&
sType.getPrimitiveType().getBuiltinTypeCode() == SchemaType.BTC_DECIMAL)
{
int bits = sType.getDecimalSize();
int parentBits = sType.getBaseType().getDecimalSize();
if (bits != parentBits || sType.getBaseType().getFullJavaName() == null)
{
if (bits == SchemaType.SIZE_BIG_INTEGER)
{
emit("java.math.BigInteger getBigIntegerValue();");
emit("setBigIntegerValue(java.math.BigInteger bi);");
emit("/** @deprecated */");
emit("java.math.BigInteger bigIntegerValue();");
emit("/** @deprecated */");
emit("void set(java.math.BigInteger bi);");
}
else if (bits == SchemaType.SIZE_LONG)
{
emit("long getLongValue();");
emit("void setLongValue(long l);");
emit("/** @deprecated */");
emit("long longValue();");
emit("/** @deprecated */");
emit("void set(long l);");
}
else if (bits == SchemaType.SIZE_INT)
{
emit("int getIntValue();");
emit("void setIntValue(int i);");
emit("/** @deprecated */");
emit("int intValue();");
emit("/** @deprecated */");
emit("void set(int i);");
}
else if (bits == SchemaType.SIZE_SHORT)
{
emit("short getShortValue();");
emit("void setShortValue(short s);");
emit("/** @deprecated */");
emit("short shortValue();");
emit("/** @deprecated */");
emit("void set(short s);");
}
else if (bits == SchemaType.SIZE_BYTE)
{
emit("byte getByteValue();");
emit("void setByteValue(byte b);");
emit("/** @deprecated */");
emit("byte byteValue();");
emit("/** @deprecated */");
emit("void set(byte b);");
}
}
}
if (sType.getSimpleVariety() == SchemaType.UNION)
{
emit("java.lang.Object getObjectValue();");
emit("void setObjectValue(java.lang.Object val);");
emit("/** @deprecated */");
emit("java.lang.Object objectValue();");
emit("/** @deprecated */");
emit("void objectSet(java.lang.Object val);");
emit("org.apache.xmlbeans.SchemaType instanceType();");
SchemaType ctype = sType.getUnionCommonBaseType();
if (ctype != null && ctype.getSimpleVariety() != SchemaType.UNION);
emitSpecializedAccessors(ctype);
}
if (sType.getSimpleVariety() == SchemaType.LIST)
{
emit("java.util.List getListValue();");
emit("java.util.List xgetListValue();");
emit("void setListValue(java.util.List list);");
emit("/** @deprecated */");
emit("java.util.List listValue();");
emit("/** @deprecated */");
emit("java.util.List xlistValue();");
emit("/** @deprecated */");
emit("void set(java.util.List list);");
}
}
void startBlock() throws IOException
{
emit("{");
indent();
}
void endBlock() throws IOException
{
outdent();
emit("}");
}
void printJavaDoc(String sentence) throws IOException
{
emit("");
emit("/**");
emit(" * " + sentence);
emit(" */");
}
void printShortJavaDoc(String sentence) throws IOException
{
emit("/** " + sentence + " */");
}
static SchemaType findBaseEnumType(SchemaType sType)
{
while (sType.getBaseType().hasStringEnumValues())
sType = sType.getBaseType();
return sType;
}
public static String javaStringEscape(String str)
{
// forbidden: \n, \r, \", \\.
test: {
for (int i = 0; i < str.length(); i++)
{
switch (str.charAt(i))
{
case '\n':
case '\r':
case '\"':
case '\\':
break test;
}
}
return str;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < str.length(); i++)
{
char ch = str.charAt(i);
switch (ch)
{
default:
sb.append(ch);
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
}
}
return sb.toString();
}
void printStringEnumeration(SchemaType sType) throws IOException
{
SchemaType baseEnumType = findBaseEnumType(sType);
String baseEnumClass = baseEnumType.getFullJavaName();
if (baseEnumType == sType)
{
emit("");
emit("org.apache.xmlbeans.StringEnumAbstractBase enumValue();");
emit("void set(org.apache.xmlbeans.StringEnumAbstractBase e);");
}
emit("");
SchemaStringEnumEntry[] entries = sType.getStringEnumEntries();
for (int i = 0; i < entries.length; i++)
{
String enumValue = entries[i].getString();
String constName = entries[i].getEnumName();
if (baseEnumType != sType)
emit("static final " + baseEnumClass + ".Enum " + constName + " = " + baseEnumClass + "." + constName + ";");
else
emit("static final Enum " + constName + " = Enum.forString(\"" + javaStringEscape(enumValue) + "\");");
}
emit("");
for (int i = 0; i < entries.length; i++)
{
String constName = "INT_" + entries[i].getEnumName();
if (baseEnumType != sType)
emit("static final int " + constName + " = " + baseEnumClass + "." + constName + ";");
else
emit("static final int " + constName + " = Enum." + constName + ";");
}
if (baseEnumType == sType)
{
emit("");
emit("/**");
emit(" * Enumeration value class for " + baseEnumClass + ".");
emit(" * These enum values can be used as follows:");
emit(" * <pre>");
emit(" * enum.toString(); // returns the string value of the enum");
emit(" * enum.intValue(); // returns an int value, useful for switches");
if (entries.length > 0)
emit(" * // e.g., case Enum.INT_" + entries[0].getEnumName());
emit(" * Enum.forString(s); // returns the enum value for a string");
emit(" * Enum.forInt(i); // returns the enum value for an int");
emit(" * </pre>");
emit(" * Enumeration objects are immutable singleton objects that");
emit(" * can be compared using == object equality. They have no");
emit(" * public constructor. See the constants defined within this");
emit(" * class for all the valid values.");
emit(" */");
emit("static final class Enum extends org.apache.xmlbeans.StringEnumAbstractBase");
emit("{");
indent();
emit("/**");
emit(" * Returns the enum value for a string, or null if none.");
emit(" */");
emit("public static Enum forString(java.lang.String s)");
emit(" { return (Enum)table.forString(s); }");
emit("/**");
emit(" * Returns the enum value corresponding to an int, or null if none.");
emit(" */");
emit("public static Enum forInt(int i)");
emit(" { return (Enum)table.forInt(i); }");
emit("");
emit("private Enum(java.lang.String s, int i)");
emit(" { super(s, i); }");
emit("");
for (int i = 0; i < entries.length; i++)
{
String constName = "INT_" + entries[i].getEnumName();
int intValue = entries[i].getIntValue();
emit("static final int " + constName + " = " + intValue + ";");
}
emit("");
emit("public static final org.apache.xmlbeans.StringEnumAbstractBase.Table table =");
emit(" new org.apache.xmlbeans.StringEnumAbstractBase.Table");
emit("(");
indent();
emit("new Enum[]");
emit("{");
indent();
for (int i = 0; i < entries.length; i++)
{
String enumValue = entries[i].getString();
String constName = "INT_" + entries[i].getEnumName();
emit("new Enum(\"" + javaStringEscape(enumValue) + "\", " + constName + "),");
}
outdent();
emit("}");
outdent();
emit(");");
emit("private static final long serialVersionUID = 1L;");
emit("private Object readResolve() { return forInt(intValue()); } ");
outdent();
emit("}");
}
}
String xmlTypeForProperty(SchemaProperty sProp)
{
SchemaType sType = sProp.javaBasedOnType();
return findJavaType(sType).replace('$', '.');
}
static boolean xmlTypeForPropertyIsUnion(SchemaProperty sProp)
{
SchemaType sType = sProp.javaBasedOnType();
return (sType.isSimpleType() && sType.getSimpleVariety() == SchemaType.UNION);
}
String javaTypeForProperty(SchemaProperty sProp)
{
// The type to use is the XML object....
if (sProp.getJavaTypeCode() == SchemaProperty.XML_OBJECT)
{
SchemaType sType = sProp.javaBasedOnType();
return findJavaType(sType).replace('$', '.');
}
switch (sProp.getJavaTypeCode())
{
case SchemaProperty.JAVA_BOOLEAN:
return "boolean";
case SchemaProperty.JAVA_FLOAT:
return "float";
case SchemaProperty.JAVA_DOUBLE:
return "double";
case SchemaProperty.JAVA_BYTE:
return "byte";
case SchemaProperty.JAVA_SHORT:
return "short";
case SchemaProperty.JAVA_INT:
return "int";
case SchemaProperty.JAVA_LONG:
return "long";
case SchemaProperty.JAVA_BIG_DECIMAL:
return "java.math.BigDecimal";
case SchemaProperty.JAVA_BIG_INTEGER:
return "java.math.BigInteger";
case SchemaProperty.JAVA_STRING:
return "java.lang.String";
case SchemaProperty.JAVA_BYTE_ARRAY:
return "byte[]";
case SchemaProperty.JAVA_GDATE:
return "org.apache.xmlbeans.GDate";
case SchemaProperty.JAVA_GDURATION:
return "org.apache.xmlbeans.GDuration";
case SchemaProperty.JAVA_DATE:
return "java.util.Date";
case SchemaProperty.JAVA_QNAME:
return "javax.xml.namespace.QName";
case SchemaProperty.JAVA_LIST:
return "java.util.List";
case SchemaProperty.JAVA_CALENDAR:
return "java.util.Calendar";
case SchemaProperty.JAVA_ENUM:
SchemaType sType = sProp.javaBasedOnType().getBaseEnumType();
return findJavaType(sType).replace('$', '.') + ".Enum";
case SchemaProperty.JAVA_OBJECT:
return "java.lang.Object";
default:
assert(false);
throw new IllegalStateException();
}
}
void printPropertyGetters(QName qName, boolean isAttr,
String propertyName, int javaType,
String type, String xtype,
boolean nillable, boolean optional,
boolean several, boolean singleton)
throws IOException
{
String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element");
boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);
if (singleton)
{
printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc);
emit(type + " get" + propertyName + "();");
if (!xmltype)
{
printJavaDoc((several ? "Gets (as xml) first " : "Gets (as xml) the ") + propdesc);
emit(xtype + " xget" + propertyName + "();");
}
if (nillable)
{
printJavaDoc((several ? "Tests for nil first " : "Tests for nil ") + propdesc);
emit("boolean isNil" + propertyName + "();");
}
}
if (optional)
{
printJavaDoc((several ? "True if has at least one " : "True if has ") + propdesc);
emit("boolean isSet" + propertyName + "();");
}
if (several)
{
String arrayName = propertyName + "Array";
printJavaDoc("Gets array of all " + propdesc + "s");
emit(type + "[] get" + arrayName + "();");
printJavaDoc("Gets ith " + propdesc);
emit(type + " get" + arrayName + "(int i);");
if (!xmltype)
{
printJavaDoc("Gets (as xml) array of all " + propdesc + "s");
emit(xtype + "[] xget" + arrayName + "();");
printJavaDoc("Gets (as xml) ith " + propdesc);
emit(xtype + " xget" + arrayName + "(int i);");
}
if (nillable)
{
printJavaDoc("Tests for nil ith " + propdesc);
emit("boolean isNil" + arrayName + "(int i);");
}
printJavaDoc("Returns number of " + propdesc);
emit("int sizeOf" + arrayName + "();");
}
}
void printPropertySetters(QName qName, boolean isAttr,
String propertyName, int javaType, String type, String xtype,
boolean nillable, boolean optional,
boolean several, boolean singleton)
throws IOException
{
String safeVarName = NameUtil.nonJavaKeyword(NameUtil.lowerCamelCase(propertyName));
if (safeVarName.equals("i"))
safeVarName = "iValue";
boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);
String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element");
if (singleton)
{
printJavaDoc((several ? "Sets first " : "Sets the ") + propdesc);
emit("void set" + propertyName + "(" + type + " " + safeVarName + ");");
if (!xmltype)
{
printJavaDoc((several ? "Sets (as xml) first " : "Sets (as xml) the ") + propdesc);
emit("void xset" + propertyName + "(" + xtype + " " + safeVarName + ");");
}
if (xmltype && !several)
{
printJavaDoc("Appends and returns a new empty " + propdesc);
emit(xtype + " addNew" + propertyName + "();");
}
if (nillable)
{
printJavaDoc((several ? "Nils the first " : "Nils the ") + propdesc);
emit("void setNil" + propertyName + "();");
}
}
if (optional)
{
printJavaDoc((several ? "Removes first " : "Unsets the ") + propdesc);
emit("void unset" + propertyName + "();");
}
if (several)
{
String arrayName = propertyName + "Array";
printJavaDoc("Sets array of all " + propdesc);
emit("void set" + arrayName + "(" + type + "[] " + safeVarName + "Array);");
printJavaDoc("Sets ith " + propdesc);
emit("void set" + arrayName + "(int i, " + type + " " + safeVarName + ");");
if (!xmltype)
{
printJavaDoc("Sets (as xml) array of all " + propdesc);
emit("void xset" + arrayName + "(" + xtype + "[]" + safeVarName + "Array);");
printJavaDoc("Sets (as xml) ith " + propdesc);
emit("void xset" + arrayName + "(int i, " + xtype + " " + safeVarName + ");");
}
if (nillable)
{
printJavaDoc("Nils the ith " + propdesc);
emit("void setNil" + arrayName + "(int i);");
}
if (!xmltype)
{
printJavaDoc("Inserts the value as the ith " + propdesc);
emit("void insert" + propertyName + "(int i, " + type + " " + safeVarName + ");");
printJavaDoc("Appends the value as the last " + propdesc);
emit("void add" + propertyName + "(" + type + " " + safeVarName + ");");
}
if (xmltype)
{
printJavaDoc("Inserts and returns a new empty value (as xml) as the ith " + propdesc);
emit(xtype + " insertNew" + propertyName + "(int i);");
printJavaDoc("Appends and returns a new empty value (as xml) as the last " + propdesc);
emit(xtype + " addNew" + propertyName + "();");
}
printJavaDoc("Removes the ith " + propdesc);
emit("void remove" + propertyName + "(int i);");
}
}
String getAtomicRestrictionType(SchemaType sType) {
SchemaType pType = sType.getPrimitiveType();
switch (pType.getBuiltinTypeCode())
{
case SchemaType.BTC_ANY_SIMPLE:
return "org.apache.xmlbeans.impl.values.XmlAnySimpleTypeImpl";
case SchemaType.BTC_BOOLEAN:
return "org.apache.xmlbeans.impl.values.JavaBooleanHolderEx";
case SchemaType.BTC_BASE_64_BINARY:
return "org.apache.xmlbeans.impl.values.JavaBase64HolderEx";
case SchemaType.BTC_HEX_BINARY:
return "org.apache.xmlbeans.impl.values.JavaHexBinaryHolderEx";
case SchemaType.BTC_ANY_URI:
return "org.apache.xmlbeans.impl.values.JavaUriHolderEx";
case SchemaType.BTC_QNAME:
return "org.apache.xmlbeans.impl.values.JavaQNameHolderEx";
case SchemaType.BTC_NOTATION:
return "org.apache.xmlbeans.impl.values.JavaNotationHolderEx";
case SchemaType.BTC_FLOAT:
return "org.apache.xmlbeans.impl.values.JavaFloatHolderEx";
case SchemaType.BTC_DOUBLE:
return "org.apache.xmlbeans.impl.values.JavaDoubleHolderEx";
case SchemaType.BTC_DECIMAL:
switch (sType.getDecimalSize())
{
default:
assert(false);
case SchemaType.SIZE_BIG_DECIMAL:
return "org.apache.xmlbeans.impl.values.JavaDecimalHolderEx";
case SchemaType.SIZE_BIG_INTEGER:
return "org.apache.xmlbeans.impl.values.JavaIntegerHolderEx";
case SchemaType.SIZE_LONG:
return "org.apache.xmlbeans.impl.values.JavaLongHolderEx";
case SchemaType.SIZE_INT:
case SchemaType.SIZE_SHORT:
case SchemaType.SIZE_BYTE:
return "org.apache.xmlbeans.impl.values.JavaIntHolderEx";
}
case SchemaType.BTC_STRING:
if (sType.hasStringEnumValues())
return "org.apache.xmlbeans.impl.values.JavaStringEnumerationHolderEx";
else
return "org.apache.xmlbeans.impl.values.JavaStringHolderEx";
case SchemaType.BTC_DATE_TIME:
case SchemaType.BTC_TIME:
case SchemaType.BTC_DATE:
case SchemaType.BTC_G_YEAR_MONTH:
case SchemaType.BTC_G_YEAR:
case SchemaType.BTC_G_MONTH_DAY:
case SchemaType.BTC_G_DAY:
case SchemaType.BTC_G_MONTH:
return "org.apache.xmlbeans.impl.values.JavaGDateHolderEx";
case SchemaType.BTC_DURATION:
return "org.apache.xmlbeans.impl.values.JavaGDurationHolderEx";
default:
assert(false) : "unrecognized primitive type";
return null;
}
}
static SchemaType findBaseType(SchemaType sType)
{
while (sType.getFullJavaName() == null)
sType = sType.getBaseType();
return sType;
}
String getBaseClass(SchemaType sType) {
SchemaType baseType = findBaseType(sType.getBaseType());
switch (sType.getSimpleVariety())
{
case SchemaType.NOT_SIMPLE:
// non-simple-content: inherit from base type impl
if (!XmlObject.type.equals(baseType))
return baseType.getFullJavaImplName();
return "org.apache.xmlbeans.impl.values.XmlComplexContentImpl";
case SchemaType.ATOMIC:
// We should only get called for restrictions
assert(! sType.isBuiltinType());
return getAtomicRestrictionType(sType);
case SchemaType.LIST:
return "org.apache.xmlbeans.impl.values.XmlListImpl";
case SchemaType.UNION:
return "org.apache.xmlbeans.impl.values.XmlUnionImpl";
default:
throw new IllegalStateException();
}
}
void printConstructor(SchemaType sType, String shortName) throws IOException {
emit("");
emit("public " + shortName + "(org.apache.xmlbeans.SchemaType sType)");
startBlock();
emit("super(sType" + (sType.getSimpleVariety() == SchemaType.NOT_SIMPLE ?
"":
", " + !sType.isSimpleType()) +
");");
endBlock();
if (sType.getSimpleVariety() != SchemaType.NOT_SIMPLE)
{
emit("");
emit("protected " + shortName + "(org.apache.xmlbeans.SchemaType sType, boolean b)");
startBlock();
emit("super(sType, b);");
endBlock();
}
}
void startClass(SchemaType sType, boolean isInner) throws IOException
{
String shortName = sType.getShortJavaImplName();
String baseClass = getBaseClass(sType);
StringBuffer interfaces = new StringBuffer();
interfaces.append(sType.getFullJavaName().replace('$', '.'));
if (sType.getSimpleVariety() == SchemaType.UNION) {
SchemaType[] memberTypes = sType.getUnionMemberTypes();
for (int i = 0 ; i < memberTypes.length ; i++)
interfaces.append(", " + memberTypes[i].getFullJavaName().replace('$', '.'));
}
emit("public " + ( isInner ? "static ": "" ) + "class " + shortName +
" extends " + baseClass + " implements " + interfaces.toString());
startBlock();
}
void makeAttributeDefaultValue(String jtargetType, SchemaProperty prop, String identifier) throws IOException
{
String fullName = jtargetType;
if (fullName == null)
fullName = prop.javaBasedOnType().getFullJavaName().replace('$', '.');
emit("target = (" + fullName + ")get_default_attribute_value(" + identifier + ");");
}
void makeMissingValue(int javaType) throws IOException
{
switch (javaType)
{
case SchemaProperty.JAVA_BOOLEAN:
emit("return false;"); break;
case SchemaProperty.JAVA_FLOAT:
emit("return 0.0f;"); break;
case SchemaProperty.JAVA_DOUBLE:
emit("return 0.0;"); break;
case SchemaProperty.JAVA_BYTE:
case SchemaProperty.JAVA_SHORT:
case SchemaProperty.JAVA_INT:
emit("return 0;"); break;
case SchemaProperty.JAVA_LONG:
emit("return 0L;"); break;
default:
case SchemaProperty.XML_OBJECT:
case SchemaProperty.JAVA_BIG_DECIMAL:
case SchemaProperty.JAVA_BIG_INTEGER:
case SchemaProperty.JAVA_STRING:
case SchemaProperty.JAVA_BYTE_ARRAY:
case SchemaProperty.JAVA_GDATE:
case SchemaProperty.JAVA_GDURATION:
case SchemaProperty.JAVA_DATE:
case SchemaProperty.JAVA_QNAME:
case SchemaProperty.JAVA_LIST:
case SchemaProperty.JAVA_CALENDAR:
case SchemaProperty.JAVA_ENUM:
case SchemaProperty.JAVA_OBJECT:
emit("return null;"); break;
}
}
void printJGetArrayValue(int javaType, String type) throws IOException {
switch (javaType)
{
case SchemaProperty.XML_OBJECT:
case SchemaProperty.JAVA_ENUM:
emit(type + "[] result = new " + type + "[targetList.size()];");
emit("targetList.toArray(result);");
break;
case SchemaProperty.JAVA_BOOLEAN:
emit("boolean[] result = new boolean[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getBooleanValue();");
break;
case SchemaProperty.JAVA_FLOAT:
emit("float[] result = new float[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getFloatValue();");
break;
case SchemaProperty.JAVA_DOUBLE:
emit("double[] result = new double[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getDoubleValue();");
break;
case SchemaProperty.JAVA_BYTE:
emit("byte[] result = new byte[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getByteValue();");
break;
case SchemaProperty.JAVA_SHORT:
emit("short[] result = new short[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getShortValue();");
break;
case SchemaProperty.JAVA_INT:
emit("int[] result = new int[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getIntValue();");
break;
case SchemaProperty.JAVA_LONG:
emit("long[] result = new long[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getLongValue();");
break;
case SchemaProperty.JAVA_BIG_DECIMAL:
emit("java.math.BigDecimal[] result = new java.math.BigDecimal[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getBigDecimalValue();");
break;
case SchemaProperty.JAVA_BIG_INTEGER:
emit("java.math.BigInteger[] result = new java.math.BigInteger[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getBigIntegerValue();");
break;
case SchemaProperty.JAVA_STRING:
emit("java.lang.String[] result = new java.lang.String[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getStringValue();");
break;
case SchemaProperty.JAVA_BYTE_ARRAY:
emit("byte[][] result = new byte[targetList.size()][];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getByteArrayValue();");
break;
case SchemaProperty.JAVA_CALENDAR:
emit("java.util.Calendar[] result = new java.util.Calendar[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getCalendarValue();");
break;
case SchemaProperty.JAVA_DATE:
emit("java.util.Date[] result = new java.util.Date[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getDateValue();");
break;
case SchemaProperty.JAVA_GDATE:
emit("org.apache.xmlbeans.GDate[] result = new org.apache.xmlbeans.GDate[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getGDateValue();");
break;
case SchemaProperty.JAVA_GDURATION:
emit("org.apache.xmlbeans.GDuration[] result = new org.apache.xmlbeans.GDuration[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getGDurationValue();");
break;
case SchemaProperty.JAVA_QNAME:
emit("javax.xml.namespace.QName[] result = new javax.xml.namespace.QName[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getQNameValue();");
break;
case SchemaProperty.JAVA_LIST:
emit("java.util.List[] result = new java.util.List[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getListValue();");
break;
case SchemaProperty.JAVA_OBJECT:
emit("Object[] result = new Object[targetList.size()];");
emit("for (int i = 0, len = targetList.size() ; i < len ; i++)");
emit(" result[i] = ((org.apache.xmlbeans.SimpleValue)targetList.get(i)).getObjectValue();");
break;
}
emit("return result;");
}
void printJGetValue(int javaType, String type) throws IOException {
switch (javaType)
{
case SchemaProperty.XML_OBJECT:
emit("return target;"); break;
case SchemaProperty.JAVA_BOOLEAN:
emit("return target.getBooleanValue();"); break;
case SchemaProperty.JAVA_FLOAT:
emit("return target.getFloatValue();"); break;
case SchemaProperty.JAVA_DOUBLE:
emit("return target.getDoubleValue();"); break;
case SchemaProperty.JAVA_BYTE:
emit("return target.getByteValue();"); break;
case SchemaProperty.JAVA_SHORT:
emit("return target.getShortValue();"); break;
case SchemaProperty.JAVA_INT:
emit("return target.getIntValue();"); break;
case SchemaProperty.JAVA_LONG:
emit("return target.getLongValue();"); break;
case SchemaProperty.JAVA_BIG_DECIMAL:
emit("return target.getBigDecimalValue();"); break;
case SchemaProperty.JAVA_BIG_INTEGER:
emit("return target.getBigIntegerValue();"); break;
case SchemaProperty.JAVA_STRING:
emit("return target.getStringValue();"); break;
case SchemaProperty.JAVA_BYTE_ARRAY:
emit("return target.getByteArrayValue();"); break;
case SchemaProperty.JAVA_GDATE:
emit("return target.getGDateValue();"); break;
case SchemaProperty.JAVA_GDURATION:
emit("return target.getGDurationValue();"); break;
case SchemaProperty.JAVA_CALENDAR:
emit("return target.getCalendarValue();"); break;
case SchemaProperty.JAVA_DATE:
emit("return target.getDateValue();"); break;
case SchemaProperty.JAVA_QNAME:
emit("return target.getQNameValue();"); break;
case SchemaProperty.JAVA_LIST:
emit("return target.getListValue();"); break;
case SchemaProperty.JAVA_ENUM:
emit("return (" + type + ")target.getEnumValue();"); break;
case SchemaProperty.JAVA_OBJECT:
emit("return target.getObjectValue();"); break;
}
}
String jsetMethod(int javaType) throws IOException
{
switch (javaType)
{
case SchemaProperty.XML_OBJECT:
return "target.set";
case SchemaProperty.JAVA_BOOLEAN:
return "target.setBooleanValue";
case SchemaProperty.JAVA_FLOAT:
return "target.setFloatValue";
case SchemaProperty.JAVA_DOUBLE:
return "target.setDoubleValue";
case SchemaProperty.JAVA_BYTE:
return "target.setByteValue";
case SchemaProperty.JAVA_SHORT:
return "target.setShortValue";
case SchemaProperty.JAVA_INT:
return "target.setIntValue";
case SchemaProperty.JAVA_LONG:
return "target.setLongValue";
case SchemaProperty.JAVA_BIG_DECIMAL:
return "target.setBigDecimalValue";
case SchemaProperty.JAVA_BIG_INTEGER:
return "target.setBigIntegerValue";
case SchemaProperty.JAVA_STRING:
return "target.setStringValue";
case SchemaProperty.JAVA_BYTE_ARRAY:
return "target.setByteArrayValue";
case SchemaProperty.JAVA_GDATE:
return "target.setGDateValue";
case SchemaProperty.JAVA_GDURATION:
return "target.setGDurationValue";
case SchemaProperty.JAVA_CALENDAR:
return "target.setCalendarValue";
case SchemaProperty.JAVA_DATE:
return "target.setDateValue";
case SchemaProperty.JAVA_QNAME:
return "target.setQNameValue";
case SchemaProperty.JAVA_LIST:
return "target.setListValue";
case SchemaProperty.JAVA_ENUM:
return "target.setEnumValue";
case SchemaProperty.JAVA_OBJECT:
return "target.setObjectValue";
default:
throw new IllegalStateException();
}
}
String getIdentifier(Map qNameMap, QName qName) {
return ((String[])qNameMap.get(qName))[0];
}
String getSetIdentifier(Map qNameMap, QName qName) {
String[] identifiers = (String[])qNameMap.get(qName);
return identifiers[1] == null ? identifiers[0] : identifiers[1];
}
Map printStaticFields(SchemaProperty[] properties) throws IOException {
final Map results = new HashMap();
emit("");
for (int i = 0; i < properties.length; i++)
{
final String[] identifiers = new String[2];
final SchemaProperty prop = properties[i];
final QName name = prop.getName();
results.put(name, identifiers);
final String javaName = prop.getJavaPropertyName();
identifiers[0] = (javaName + "$" + (i * 2)).toUpperCase();
final String uriString = "\"" + name.getNamespaceURI() + "\"";
emit("private static final javax.xml.namespace.QName " + identifiers[0] +
" = " );
indent();
emit("new javax.xml.namespace.QName(" +
uriString + ", \"" + name.getLocalPart() + "\");");
outdent();
if (properties[i].acceptedNames() != null)
{
final QName[] qnames = properties[i].acceptedNames();
if (qnames.length > 1)
{
identifiers[1] = (javaName + "$" + (i*2+1)).toUpperCase();
emit("private static final org.apache.xmlbeans.QNameSet " + identifiers[1] +
" = org.apache.xmlbeans.QNameSet.forArray( new javax.xml.namespace.QName[] { " );
indent();
for (int j = 0 ; j < qnames.length ; j++)
{
emit("new javax.xml.namespace.QName(\"" + qnames[j].getNamespaceURI() +
"\", \"" + qnames[j].getLocalPart() + "\"),");
}
outdent();
emit("});");
}
}
}
emit("");
return results;
}
void emitImplementationPreamble() throws IOException
{
emit("synchronized (monitor())");
emit("{");
indent();
emit("check_orphaned();");
}
void emitImplementationPostamble() throws IOException
{
outdent();
emit("}");
}
void emitAddTarget(String identifier, boolean isAttr, boolean declareTarget, String xtype)
throws IOException
{
if (declareTarget)
emit(xtype + " target;");
if (isAttr)
emit("target = (" + xtype + ")get_store().add_attribute_user(" + identifier + ");");
else
emit("target = (" + xtype + ")get_store().add_element_user(" + identifier + ");");
}
private static final int NOTHING = 1;
private static final int ADD_NEW_VALUE = 3;
private static final int THROW_EXCEPTION = 4;
void emitGetTarget(String setIdentifier,
String identifier,
boolean isAttr,
String index,
int nullBehaviour,
String xtype)
throws IOException
{
assert setIdentifier != null && identifier != null;
emit(xtype + " target = null;");
if (isAttr)
emit("target = (" + xtype + ")get_store().find_attribute_user(" + identifier + ");");
else
emit("target = (" + xtype + ")get_store().find_element_user(" + setIdentifier + ", " + index + ");");
if (nullBehaviour == NOTHING)
return;
emit("if (target == null)");
startBlock();
switch (nullBehaviour)
{
case ADD_NEW_VALUE:
emitAddTarget(identifier, isAttr, false, xtype);
break;
case THROW_EXCEPTION:
emit("throw new IndexOutOfBoundsException();");
break;
case NOTHING:
break;
default:
assert false : "Bad behaviour type: " + nullBehaviour;
}
endBlock();
}
void printGetterImpls(
SchemaProperty prop, QName qName, boolean isAttr, String propertyName,
int javaType, String type, String xtype, boolean nillable,
boolean optional, boolean several, boolean singleton,
boolean isunion,
String identifier, String setIdentifier )
throws IOException
{
String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element");
boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);
String jtargetType = (isunion || !xmltype) ? "org.apache.xmlbeans.SimpleValue" : xtype;
if (singleton)
{
// Value getProp()
printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc);
emit("public " + type + " get" + propertyName + "()");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, jtargetType);
if (isAttr && (prop.hasDefault() == SchemaProperty.CONSISTENTLY ||
prop.hasFixed() == SchemaProperty.CONSISTENTLY))
{
emit("if (target == null)");
startBlock();
makeAttributeDefaultValue(jtargetType, prop, identifier);
endBlock();
}
emit("if (target == null)");
startBlock();
makeMissingValue(javaType);
endBlock();
printJGetValue(javaType, type);
emitImplementationPostamble();
endBlock();
if (!xmltype)
{
// Value xgetProp()
printJavaDoc((several ? "Gets (as xml) first " : "Gets (as xml) the ") + propdesc);
emit("public " + xtype + " xget" + propertyName + "()");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, xtype);
if (isAttr && (prop.hasDefault() == SchemaProperty.CONSISTENTLY ||
prop.hasFixed() == SchemaProperty.CONSISTENTLY))
{
emit("if (target == null)");
startBlock();
makeAttributeDefaultValue(xtype, prop, identifier);
endBlock();
}
emit("return target;");
emitImplementationPostamble();
endBlock();
}
if (nillable)
{
// boolean isNilProp()
printJavaDoc((several ? "Tests for nil first " : "Tests for nil ") + propdesc);
emit("public boolean isNil" + propertyName + "()");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, xtype);
emit("if (target == null) return false;");
emit("return target.isNil();");
emitImplementationPostamble();
endBlock();
}
}
if (optional)
{
// boolean isSetProp()
printJavaDoc((several ? "True if has at least one " : "True if has ") + propdesc);
emit("public boolean isSet" + propertyName + "()");
startBlock();
emitImplementationPreamble();
if (isAttr)
emit("return get_store().find_attribute_user(" + identifier +") != null;");
else
emit("return get_store().count_elements(" + setIdentifier + ") != 0;");
emitImplementationPostamble();
endBlock();
}
if (several)
{
String arrayName = propertyName + "Array";
// Value[] getProp()
printJavaDoc("Gets array of all " + propdesc + "s");
emit("public " + type + "[] get" + arrayName + "()");
startBlock();
emitImplementationPreamble();
emit("java.util.List targetList = new java.util.ArrayList();");
emit("get_store().find_all_element_users(" + setIdentifier + ", targetList);");
printJGetArrayValue(javaType, type);
emitImplementationPostamble();
endBlock();
// Value getProp(int i)
printJavaDoc("Gets ith " + propdesc);
emit("public " + type + " get" + arrayName + "(int i)");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType);
printJGetValue(javaType, type);
emitImplementationPostamble();
endBlock();
if (!xmltype)
{
// Value[] xgetProp()
printJavaDoc("Gets (as xml) array of all " + propdesc + "s");
emit("public " + xtype + "[] xget" + arrayName + "()");
startBlock();
emitImplementationPreamble();
emit("java.util.List targetList = new java.util.ArrayList();");
emit("get_store().find_all_element_users(" + setIdentifier + ", targetList);");
emit(xtype + "[] result = new " + xtype + "[targetList.size()];");
emit("targetList.toArray(result);");
emit("return result;");
emitImplementationPostamble();
endBlock();
// Value xgetProp(int i)
printJavaDoc("Gets (as xml) ith " + propdesc);
emit("public " + xtype + " xget" + arrayName + "(int i)");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
emit("return (" + xtype + ")target;");
emitImplementationPostamble();
endBlock();
}
if (nillable)
{
// boolean isNil(int i);
printJavaDoc("Tests for nil ith " + propdesc);
emit("public boolean isNil" + arrayName + "(int i)");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
emit("return target.isNil();");
emitImplementationPostamble();
endBlock();
}
// int countProp();
printJavaDoc("Returns number of " + propdesc);
emit("public int sizeOf" + arrayName + "()");
startBlock();
emitImplementationPreamble();
emit("return get_store().count_elements(" + setIdentifier +");");
emitImplementationPostamble();
endBlock();
}
}
void printSetterImpls(QName qName, boolean isAttr,
String propertyName, int javaType, String type, String xtype,
boolean nillable, boolean optional,
boolean several, boolean singleton,
boolean isunion,
String identifier, String setIdentifier) throws IOException
{
String safeVarName = NameUtil.nonJavaKeyword(NameUtil.lowerCamelCase(propertyName));
if (safeVarName.equals("i"))
safeVarName = "iValue";
else if (safeVarName.equals("target"))
safeVarName = "targetValue";
boolean xmltype = (javaType == SchemaProperty.XML_OBJECT);
boolean isobj = (javaType == SchemaProperty.JAVA_OBJECT);
boolean isSubstGroup = identifier != setIdentifier;
String jSet = jsetMethod(javaType);
String jtargetType = (isunion || !xmltype) ? "org.apache.xmlbeans.SimpleValue" : xtype;
String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element");
if (singleton)
{
// void setProp(Value v);
printJavaDoc((several ? "Sets first " : "Sets the ") + propdesc);
emit("public void set" + propertyName + "(" + type + " " + safeVarName + ")");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, jtargetType);
emit(jSet + "(" + safeVarName + ");");
emitImplementationPostamble();
endBlock();
if (!xmltype)
{
// void xsetProp(Value v)
printJavaDoc((several ? "Sets (as xml) first " : "Sets (as xml) the ") + propdesc);
emit("public void xset" + propertyName + "(" + xtype + " " + safeVarName + ")");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype);
emit("target.set(" + safeVarName + ");");
emitImplementationPostamble();
endBlock();
}
if (xmltype && !several)
{
// Value addNewProp()
printJavaDoc("Appends and returns a new empty " + propdesc);
emit("public " + xtype + " addNew" + propertyName + "()");
startBlock();
emitImplementationPreamble();
emitAddTarget(identifier, isAttr, true, xtype);
emit("return target;");
emitImplementationPostamble();
endBlock();
}
if (nillable)
{
printJavaDoc((several ? "Nils the first " : "Nils the ") + propdesc);
emit("public void setNil" + propertyName + "()");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype);
emit("target.setNil();");
emitImplementationPostamble();
endBlock();
}
}
if (optional)
{
printJavaDoc((several ? "Removes first " : "Unsets the ") + propdesc);
emit("public void unset" + propertyName + "()");
startBlock();
emitImplementationPreamble();
if (isAttr)
emit("get_store().remove_attribute(" + identifier + ");");
else
emit("get_store().remove_element(" + setIdentifier + ", 0);");
emitImplementationPostamble();
endBlock();
}
if (several)
{
String arrayName = propertyName + "Array";
// JSET_INDEX
printJavaDoc("Sets array of all " + propdesc);
emit("public void set" + arrayName + "(" + type + "[] " + safeVarName + "Array)");
startBlock();
emitImplementationPreamble();
if (isobj)
{
if (!isSubstGroup)
emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");" );
else
emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");" );
}
else
{
if (!isSubstGroup)
emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");" );
else
emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");" );
}
emitImplementationPostamble();
endBlock();
printJavaDoc("Sets ith " + propdesc);
emit("public void set" + arrayName + "(int i, " + type + " " + safeVarName + ")");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType);
emit(jSet + "(" + safeVarName + ");");
emitImplementationPostamble();
endBlock();
if (!xmltype)
{
printJavaDoc("Sets (as xml) array of all " + propdesc);
emit("public void xset" + arrayName + "(" + xtype + "[]" + safeVarName + "Array)");
startBlock();
emitImplementationPreamble();
emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");" );
emitImplementationPostamble();
endBlock();
printJavaDoc("Sets (as xml) ith " + propdesc);
emit("public void xset" + arrayName + "(int i, " + xtype + " " + safeVarName + ")");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
emit("target.set(" + safeVarName + ");");
emitImplementationPostamble();
endBlock();
}
if (nillable)
{
printJavaDoc("Nils the ith " + propdesc);
emit("public void setNil" + arrayName + "(int i)");
startBlock();
emitImplementationPreamble();
emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype);
emit("target.setNil();");
emitImplementationPostamble();
endBlock();
}
if (!xmltype)
{
printJavaDoc("Inserts the value as the ith " + propdesc);
emit("public void insert" + propertyName + "(int i, " + type + " " + safeVarName + ")");
startBlock();
emitImplementationPreamble();
emit(jtargetType + " target = ");
indent();
if (!isSubstGroup)
emit("(" + jtargetType + ")get_store().insert_element_user(" + identifier + ", i);");
else // This is a subst group case
emit ("(" + jtargetType +")get_store().insert_element_user(" + setIdentifier + ", " +
identifier + ", i);");
outdent();
emit(jSet + "(" + safeVarName + ");");
emitImplementationPostamble();
endBlock();
printJavaDoc("Appends the value as the last " + propdesc);
emit("public void add" + propertyName + "(" + type + " " + safeVarName + ")");
startBlock();
emitImplementationPreamble();
emitAddTarget(identifier, isAttr, true, jtargetType);
emit(jSet + "(" + safeVarName + ");");
emitImplementationPostamble();
endBlock();
}
if (xmltype)
{
printJavaDoc("Inserts and returns a new empty value (as xml) as the ith " + propdesc);
emit("public " + xtype + " insertNew" + propertyName + "(int i)");
startBlock();
emitImplementationPreamble();
emit(xtype + " target;");
emit("target = (" + xtype + ")get_store().insert_element_user(" + identifier + ", i);");
emit("return target;");
emitImplementationPostamble();
endBlock();
printJavaDoc("Appends and returns a new empty value (as xml) as the last " + propdesc);
emit("public " + xtype + " addNew" + propertyName + "()");
startBlock();
emitImplementationPreamble();
emitAddTarget(identifier, isAttr, true, xtype);
emit("return target;");
emitImplementationPostamble();
endBlock();
}
printJavaDoc("Removes the ith " + propdesc);
emit("public void remove" + propertyName + "(int i)");
startBlock();
emitImplementationPreamble();
emit("get_store().remove_element(" + setIdentifier + ", i);");
emitImplementationPostamble();
endBlock();
}
}
static void getTypeName(Class c, StringBuffer sb) {
int arrayCount = 0;
while (c.isArray()) {
c = c.getComponentType();
arrayCount++;
}
sb.append(c.getName());
for (int i = 0 ; i < arrayCount; i++)
sb.append("[]");
}
void printInnerTypeImpl(
SchemaType sType, SchemaTypeSystem system, boolean isInner ) throws IOException
{
String shortName = sType.getShortJavaImplName();
printInnerTypeJavaDoc(sType);
startClass(sType, isInner);
printConstructor(sType, shortName);
if (!sType.isSimpleType())
{
SchemaProperty[] properties;
if (sType.getContentType() == SchemaType.SIMPLE_CONTENT)
{
// simple content types impls derive directly from "holder" impls
// in order to handle the case (for ints or string enums e.g.) where
// there is a simple type restriction. So property getters need to
// be implemented "from scratch" for each derived complex type
properties = sType.getProperties();
}
else
{
// complex content type implementations derive from base type impls
// so derived property impls can be reused
properties = sType.getDerivedProperties();
}
Map qNameMap = printStaticFields(properties);
for (int i = 0; i < properties.length; i++)
{
SchemaProperty prop = properties[i];
QName name = prop.getName();
String xmlType = xmlTypeForProperty( prop );
printGetterImpls(
prop,
name,
prop.isAttribute(),
prop.getJavaPropertyName(),
prop.getJavaTypeCode(),
javaTypeForProperty(prop),
xmlType,
prop.hasNillable() != SchemaProperty.NEVER,
prop.extendsJavaOption(),
prop.extendsJavaArray(),
prop.extendsJavaSingleton(),
xmlTypeForPropertyIsUnion(prop),
getIdentifier(qNameMap, name),
getSetIdentifier(qNameMap, name)
);
if (!prop.isReadOnly())
{
printSetterImpls(
name,
prop.isAttribute(),
prop.getJavaPropertyName(),
prop.getJavaTypeCode(),
javaTypeForProperty(prop),
xmlType,
prop.hasNillable() != SchemaProperty.NEVER,
prop.extendsJavaOption(),
prop.extendsJavaArray(),
prop.extendsJavaSingleton(),
xmlTypeForPropertyIsUnion(prop),
getIdentifier(qNameMap, name),
getSetIdentifier(qNameMap, name)
);
}
}
}
printNestedTypeImpls(sType, system);
endBlock();
}
void printNestedTypeImpls(SchemaType sType, SchemaTypeSystem system) throws IOException
{
SchemaType[] anonTypes = sType.getAnonymousTypes();
for (int i = 0; i < anonTypes.length; i++)
{
if (anonTypes[i].isSkippedAnonymousType())
printNestedTypeImpls(anonTypes[i], system);
else
printInnerTypeImpl(anonTypes[i], system, true);
}
}
}