All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.xmlbeans.impl.schema.SchemaTypeCodePrinter Maven / Gradle / Ivy

There is a newer version: 5.2.1
Show newest version
/*   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.xmlbeans.impl.schema;

import org.apache.xmlbeans.*;
import org.apache.xmlbeans.XmlOptions.BeanMethod;
import org.apache.xmlbeans.impl.common.NameUtil;
import org.apache.xmlbeans.impl.repackage.Repackager;

import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.*;

/**
 * Prints the java code for a single schema type
 */
public final class SchemaTypeCodePrinter implements SchemaCodePrinter {

    static final String INDEX_CLASSNAME = "TypeSystemHolder";
    private static final String MAX_SPACES = "                                        ";
    private static final int INDENT_INCREMENT = 4;

    private Writer _writer;
    private int _indent;
    private XmlOptions opt;

    public SchemaTypeCodePrinter() {
        _indent = 0;
    }

    void indent() {
        _indent += INDENT_INCREMENT;
    }

    void outdent() {
        _indent -= INDENT_INCREMENT;
    }

    void emit(String s, BeanMethod method) throws IOException {
        Set partMet = opt == null ? null : opt.getCompilePartialMethod();
        if ((partMet == null || partMet.contains(method))) {
            emit(s);
        }
    }

    void emit(String s) throws IOException {
        if (!s.trim().isEmpty()) {
            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));
        }
        try {
            _writer.write(s);
        } catch (CharacterCodingException cce) {
            _writer.write(makeSafe(s));
        }
        _writer.write(System.lineSeparator());
    }

    private static String makeSafe(String s) {
        Charset charset = Charset.forName(System.getProperty("file.encoding"));
        CharsetEncoder cEncoder = charset.newEncoder();
        StringBuilder result = new StringBuilder();
        int i;
        for (i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (!cEncoder.canEncode(c)) {
                break;
            }
        }
        for (; i < s.length(); i++) {
            char c = s.charAt(i);
            if (cEncoder.canEncode(c)) {
                result.append(c);
            } else {
                String hexValue = Integer.toHexString(c);
                switch (hexValue.length()) {
                    case 1:
                        result.append("\\u000").append(hexValue);
                        break;
                    case 2:
                        result.append("\\u00").append(hexValue);
                        break;
                    case 3:
                        result.append("\\u0").append(hexValue);
                        break;
                    case 4:
                        result.append("\\u").append(hexValue);
                        break;
                    default:
                        throw new IllegalStateException();
                }
            }
        }
        return result.toString();
    }

    @Override
    public void printType(Writer writer, SchemaType sType, XmlOptions opt) throws IOException {
        this.opt = opt;
        _writer = writer;
        printTopComment(sType);
        printPackage(sType, true);
        emit("");
        emit("import "+ElementFactory.class.getName()+";");
        emit("import " + AbstractDocumentFactory.class.getName() + ";");
        emit("import " + DocumentFactory.class.getName() + ";");
        emit("import " + SimpleTypeFactory.class.getName() + ";");
        emit("");
        printInnerType(sType, sType.getTypeSystem());
        _writer.flush();
    }

    @Override
    public void printTypeImpl(Writer writer, SchemaType sType, XmlOptions opt) throws IOException {
        this.opt = opt;
        _writer = writer;
        printTopComment(sType);
        printPackage(sType, false);
        emit("");
        emit("import javax.xml.namespace.QName;");
        emit("import org.apache.xmlbeans.QNameSet;");
        emit("");
        printInnerTypeImpl(sType, sType.getTypeSystem(), 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) {
        if (qname == null) {
            return "";
        }
        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 (opt.isCompileAnnotationAsJavadoc() && sType.getDocumentation() != null && sType.getDocumentation().length() > 0){
            emit(" *");
            printJavaDocBody(sType.getDocumentation());
            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 " + getFullJavaName(sType) + ".");
                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 (SchemaType member : members) {
                    emit(" *     " + member.getFullJavaName());
                }
                break;
        }
        emit(" */");
    }

    private String getFullJavaName(SchemaType sType) {

        SchemaTypeImpl sTypeI = (SchemaTypeImpl) sType;
        String ret = sTypeI.getFullJavaName();

        while (sTypeI != null && sTypeI.isRedefinition()) {
            ret = sTypeI.getFullJavaName();
            sTypeI = (SchemaTypeImpl) sTypeI.getBaseType();
        }
        return ret;
    }

    private String getUserTypeStaticHandlerMethod(boolean encode, SchemaTypeImpl stype) {
        String unqualifiedName = stype.getName().getLocalPart();
        if (unqualifiedName.length() < 2) {
            unqualifiedName = unqualifiedName.toUpperCase(Locale.ROOT);
        } else {
            unqualifiedName = unqualifiedName.substring(0, 1).toUpperCase(Locale.ROOT) + unqualifiedName.substring(1);
        }

        if (encode) {
            return stype.getUserTypeHandlerName() + ".encode" + unqualifiedName;
        } else {
            return stype.getUserTypeHandlerName() + ".decode" + unqualifiedName;
        }
    }


    public static String indexClassForSystem(SchemaTypeSystem system) {
        String name = system.getName();
        return name + "." + INDEX_CLASSNAME;
    }

    void printStaticTypeDeclaration(SchemaType sType, SchemaTypeSystem system) throws IOException {
        // Only need full factories for top-level types
        Class factoryClass;
        if (sType.isAnonymousType() && !sType.isDocumentType() && !sType.isAttributeType()) {
            factoryClass = ElementFactory.class;
        } else if (sType.isSimpleType()) {
            factoryClass = SimpleTypeFactory.class;
        } else if (sType.isAbstract()) {
            factoryClass = AbstractDocumentFactory.class;
        } else {
            factoryClass = DocumentFactory.class;
        }

        String factoryName = factoryClass.getSimpleName();

        String fullName = sType.getFullJavaName().replace('$', '.');
        String sysName = sType.getTypeSystem().getName();


        emit(factoryName + "<" + fullName + "> Factory = new " + factoryName +
             "<>(" + sysName + ".TypeSystemHolder.typeSystem, \"" + ((SchemaTypeSystemImpl) system).handleForType(sType) + "\");"
         );
        emit("org.apache.xmlbeans.SchemaType type = Factory.getType();");
        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 {
            if (sType.getContentType() == SchemaType.SIMPLE_CONTENT && sType.hasStringEnumValues()) {
                printStringEnumeration(sType);
            }

            SchemaProperty[] props = getDerivedProperties(sType);

            for (SchemaProperty prop : props) {
                printPropertyGetters(prop);

                if (!prop.isReadOnly()) {
                    printPropertySetters(prop);
                }
            }

        }

        printNestedInnerTypes(sType, system);

        endBlock();
    }

    void printNestedInnerTypes(SchemaType sType, SchemaTypeSystem system) throws IOException {
        boolean redefinition = sType.getName() != null &&
                               sType.getName().equals(sType.getBaseType().getName());
        while (sType != null) {
            SchemaType[] anonTypes = sType.getAnonymousTypes();
            for (SchemaType anonType : anonTypes) {
                if (anonType.isSkippedAnonymousType()) {
                    printNestedInnerTypes(anonType, system);
                } else {
                    printInnerType(anonType, system);
                }
            }
            // For redefinition other than by extension for complex types, go ahead and print
            // the anonymous types in the base
            if (!redefinition ||
                (sType.getDerivationType() != SchemaType.DT_EXTENSION && !sType.isSimpleType())) {
                break;
            }
            sType = sType.getBaseType();
        }
    }

    void printTopComment(SchemaType sType) throws IOException {
        // if(sType.getDocumentation() != null && sType.getDocumentation().length() > 0){
        //     printJavaDocParagraph(sType.getDocumentation());
        // }
        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());

        emit("public interface " + shortName + " extends " + baseInterface + getExtensionInterfaces(sType) + " {");
        indent();
        emitSpecializedAccessors(sType);
    }

    private static String getExtensionInterfaces(SchemaType sType) {
        SchemaTypeImpl sImpl = getImpl(sType);
        if (sImpl == null) {
            return "";
        }

        StringBuilder sb = new StringBuilder();

        InterfaceExtension[] exts = sImpl.getInterfaceExtensions();
        if (exts != null) {
            for (InterfaceExtension ext : exts) {
                sb.append(", ").append(ext.getInterface());
            }
        }

        return sb.toString();
    }

    private static SchemaTypeImpl getImpl(SchemaType sType) {
        if (sType instanceof SchemaTypeImpl) {
            return (SchemaTypeImpl) sType;
        } else {
            return null;
        }
    }

    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) {
                switch (bits) {
                    case SchemaType.SIZE_BIG_INTEGER:
                        emit("java.math.BigInteger getBigIntegerValue();", BeanMethod.GET);
                        emit("void setBigIntegerValue(java.math.BigInteger bi);", BeanMethod.SET);
                        break;
                    case SchemaType.SIZE_LONG:
                        emit("long getLongValue();", BeanMethod.GET);
                        emit("void setLongValue(long l);", BeanMethod.SET);
                        break;
                    case SchemaType.SIZE_INT:
                        emit("int getIntValue();", BeanMethod.GET);
                        emit("void setIntValue(int i);", BeanMethod.SET);
                        break;
                    case SchemaType.SIZE_SHORT:
                        emit("short getShortValue();", BeanMethod.GET);
                        emit("void setShortValue(short s);", BeanMethod.SET);
                        break;
                    case SchemaType.SIZE_BYTE:
                        emit("byte getByteValue();", BeanMethod.GET);
                        emit("void setByteValue(byte b);", BeanMethod.SET);
                        break;
                }
            }
        }

        if (sType.getSimpleVariety() == SchemaType.UNION) {
            emit("java.lang.Object getObjectValue();", BeanMethod.GET);
            emit("void setObjectValue(java.lang.Object val);", BeanMethod.SET);
            emit("org.apache.xmlbeans.SchemaType instanceType();", BeanMethod.INSTANCE_TYPE);
            SchemaType ctype = sType.getUnionCommonBaseType();
            if (ctype != null && ctype.getSimpleVariety() != SchemaType.UNION) {
                emitSpecializedAccessors(ctype);
            }
        }

        if (sType.getSimpleVariety() == SchemaType.LIST) {
            emit("java.util.List getListValue();", BeanMethod.GET_LIST);
            emit("java.util.List xgetListValue();", BeanMethod.XGET_LIST);
            emit("void setListValue(java.util.List list);", BeanMethod.SET_LIST);
        }
    }

    void startBlock() {
        // emit("{");
        indent();
    }

    void endBlock() throws IOException {
        outdent();
        emit("}");
    }

    void printJavaDoc(String sentence, BeanMethod method) throws IOException {
        Set partMet = opt == null ? null : opt.getCompilePartialMethod();
        if ((partMet == null || partMet.contains(method))) {
            printJavaDoc(sentence);
        }
    }

    void printJavaDoc(String sentence) throws IOException {
        emit("");
        emit("/**");
        emit(" * " + sentence);
        emit(" */");
    }

    void printJavaDocParagraph(String s) throws IOException{
        emit("");
        emit("/**");
        printJavaDocBody(s);
        emit(" */");
    }

    void printJavaDocBody(String doc) throws IOException{
        // add some poor mans code injection protection
        // this is not protecting against annotation based RCEs like CVE-2018-16621
        String docClean = doc.trim()
            .replace("\t", "")
            .replace("*/", "* /");

        for (String s : docClean.split("[\\n\\r]+")) {
            emit(" * " + s);
        }
    }

    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;
        }
        StringBuilder sb = new StringBuilder();
        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 = sType.getBaseEnumType();
        String baseEnumClass = baseEnumType.getFullJavaName();
        boolean hasBase = hasBase(sType);

        if (!hasBase) {
            emit("");
            emit("org.apache.xmlbeans.StringEnumAbstractBase getEnumValue();", BeanMethod.GET);
            emit("void setEnumValue(org.apache.xmlbeans.StringEnumAbstractBase e);", BeanMethod.SET);
        }

        emit("");
        SchemaStringEnumEntry[] entries = sType.getStringEnumEntries();
        HashSet seenValues = new HashSet<>();
        HashSet repeatValues = new HashSet<>();
        for (SchemaStringEnumEntry entry : entries) {
            String enumValue = entry.getString();
            if (seenValues.contains(enumValue)) {
                repeatValues.add(enumValue);
                continue;
            } else {
                seenValues.add(enumValue);
            }
            String constName = entry.getEnumName();
            if (hasBase) {
                emit(baseEnumClass + ".Enum " + constName + " = " + baseEnumClass + "." + constName + ";");
            } else {
                emit("Enum " + constName + " = Enum.forString(\"" + javaStringEscape(enumValue) + "\");");
            }
        }
        emit("");
        for (SchemaStringEnumEntry entry : entries) {
            if (repeatValues.contains(entry.getString())) {
                continue;
            }
            String constName = "INT_" + entry.getEnumName();
            if (hasBase) {
                emit("int " + constName + " = " + baseEnumClass + "." + constName + ";");
            } else {
                emit("int " + constName + " = Enum." + constName + ";");
            }
        }
        if (!hasBase) {
            emit("");
            emit("/**");
            emit(" * Enumeration value class for " + baseEnumClass + ".");
            emit(" * These enum values can be used as follows:");
            emit(" * 
");
            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(" * 
"); 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("final class Enum extends org.apache.xmlbeans.StringEnumAbstractBase {"); 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(""); 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(""); emit("private Enum(java.lang.String s, int i) {"); emit(" super(s, i);"); emit("}"); emit(""); for (SchemaStringEnumEntry entry : entries) { String constName = "INT_" + entry.getEnumName(); int intValue = entry.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(new Enum[] {"); indent(); for (SchemaStringEnumEntry entry : entries) { String enumValue = entry.getString(); String constName = "INT_" + entry.getEnumName(); emit("new Enum(\"" + javaStringEscape(enumValue) + "\", " + constName + "),"); } outdent(); emit("});"); emit("private static final long serialVersionUID = 1L;"); emit("private java.lang.Object readResolve() {"); emit(" return forInt(intValue());"); emit("}"); outdent(); emit("}"); } } private boolean hasBase(SchemaType sType) { boolean hasBase; SchemaType baseEnumType = sType.getBaseEnumType(); if (baseEnumType.isAnonymousType() && baseEnumType.isSkippedAnonymousType()) { if (sType.getContentBasedOnType() != null) { hasBase = sType.getContentBasedOnType().getBaseType() != baseEnumType; } else { hasBase = sType.getBaseType() != baseEnumType; } } else { hasBase = baseEnumType != sType; } return hasBase; } 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); } static boolean isJavaPrimitive(int javaType) { return (javaType >= SchemaProperty.JAVA_FIRST_PRIMITIVE && (javaType <= SchemaProperty.JAVA_LAST_PRIMITIVE)); } /** * Returns the wrapped type for a java primitive. */ static String javaWrappedType(int javaType) { switch (javaType) { case SchemaProperty.JAVA_BOOLEAN: return "java.lang.Boolean"; case SchemaProperty.JAVA_FLOAT: return "java.lang.Float"; case SchemaProperty.JAVA_DOUBLE: return "java.lang.Double"; case SchemaProperty.JAVA_BYTE: return "java.lang.Byte"; case SchemaProperty.JAVA_SHORT: return "java.lang.Short"; case SchemaProperty.JAVA_INT: return "java.lang.Integer"; case SchemaProperty.JAVA_LONG: return "java.lang.Long"; // anything else is not a java primitive default: assert false; throw new IllegalStateException(); } } 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('$', '.'); } if (sProp.getJavaTypeCode() == SchemaProperty.JAVA_USER) { return ((SchemaTypeImpl) sProp.getType()).getUserTypeName(); } 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(); if (sType.getSimpleVariety() == SchemaType.UNION) { sType = sType.getUnionCommonBaseType(); } assert sType.getBaseEnumType() != null; if (hasBase(sType)) { return findJavaType(sType.getBaseEnumType()).replace('$', '.') + ".Enum"; } else { return findJavaType(sType).replace('$', '.') + ".Enum"; } case SchemaProperty.JAVA_OBJECT: return "java.lang.Object"; default: assert (false); throw new IllegalStateException(); } } void printPropertyGetters(SchemaProperty prop) throws IOException { String propertyName = prop.getJavaPropertyName(); int javaType = prop.getJavaTypeCode(); String type = javaTypeForProperty(prop); String xtype = xmlTypeForProperty(prop); boolean nillable = prop.hasNillable() != SchemaProperty.NEVER; boolean several = prop.extendsJavaArray(); String propertyDocumentation = prop.getDocumentation(); String propdesc = "\"" + prop.getName().getLocalPart() + "\"" + (prop.isAttribute() ? " attribute" : " element"); boolean xmltype = (javaType == SchemaProperty.XML_OBJECT); if (prop.extendsJavaSingleton()) { if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){ printJavaDocParagraph(propertyDocumentation); }else { printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc, BeanMethod.GET); } emit(type + " get" + propertyName + "();", BeanMethod.GET); if (!xmltype) { printJavaDoc((several ? "Gets (as xml) first " : "Gets (as xml) the ") + propdesc, BeanMethod.XGET); emit(xtype + " xget" + propertyName + "();", BeanMethod.XGET); } if (nillable) { printJavaDoc((several ? "Tests for nil first " : "Tests for nil ") + propdesc, BeanMethod.IS_NIL); emit("boolean isNil" + propertyName + "();", BeanMethod.IS_NIL); } } if (prop.extendsJavaOption()) { if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){ printJavaDocParagraph(propertyDocumentation); }else { printJavaDoc((several ? "True if has at least one " : "True if has ") + propdesc, BeanMethod.IS_SET); } emit("boolean isSet" + propertyName + "();", BeanMethod.IS_SET); } if (several) { if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){ printJavaDocParagraph(propertyDocumentation); } String arrayName = propertyName + "Array"; String wrappedType = type; if (isJavaPrimitive(javaType)) { wrappedType = javaWrappedType(javaType); } if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){ printJavaDocParagraph(propertyDocumentation); }else{ printJavaDoc("Gets a List of " + propdesc + "s", BeanMethod.GET_LIST); } emit("java.util.List<" + wrappedType + "> get" + propertyName + "List();", BeanMethod.GET_LIST); if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){ printJavaDocParagraph(propertyDocumentation); }else{ printJavaDoc("Gets array of all " + propdesc + "s", BeanMethod.GET_ARRAY); } emit(type + "[] get" + arrayName + "();", BeanMethod.GET_ARRAY); printJavaDoc("Gets ith " + propdesc, BeanMethod.GET_IDX); emit(type + " get" + arrayName + "(int i);", BeanMethod.GET_IDX); if (!xmltype) { printJavaDoc("Gets (as xml) a List of " + propdesc + "s", BeanMethod.XGET_LIST); emit("java.util.List<" + xtype + "> xget" + propertyName + "List();", BeanMethod.XGET_LIST); printJavaDoc("Gets (as xml) array of all " + propdesc + "s", BeanMethod.XGET_ARRAY); emit(xtype + "[] xget" + arrayName + "();", BeanMethod.XGET_ARRAY); printJavaDoc("Gets (as xml) ith " + propdesc, BeanMethod.XGET_IDX); emit(xtype + " xget" + arrayName + "(int i);", BeanMethod.XGET_IDX); } if (nillable) { printJavaDoc("Tests for nil ith " + propdesc, BeanMethod.IS_NIL_IDX); emit("boolean isNil" + arrayName + "(int i);", BeanMethod.IS_NIL_IDX); } printJavaDoc("Returns number of " + propdesc, BeanMethod.SIZE_OF_ARRAY); emit("int sizeOf" + arrayName + "();", BeanMethod.SIZE_OF_ARRAY); } } void printPropertySetters(SchemaProperty prop) throws IOException { QName qName = prop.getName(); boolean isAttr = prop.isAttribute(); String propertyName = prop.getJavaPropertyName(); int javaType = prop.getJavaTypeCode(); String type = javaTypeForProperty(prop); String xtype = xmlTypeForProperty(prop); boolean nillable = prop.hasNillable() != SchemaProperty.NEVER; boolean optional = prop.extendsJavaOption(); boolean several = prop.extendsJavaArray(); boolean singleton = prop.extendsJavaSingleton(); String propertyDocumentation = prop.getDocumentation(); 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) { if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0) { printJavaDocParagraph(propertyDocumentation); } else { printJavaDoc((several ? "Sets first " : "Sets the ") + propdesc, BeanMethod.SET); } emit("void set" + propertyName + "(" + type + " " + safeVarName + ");", BeanMethod.SET); if (!xmltype) { printJavaDoc((several ? "Sets (as xml) first " : "Sets (as xml) the ") + propdesc, BeanMethod.XSET); emit("void xset" + propertyName + "(" + xtype + " " + safeVarName + ");", BeanMethod.XSET); } if (xmltype && !several) { printJavaDoc("Appends and returns a new empty " + propdesc, BeanMethod.ADD_NEW); emit(xtype + " addNew" + propertyName + "();", BeanMethod.ADD_NEW); } if (nillable) { printJavaDoc((several ? "Nils the first " : "Nils the ") + propdesc, BeanMethod.SET_NIL); emit("void setNil" + propertyName + "();", BeanMethod.SET_NIL); } } if (optional) { if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0) { printJavaDocParagraph(propertyDocumentation); } else { printJavaDoc((several ? "Removes first " : "Unsets the ") + propdesc, BeanMethod.UNSET); } emit("void unset" + propertyName + "();", BeanMethod.UNSET); } if (several) { String arrayName = propertyName + "Array"; if(opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0) { printJavaDocParagraph(propertyDocumentation); } else { printJavaDoc("Sets array of all " + propdesc, BeanMethod.SET_ARRAY); } emit("void set" + arrayName + "(" + type + "[] " + safeVarName + "Array);", BeanMethod.SET_ARRAY); if (opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0) { printJavaDocParagraph(propertyDocumentation); } else { printJavaDoc("Sets ith " + propdesc, BeanMethod.SET_IDX); } emit("void set" + arrayName + "(int i, " + type + " " + safeVarName + ");", BeanMethod.SET_IDX); if (!xmltype) { printJavaDoc("Sets (as xml) array of all " + propdesc, BeanMethod.XSET_ARRAY); emit("void xset" + arrayName + "(" + xtype + "[] " + safeVarName + "Array);", BeanMethod.XSET_ARRAY); printJavaDoc("Sets (as xml) ith " + propdesc, BeanMethod.XSET_IDX); emit("void xset" + arrayName + "(int i, " + xtype + " " + safeVarName + ");", BeanMethod.XSET_IDX); } if (nillable) { printJavaDoc("Nils the ith " + propdesc, BeanMethod.SET_NIL_IDX); emit("void setNil" + arrayName + "(int i);", BeanMethod.SET_NIL_IDX); } if (!xmltype) { printJavaDoc("Inserts the value as the ith " + propdesc, BeanMethod.INSERT_IDX); emit("void insert" + propertyName + "(int i, " + type + " " + safeVarName + ");", BeanMethod.INSERT_IDX); printJavaDoc("Appends the value as the last " + propdesc, BeanMethod.ADD); emit("void add" + propertyName + "(" + type + " " + safeVarName + ");", BeanMethod.ADD); } printJavaDoc("Inserts and returns a new empty value (as xml) as the ith " + propdesc, BeanMethod.INSERT_NEW_IDX); emit(xtype + " insertNew" + propertyName + "(int i);", BeanMethod.INSERT_NEW_IDX); printJavaDoc("Appends and returns a new empty value (as xml) as the last " + propdesc, BeanMethod.ADD_NEW); emit(xtype + " addNew" + propertyName + "();", BeanMethod.ADD_NEW); printJavaDoc("Removes the ith " + propdesc, BeanMethod.REMOVE_IDX); emit("void remove" + propertyName + "(int i);", BeanMethod.REMOVE_IDX); } } 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); StringBuilder interfaces = new StringBuilder(); interfaces.append(sType.getFullJavaName().replace('$', '.')); if (sType.getSimpleVariety() == SchemaType.UNION) { SchemaType[] memberTypes = sType.getUnionMemberTypes(); for (SchemaType memberType : memberTypes) { interfaces.append(", ").append(memberType.getFullJavaName().replace('$', '.')); } } emit("public " + (isInner ? "static " : "") + "class " + shortName + " extends " + baseClass + " implements " + interfaces + " {"); startBlock(); emit("private static final long serialVersionUID = 1L;"); } 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 + ");"); } String makeMissingValue(int javaType) throws IOException { switch (javaType) { case SchemaProperty.JAVA_BOOLEAN: return "false"; case SchemaProperty.JAVA_FLOAT: return "0.0f"; case SchemaProperty.JAVA_DOUBLE: return "0.0"; case SchemaProperty.JAVA_BYTE: case SchemaProperty.JAVA_SHORT: case SchemaProperty.JAVA_INT: return "0"; case SchemaProperty.JAVA_LONG: return "0L"; 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: return "null"; } } void printJGetArrayValue(int javaType, String type, SchemaTypeImpl stype, String setIdentifier) throws IOException { String em; switch (javaType) { case SchemaProperty.XML_OBJECT: em ="XmlObjectArray(#ID#, new " + type + "[0]);"; break; case SchemaProperty.JAVA_ENUM: em = "EnumArray(#ID#, " + type + "[]::new);"; break; case SchemaProperty.JAVA_BOOLEAN: em = "BooleanArray(#ID#);"; break; case SchemaProperty.JAVA_FLOAT: em = "FloatArray(#ID#);"; break; case SchemaProperty.JAVA_DOUBLE: em = "DoubleArray(#ID#);"; break; case SchemaProperty.JAVA_BYTE: em = "ByteArray(#ID#);"; break; case SchemaProperty.JAVA_SHORT: em = "ShortArray(#ID#);"; break; case SchemaProperty.JAVA_INT: em = "IntArray(#ID#);"; break; case SchemaProperty.JAVA_LONG: em = "LongArray(#ID#);"; break; case SchemaProperty.JAVA_BIG_DECIMAL: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getBigDecimalValue, java.math.BigDecimal[]::new);"; break; case SchemaProperty.JAVA_BIG_INTEGER: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getBigIntegerValue, java.math.BigInteger[]::new);"; break; case SchemaProperty.JAVA_STRING: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getStringValue, String[]::new);"; break; case SchemaProperty.JAVA_BYTE_ARRAY: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getByteArrayValue, byte[][]::new);"; break; case SchemaProperty.JAVA_CALENDAR: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getCalendarValue, java.util.Calendar[]::new);"; break; case SchemaProperty.JAVA_DATE: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getDateValue, java.util.Date[]::new);"; break; case SchemaProperty.JAVA_GDATE: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getGDateValue, org.apache.xmlbeans.GDate[]::new);"; break; case SchemaProperty.JAVA_GDURATION: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getGDurationValue, org.apache.xmlbeans.GDuration[]::new);"; break; case SchemaProperty.JAVA_QNAME: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getQNameValue, javax.xml.namespace.QName[]::new);"; break; case SchemaProperty.JAVA_LIST: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getListValue, java.util.List[]::new);"; break; case SchemaProperty.JAVA_OBJECT: em = "ObjectArray(#ID#, org.apache.xmlbeans.SimpleValue::getObjectValue, java.lang.Object[]::new);"; break; case SchemaProperty.JAVA_USER: // TOOD: replace lambda with method reference em = "ObjectArray(#ID#, e -> " + getUserTypeStaticHandlerMethod(false, stype) + "(e), " + stype.getUserTypeName() + "[]::new);"; break; default: throw new IllegalStateException(); } emit("return get" +em.replace("#ID#", setIdentifier), BeanMethod.GET_ARRAY); } String printJGetValue(int javaType, String type, SchemaTypeImpl stype) throws IOException { switch (javaType) { case SchemaProperty.XML_OBJECT: return "target"; case SchemaProperty.JAVA_BOOLEAN: return "target.getBooleanValue()"; case SchemaProperty.JAVA_FLOAT: return "target.getFloatValue()"; case SchemaProperty.JAVA_DOUBLE: return "target.getDoubleValue()"; case SchemaProperty.JAVA_BYTE: return "target.getByteValue()"; case SchemaProperty.JAVA_SHORT: return "target.getShortValue()"; case SchemaProperty.JAVA_INT: return "target.getIntValue()"; case SchemaProperty.JAVA_LONG: return "target.getLongValue()"; case SchemaProperty.JAVA_BIG_DECIMAL: return "target.getBigDecimalValue()"; case SchemaProperty.JAVA_BIG_INTEGER: return "target.getBigIntegerValue()"; case SchemaProperty.JAVA_STRING: return "target.getStringValue()"; case SchemaProperty.JAVA_BYTE_ARRAY: return "target.getByteArrayValue()"; case SchemaProperty.JAVA_GDATE: return "target.getGDateValue()"; case SchemaProperty.JAVA_GDURATION: return "target.getGDurationValue()"; case SchemaProperty.JAVA_CALENDAR: return "target.getCalendarValue()"; case SchemaProperty.JAVA_DATE: return "target.getDateValue()"; case SchemaProperty.JAVA_QNAME: return "target.getQNameValue()"; case SchemaProperty.JAVA_LIST: return "target.getListValue()"; case SchemaProperty.JAVA_ENUM: return "(" + type + ")target.getEnumValue()"; case SchemaProperty.JAVA_OBJECT: return "target.getObjectValue()"; case SchemaProperty.JAVA_USER: return getUserTypeStaticHandlerMethod(false, stype) + "(target)"; default: throw new IllegalStateException(); } } void printJSetValue(int javaType, String safeVarName, SchemaTypeImpl stype) throws IOException { String em; switch (javaType) { case SchemaProperty.XML_OBJECT: em = "target.set(#VARNAME#)"; break; case SchemaProperty.JAVA_BOOLEAN: em = "target.setBooleanValue(#VARNAME#)"; break; case SchemaProperty.JAVA_FLOAT: em = "target.setFloatValue(#VARNAME#)"; break; case SchemaProperty.JAVA_DOUBLE: em = "target.setDoubleValue(#VARNAME#)"; break; case SchemaProperty.JAVA_BYTE: em = "target.setByteValue(#VARNAME#)"; break; case SchemaProperty.JAVA_SHORT: em = "target.setShortValue(#VARNAME#)"; break; case SchemaProperty.JAVA_INT: em = "target.setIntValue(#VARNAME#)"; break; case SchemaProperty.JAVA_LONG: em = "target.setLongValue(#VARNAME#)"; break; case SchemaProperty.JAVA_BIG_DECIMAL: em = "target.setBigDecimalValue(#VARNAME#)"; break; case SchemaProperty.JAVA_BIG_INTEGER: em = "target.setBigIntegerValue(#VARNAME#)"; break; case SchemaProperty.JAVA_STRING: em = "target.setStringValue(#VARNAME#)"; break; case SchemaProperty.JAVA_BYTE_ARRAY: em = "target.setByteArrayValue(#VARNAME#)"; break; case SchemaProperty.JAVA_GDATE: em = "target.setGDateValue(#VARNAME#)"; break; case SchemaProperty.JAVA_GDURATION: em = "target.setGDurationValue(#VARNAME#)"; break; case SchemaProperty.JAVA_CALENDAR: em = "target.setCalendarValue(#VARNAME#)"; break; case SchemaProperty.JAVA_DATE: em = "target.setDateValue(#VARNAME#)"; break; case SchemaProperty.JAVA_QNAME: em = "target.setQNameValue(#VARNAME#)"; break; case SchemaProperty.JAVA_LIST: em = "target.setListValue(#VARNAME#)"; break; case SchemaProperty.JAVA_ENUM: em = "target.setEnumValue(#VARNAME#)"; break; case SchemaProperty.JAVA_OBJECT: em = "target.setObjectValue(#VARNAME#)"; break; case SchemaProperty.JAVA_USER: em = getUserTypeStaticHandlerMethod(true, stype) + "(#VARNAME#, target)"; break; default: throw new IllegalStateException(); } emit(em.replace("#VARNAME#", safeVarName) + ";"); } String getIdentifier(Map qnameMap, QName qName) { return "PROPERTY_QNAME[" + qnameMap.get(qName) + "]"; } String getSetIdentifier(Map qnameMap, QName qName, Map qsetMap) { Integer ord = qsetMap.get(qName); return ord == null ? getIdentifier(qnameMap, qName) : "PROPERTY_QSET["+ ord + "]"; } void printStaticFields(SchemaProperty[] properties, Map qnameMap, Map qsetMap) throws IOException { if (properties.length == 0) { return; } int countQSet = 0; emit(""); emit("private static final QName[] PROPERTY_QNAME = {"); indent(); for (SchemaProperty prop : properties) { final QName name = prop.getName(); qnameMap.put(name, qnameMap.size()); emit("new QName(\"" + name.getNamespaceURI() + "\", \"" + name.getLocalPart() + "\"),"); countQSet = Math.max(countQSet, (prop.acceptedNames() == null ? 0 : prop.acceptedNames().length)); } outdent(); emit("};"); emit(""); if (countQSet > 1) { emit("private static final QNameSet[] PROPERTY_QSET = {"); for (SchemaProperty prop : properties) { final QName name = prop.getName(); final QName[] qnames = prop.acceptedNames(); if (qnames != null && qnames.length > 1) { qsetMap.put(name, qsetMap.size()); emit("QNameSet.forArray( new QName[] { "); indent(); for (QName qname : qnames) { emit("new QName(\"" + qname.getNamespaceURI() + "\", \"" + qname.getLocalPart() + "\"),"); } outdent(); emit("}),"); } } emit("};"); } } void emitImplementationPreamble() throws IOException { emit("synchronized (monitor()) {"); indent(); emit("check_orphaned();"); } void emitImplementationPostamble() throws IOException { outdent(); emit("}"); } void emitAddTarget(String identifier, boolean isAttr, String xtype) throws IOException { if (isAttr) { emit("target = (" + xtype + ")get_store().add_attribute_user(" + identifier + ");"); } else { emit("target = (" + xtype + ")get_store().add_element_user(" + identifier + ");"); } } void emitPre(SchemaType sType, int opType, String identifier, boolean isAttr) throws IOException { emitPre(sType, opType, identifier, isAttr, "-1"); } void emitPre(SchemaType sType, int opType, String identifier, boolean isAttr, String index) throws IOException { SchemaTypeImpl sImpl = getImpl(sType); if (sImpl == null) { return; } PrePostExtension ext = sImpl.getPrePostExtension(); if (ext != null) { if (ext.hasPreCall()) { emit("if ( " + ext.getStaticHandler() + ".preSet(" + prePostOpString(opType) + ", this, " + identifier + ", " + isAttr + ", " + index + ")) {"); startBlock(); } } } void emitPost(SchemaType sType, int opType, String identifier, boolean isAttr) throws IOException { emitPost(sType, opType, identifier, isAttr, "-1"); } void emitPost(SchemaType sType, int opType, String identifier, boolean isAttr, String index) throws IOException { SchemaTypeImpl sImpl = getImpl(sType); if (sImpl == null) { return; } PrePostExtension ext = sImpl.getPrePostExtension(); if (ext != null) { if (ext.hasPreCall()) { endBlock(); } if (ext.hasPostCall()) { emit(ext.getStaticHandler() + ".postSet(" + prePostOpString(opType) + ", this, " + identifier + ", " + isAttr + ", " + index + ");"); } } } String prePostOpString(int opType) { switch (opType) { default: assert false; case PrePostExtension.OPERATION_SET: return "org.apache.xmlbeans.PrePostExtension.OPERATION_SET"; case PrePostExtension.OPERATION_INSERT: return "org.apache.xmlbeans.PrePostExtension.OPERATION_INSERT"; case PrePostExtension.OPERATION_REMOVE: return "org.apache.xmlbeans.PrePostExtension.OPERATION_REMOVE"; } } 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: // target already emited, no need for emitDeclareTarget(false, xtype); emitAddTarget(identifier, isAttr, xtype); break; case THROW_EXCEPTION: emit("throw new IndexOutOfBoundsException();"); break; default: assert false : "Bad behaviour type: " + nullBehaviour; } endBlock(); } void printListGetterImpl(String propdesc, String propertyName, String wrappedType, boolean xmltype, boolean xget) throws IOException { Set bmList = (opt == null) ? null : opt.getCompilePartialMethod(); if (bmList != null && !bmList.contains(xget ? BeanMethod.XGET_LIST : BeanMethod.GET_LIST)) { return; } String arrayName = propertyName + "Array"; printJavaDoc("Gets " + (xget ? "(as xml) " : "") + "a List of " + propdesc + "s"); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public java.util.List<" + wrappedType + "> " + (xget ? "xget" : "get") + propertyName + "List() {"); startBlock(); emitImplementationPreamble(); emit("return new org.apache.xmlbeans.impl.values.JavaList" + ((xmltype || xget) ? "Xml" : "") + "Object<>("); indent(); if (bmList == null || bmList.contains(xget ? BeanMethod.XGET_IDX : BeanMethod.GET_IDX)) { emit("this::" + (xget ? "xget" : "get") + arrayName + ","); } else { emit("null,"); } if (bmList == null || bmList.contains(xget ? BeanMethod.XSET_IDX : BeanMethod.SET_IDX)) { emit("this::" + (xget ? "xset" : "set") + arrayName + ","); } else { emit("null,"); } if (bmList == null || bmList.contains((xmltype || xget) ? BeanMethod.INSERT_NEW_IDX : BeanMethod.INSERT_IDX)) { emit("this::insert" + ((xmltype || xget) ? "New" : "") + propertyName + ","); } else { emit("null,"); } if (bmList == null || bmList.contains(BeanMethod.REMOVE_IDX)) { emit("this::remove" + propertyName + ","); } else { emit("null,"); } if (bmList == null || bmList.contains(BeanMethod.SIZE_OF_ARRAY)) { emit("this::sizeOf" + arrayName); } else { emit("null"); } outdent(); emit(");"); emitImplementationPostamble(); endBlock(); } void printGetterImpls(SchemaProperty prop, Map qnameMap, Map qsetMap) throws IOException { final QName qName = prop.getName(); final String identifier = getIdentifier(qnameMap, qName); final String setIdentifier = getSetIdentifier(qnameMap, qName, qsetMap); final boolean several = prop.extendsJavaArray(); final boolean nillable = prop.hasNillable() != SchemaProperty.NEVER; final String type = javaTypeForProperty(prop); final String xtype = xmlTypeForProperty(prop); final int javaType = prop.getJavaTypeCode(); final boolean isAttr = prop.isAttribute(); final String propertyName = prop.getJavaPropertyName(); String propertyDocumentation = prop.getDocumentation(); String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element"); boolean xmltype = (javaType == SchemaProperty.XML_OBJECT); String jtargetType = (xmlTypeForPropertyIsUnion(prop) || !xmltype) ? "org.apache.xmlbeans.SimpleValue" : xtype; Set bmList = (opt == null) ? null : opt.getCompilePartialMethod(); if (prop.extendsJavaSingleton()) { if (bmList == null || bmList.contains(BeanMethod.GET)) { // Value getProp() if(opt.isCompileAnnotationAsJavadoc() && propertyDocumentation != null && propertyDocumentation.length() > 0){ printJavaDocParagraph(propertyDocumentation); } else { printJavaDoc((several ? "Gets first " : "Gets the ") + propdesc); } if (!opt.isCompileNoAnnotations()) { emit("@Override"); } 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("return (target == null) ? " + makeMissingValue(javaType) + " : " + printJGetValue(javaType, type, (SchemaTypeImpl) prop.getType()) + ";"); emitImplementationPostamble(); endBlock(); } if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XGET))) { // Value xgetProp() printJavaDoc((several ? "Gets (as xml) first " : "Gets (as xml) the ") + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } 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 && (bmList == null || bmList.contains(BeanMethod.IS_NIL))) { // boolean isNilProp() printJavaDoc((several ? "Tests for nil first " : "Tests for nil ") + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public boolean isNil" + propertyName + "() {"); startBlock(); emitImplementationPreamble(); emitGetTarget(setIdentifier, identifier, isAttr, "0", NOTHING, xtype); emit("return target != null && target.isNil();"); emitImplementationPostamble(); endBlock(); } } if (prop.extendsJavaOption() && (bmList == null || bmList.contains(BeanMethod.IS_SET))) { // boolean isSetProp() printJavaDoc((several ? "True if has at least one " : "True if has ") + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } 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"; // use boxed type if the java type is a primitive and jdk1.5 // jdk1.5 will box/unbox for us String wrappedType = type; if (isJavaPrimitive(javaType)) { wrappedType = javaWrappedType(javaType); } printListGetterImpl(propdesc, propertyName, wrappedType, xmltype, false); if (bmList == null || bmList.contains(BeanMethod.GET_ARRAY)) { // Value[] getProp() printJavaDoc("Gets array of all " + propdesc + "s"); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public " + type + "[] get" + arrayName + "() {"); startBlock(); printJGetArrayValue(javaType, type, (SchemaTypeImpl) prop.getType(), setIdentifier); endBlock(); } if (bmList == null || bmList.contains(BeanMethod.GET_IDX)) { // Value getProp(int i) printJavaDoc("Gets ith " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public " + type + " get" + arrayName + "(int i) {"); startBlock(); emitImplementationPreamble(); emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType); emit("return " + printJGetValue(javaType, type, (SchemaTypeImpl) prop.getType()) + ";"); emitImplementationPostamble(); endBlock(); } if (!xmltype) { printListGetterImpl(propdesc, propertyName, xtype, false, true); } if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XGET_ARRAY))) { // Value[] xgetProp() printJavaDoc("Gets (as xml) array of all " + propdesc + "s"); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public " + xtype + "[] xget" + arrayName + "() {"); startBlock(); emit("return xgetArray(" + setIdentifier + ", " + xtype + "[]::new);"); endBlock(); } if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XGET_IDX))) { // Value xgetProp(int i) printJavaDoc("Gets (as xml) ith " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public " + xtype + " xget" + arrayName + "(int i) {"); startBlock(); emitImplementationPreamble(); emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype); emit("return target;"); emitImplementationPostamble(); endBlock(); } if (nillable && (bmList == null || bmList.contains(BeanMethod.IS_NIL_IDX))) { // boolean isNil(int i); printJavaDoc("Tests for nil ith " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } 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(); if (bmList == null || bmList.contains(BeanMethod.SIZE_OF_ARRAY)) { printJavaDoc("Returns number of " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public int sizeOf" + arrayName + "() {"); startBlock(); emitImplementationPreamble(); emit("return get_store().count_elements(" + setIdentifier + ");"); emitImplementationPostamble(); endBlock(); } } } void printSetterImpls(SchemaProperty prop, Map qnameMap, Map qsetMap, SchemaType sType) throws IOException { final QName qName = prop.getName(); final String identifier = getIdentifier(qnameMap, qName); final String setIdentifier = getSetIdentifier(qnameMap, qName, qsetMap); final boolean several = prop.extendsJavaArray(); final boolean nillable = prop.hasNillable() != SchemaProperty.NEVER; final String type = javaTypeForProperty(prop); final String xtype = xmlTypeForProperty(prop); final int javaType = prop.getJavaTypeCode(); final boolean isAttr = prop.isAttribute(); final String propertyName = prop.getJavaPropertyName(); Set bmList = (opt == null) ? null : opt.getCompilePartialMethod(); String safeVarName = NameUtil.nonJavaKeyword(NameUtil.lowerCamelCase(propertyName)); safeVarName = NameUtil.nonExtraKeyword(safeVarName); boolean xmltype = (javaType == SchemaProperty.XML_OBJECT); boolean isobj = (javaType == SchemaProperty.JAVA_OBJECT); boolean isSubstGroup = !Objects.equals(identifier, setIdentifier); String jtargetType = (xmlTypeForPropertyIsUnion(prop) || !xmltype) ? "org.apache.xmlbeans.SimpleValue" : xtype; String propdesc = "\"" + qName.getLocalPart() + "\"" + (isAttr ? " attribute" : " element"); if (prop.extendsJavaSingleton()) { if (bmList == null || bmList.contains(BeanMethod.SET)) { // void setProp(Value v); printJavaDoc((several ? "Sets first " : "Sets the ") + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void set" + propertyName + "(" + type + " " + safeVarName + ") {"); startBlock(); if (xmltype && !isSubstGroup && !isAttr) { emitPre(sType, PrePostExtension.OPERATION_SET, identifier, false, several ? "0" : "-1"); emit("generatedSetterHelperImpl(" + safeVarName + ", " + setIdentifier + ", 0, " + "org.apache.xmlbeans.impl.values.XmlObjectBase.KIND_SETTERHELPER_SINGLETON);"); emitPost(sType, PrePostExtension.OPERATION_SET, identifier, false, several ? "0" : "-1"); } else { emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, jtargetType); printJSetValue(javaType, safeVarName, (SchemaTypeImpl) prop.getType()); emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); emitImplementationPostamble(); } endBlock(); } if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XSET))) { // void xsetProp(Value v) printJavaDoc((several ? "Sets (as xml) first " : "Sets (as xml) the ") + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void xset" + propertyName + "(" + xtype + " " + safeVarName + ") {"); startBlock(); emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype); emit("target.set(" + safeVarName + ");"); emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); emitImplementationPostamble(); endBlock(); } if (xmltype && !several && (bmList == null || bmList.contains(BeanMethod.ADD_NEW))) { // Value addNewProp() printJavaDoc("Appends and returns a new empty " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public " + xtype + " addNew" + propertyName + "() {"); startBlock(); emitImplementationPreamble(); emit(xtype + " target = null;"); emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); emitAddTarget(identifier, isAttr, xtype); emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); emit("return target;"); emitImplementationPostamble(); endBlock(); } if (nillable && (bmList == null || bmList.contains(BeanMethod.SET_NIL))) { printJavaDoc((several ? "Nils the first " : "Nils the ") + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void setNil" + propertyName + "() {"); startBlock(); emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); emitGetTarget(setIdentifier, identifier, isAttr, "0", ADD_NEW_VALUE, xtype); emit("target.setNil();"); emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, several ? "0" : "-1"); emitImplementationPostamble(); endBlock(); } } if (prop.extendsJavaOption() && (bmList == null || bmList.contains(BeanMethod.UNSET))) { printJavaDoc((several ? "Removes first " : "Unsets the ") + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void unset" + propertyName + "() {"); startBlock(); emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, several ? "0" : "-1"); if (isAttr) { emit("get_store().remove_attribute(" + identifier + ");"); } else { emit("get_store().remove_element(" + setIdentifier + ", 0);"); } emitPost(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, several ? "0" : "-1"); emitImplementationPostamble(); endBlock(); } if (several) { String arrayName = propertyName + "Array"; if (bmList == null || bmList.contains(BeanMethod.SET_ARRAY)) { if (xmltype) { printJavaDoc("Sets array of all " + propdesc + " WARNING: This method is not atomicaly synchronized."); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void set" + arrayName + "(" + type + "[] " + safeVarName + "Array) {"); startBlock(); // do not use synchronize (monitor()) { and GlobalLock inside } !!! deadlock //emitImplementationPreamble(); emit("check_orphaned();"); emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); 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 + ");"); } } emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); //emitImplementationPostamble(); to avoid deadlock endBlock(); } else { printJavaDoc("Sets array of all " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void set" + arrayName + "(" + type + "[] " + safeVarName + "Array) {"); startBlock(); emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); if (isobj) { if (!isSubstGroup) { emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");"); } else { emit("unionArraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");"); } } else if (prop.getJavaTypeCode() == SchemaProperty.JAVA_USER) { if (!isSubstGroup) { emit("org.apache.xmlbeans.SimpleValue[] dests = arraySetterHelper(" + safeVarName + "Array.length" + ", " + identifier + ");"); emit("for ( int i = 0 ; i < dests.length ; i++ ) {"); emit(" " + getUserTypeStaticHandlerMethod(true, (SchemaTypeImpl) prop.getType()) + "(" + safeVarName + "Array[i], dests[i]);"); emit("}"); } else { emit("org.apache.xmlbeans.SimpleValue[] dests = arraySetterHelper(" + safeVarName + "Array.length" + ", " + identifier + ", " + setIdentifier + ");"); emit("for ( int i = 0 ; i < dests.length ; i++ ) {"); emit(" " + getUserTypeStaticHandlerMethod(true, (SchemaTypeImpl) prop.getType()) + "(" + safeVarName + "Array[i], dests[i]);"); emit("}"); } } else { if (!isSubstGroup) { emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");"); } else { emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ", " + setIdentifier + ");"); } } emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); emitImplementationPostamble(); endBlock(); } } if (bmList == null || bmList.contains(BeanMethod.SET_IDX)) { printJavaDoc("Sets ith " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void set" + arrayName + "(int i, " + type + " " + safeVarName + ") {"); startBlock(); if (xmltype && !isSubstGroup) { emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); emit("generatedSetterHelperImpl(" + safeVarName + ", " + setIdentifier + ", i, " + "org.apache.xmlbeans.impl.values.XmlObjectBase.KIND_SETTERHELPER_ARRAYITEM);"); emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); } else { emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, jtargetType); printJSetValue(javaType, safeVarName, (SchemaTypeImpl) prop.getType()); emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); emitImplementationPostamble(); } endBlock(); } if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XSET_ARRAY))) { printJavaDoc("Sets (as xml) array of all " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void xset" + arrayName + "(" + xtype + "[]" + safeVarName + "Array) {"); startBlock(); emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); emit("arraySetterHelper(" + safeVarName + "Array" + ", " + identifier + ");"); emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr); emitImplementationPostamble(); endBlock(); } if (!xmltype && (bmList == null || bmList.contains(BeanMethod.XSET_IDX))) { printJavaDoc("Sets (as xml) ith " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void xset" + arrayName + "(int i, " + xtype + " " + safeVarName + ") {"); startBlock(); emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype); emit("target.set(" + safeVarName + ");"); emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); emitImplementationPostamble(); endBlock(); } if (nillable && (bmList == null || bmList.contains(BeanMethod.SET_NIL_IDX))) { printJavaDoc("Nils the ith " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void setNil" + arrayName + "(int i) {"); startBlock(); emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); emitGetTarget(setIdentifier, identifier, isAttr, "i", THROW_EXCEPTION, xtype); emit("target.setNil();"); emitPost(sType, PrePostExtension.OPERATION_SET, identifier, isAttr, "i"); emitImplementationPostamble(); endBlock(); } if (!xmltype && (bmList == null || bmList.contains(BeanMethod.INSERT_IDX))) { printJavaDoc("Inserts the value as the ith " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void insert" + propertyName + "(int i, " + type + " " + safeVarName + ") {"); startBlock(); emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i"); 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(); printJSetValue(javaType, safeVarName, (SchemaTypeImpl) prop.getType()); emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i"); emitImplementationPostamble(); endBlock(); } if (!xmltype && (bmList == null || bmList.contains(BeanMethod.ADD))) { printJavaDoc("Appends the value as the last " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void add" + propertyName + "(" + type + " " + safeVarName + ") {"); startBlock(); emitImplementationPreamble(); emit(jtargetType + " target = null;"); emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); emitAddTarget(identifier, isAttr, jtargetType); printJSetValue(javaType, safeVarName, (SchemaTypeImpl) prop.getType()); emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); emitImplementationPostamble(); endBlock(); } if (bmList == null || bmList.contains(BeanMethod.INSERT_NEW_IDX)) { printJavaDoc("Inserts and returns a new empty value (as xml) as the ith " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public " + xtype + " insertNew" + propertyName + "(int i) {"); startBlock(); emitImplementationPreamble(); emit(xtype + " target = null;"); emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i"); if (!isSubstGroup) { emit("target = (" + xtype + ")get_store().insert_element_user(" + identifier + ", i);"); } else // This is a subst group case { emit("target = (" + xtype + ")get_store().insert_element_user(" + setIdentifier + ", " + identifier + ", i);"); } emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr, "i"); emit("return target;"); emitImplementationPostamble(); endBlock(); } if (bmList == null || bmList.contains(BeanMethod.ADD_NEW)) { printJavaDoc("Appends and returns a new empty value (as xml) as the last " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public " + xtype + " addNew" + propertyName + "() {"); startBlock(); emitImplementationPreamble(); emit(xtype + " target = null;"); emitPre(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); emitAddTarget(identifier, isAttr, xtype); emitPost(sType, PrePostExtension.OPERATION_INSERT, identifier, isAttr); emit("return target;"); emitImplementationPostamble(); endBlock(); } if (bmList == null || bmList.contains(BeanMethod.REMOVE_IDX)) { printJavaDoc("Removes the ith " + propdesc); if (!opt.isCompileNoAnnotations()) { emit("@Override"); } emit("public void remove" + propertyName + "(int i) {"); startBlock(); emitImplementationPreamble(); emitPre(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, "i"); emit("get_store().remove_element(" + setIdentifier + ", i);"); emitPost(sType, PrePostExtension.OPERATION_REMOVE, identifier, isAttr, "i"); emitImplementationPostamble(); endBlock(); } } } SchemaProperty[] getSchemaProperties(SchemaType sType) { if (sType.getContentType() != SchemaType.SIMPLE_CONTENT) { // complex content type implementations derive from base type impls // so derived property impls can be reused return getDerivedProperties(sType); } // 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 // Moreover, attribute or element properties can be removed via restriction, // but we still need to implement them because this class is supposed to // also implement all the interfaces SchemaType baseType = sType.getBaseType(); List extraProperties = null; while (!baseType.isSimpleType() && !baseType.isBuiltinType()) { for (SchemaProperty baseProperty : baseType.getDerivedProperties()) { if (!(baseProperty.isAttribute() && sType.getAttributeProperty(baseProperty.getName()) != null)) { if (extraProperties == null) { extraProperties = new ArrayList<>(); } extraProperties.add(baseProperty); } } baseType = baseType.getBaseType(); } SchemaProperty[] properties = sType.getProperties(); if (extraProperties == null) { return properties; } Collections.addAll(extraProperties, properties); return extraProperties.toArray(new SchemaProperty[0]); } void printInnerTypeImpl( SchemaType sType, SchemaTypeSystem system, boolean isInner) throws IOException { String shortName = sType.getShortJavaImplName(); printInnerTypeJavaDoc(sType); startClass(sType, isInner); printConstructor(sType, shortName); printExtensionImplMethods(sType); if (!sType.isSimpleType()) { SchemaProperty[] properties = getSchemaProperties(sType); Map qnameMap = new HashMap<>(); Map qsetMap = new HashMap<>(); printStaticFields(properties, qnameMap, qsetMap); for (SchemaProperty prop : properties) { printGetterImpls(prop, qnameMap, qsetMap); if (!prop.isReadOnly()) { printSetterImpls(prop, qnameMap, qsetMap, sType); } } } printNestedTypeImpls(sType, system); endBlock(); } private SchemaProperty[] getDerivedProperties(SchemaType sType) { // We have to see if this is redefined, because if it is we have // to include all properties associated to its supertypes QName name = sType.getName(); if (name != null && name.equals(sType.getBaseType().getName())) { SchemaType sType2 = sType.getBaseType(); // Walk all the redefined types and record any properties // not present in sType, because the redefined types do not // have a generated class to represent them SchemaProperty[] props = sType.getDerivedProperties(); Map propsByName = new LinkedHashMap<>(); for (SchemaProperty prop : props) { propsByName.put(prop.getName(), prop); } while (sType2 != null && name.equals(sType2.getName())) { props = sType2.getDerivedProperties(); for (SchemaProperty prop : props) { if (!propsByName.containsKey(prop.getName())) { propsByName.put(prop.getName(), prop); } } sType2 = sType2.getBaseType(); } return propsByName.values().toArray(new SchemaProperty[0]); } else { return sType.getDerivedProperties(); } } private void printExtensionImplMethods(SchemaType sType) throws IOException { SchemaTypeImpl sImpl = getImpl(sType); if (sImpl == null) { return; } InterfaceExtension[] exts = sImpl.getInterfaceExtensions(); if (exts != null) { for (InterfaceExtension ext : exts) { InterfaceExtension.MethodSignature[] methods = ext.getMethods(); if (methods != null) { for (InterfaceExtension.MethodSignature method : methods) { printJavaDoc("Implementation method for interface " + ext.getStaticHandler()); printInterfaceMethodDecl(method); startBlock(); printInterfaceMethodImpl(ext.getStaticHandler(), method); endBlock(); } } } } } void printInterfaceMethodDecl(InterfaceExtension.MethodSignature method) throws IOException { StringBuilder decl = new StringBuilder(60); decl.append("public ").append(method.getReturnType()); decl.append(" ").append(method.getName()).append("("); String[] paramTypes = method.getParameterTypes(); for (int i = 0; i < paramTypes.length; i++) { if (i != 0) { decl.append(", "); } decl.append(paramTypes[i]).append(" p").append(i); } decl.append(")"); String[] exceptions = method.getExceptionTypes(); for (int i = 0; i < exceptions.length; i++) { decl.append(i == 0 ? " throws " : ", ").append(exceptions[i]); } decl.append(" {"); emit(decl.toString()); } void printInterfaceMethodImpl(String handler, InterfaceExtension.MethodSignature method) throws IOException { StringBuilder impl = new StringBuilder(60); if (!method.getReturnType().equals("void")) { impl.append("return "); } impl.append(handler).append(".").append(method.getName()).append("(this"); String[] params = method.getParameterTypes(); for (int i = 0; i < params.length; i++) { impl.append(", p").append(i); } impl.append(");"); emit(impl.toString()); } void printNestedTypeImpls(SchemaType sType, SchemaTypeSystem system) throws IOException { boolean redefinition = sType.getName() != null && sType.getName().equals(sType.getBaseType().getName()); while (sType != null) { SchemaType[] anonTypes = sType.getAnonymousTypes(); for (SchemaType anonType : anonTypes) { if (anonType.isSkippedAnonymousType()) { printNestedTypeImpls(anonType, system); } else { printInnerTypeImpl(anonType, system, true); } } // For redefinition by extension, go ahead and print the anonymous // types in the base if (!redefinition || (sType.getDerivationType() != SchemaType.DT_EXTENSION && !sType.isSimpleType())) { break; } sType = sType.getBaseType(); } } public void printHolder(Writer writer, SchemaTypeSystem system, XmlOptions opt, Repackager repackager) throws IOException { _writer = writer; String sysPack = system.getName(); if (repackager != null) { sysPack = repackager.repackage(new StringBuffer(sysPack)).toString(); } emit("package "+sysPack+";"); emit(""); emit("import org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl;"); emit(""); emit("public final class TypeSystemHolder extends SchemaTypeSystemImpl {"); indent(); emit("public static final TypeSystemHolder typeSystem = new TypeSystemHolder();"); emit(""); emit("private TypeSystemHolder() {"); indent(); emit("super(TypeSystemHolder.class);"); outdent(); emit("}"); outdent(); emit("}"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy