Package org.eclipse.persistence.tools.dbws.oracle

Source Code of org.eclipse.persistence.tools.dbws.oracle.PLSQLOXDescriptorBuilder

/*******************************************************************************
* Copyright (c) 1998, 2012 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     Mike Norman - from Proof-of-concept, become production code
******************************************************************************/
package org.eclipse.persistence.tools.dbws.oracle;

//javase imports
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

//java eXtension imports
import javax.xml.namespace.QName;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;

//EclipseLink imports
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.mappings.XMLCompositeCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeDirectCollectionMapping;
import org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;
import org.eclipse.persistence.oxm.schema.XMLSchemaURLReference;
import org.eclipse.persistence.platform.database.oracle.publisher.visit.PublisherDefaultListener;

import static org.eclipse.persistence.internal.helper.ClassConstants.BIGDECIMAL;
import static org.eclipse.persistence.internal.helper.ClassConstants.BOOLEAN;
import static org.eclipse.persistence.internal.helper.ClassConstants.INTEGER;
import static org.eclipse.persistence.internal.helper.ClassConstants.JavaSqlDate_Class;
import static org.eclipse.persistence.internal.helper.ClassConstants.Object_Class;
import static org.eclipse.persistence.internal.helper.ClassConstants.STRING;
import static org.eclipse.persistence.internal.xr.XRDynamicClassLoader.COLLECTION_WRAPPER_SUFFIX;
import static org.eclipse.persistence.oxm.XMLConstants.ANY_SIMPLE_TYPE_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.BOOLEAN_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.DATE_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.DECIMAL_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.INTEGER_QNAME;
import static org.eclipse.persistence.oxm.XMLConstants.SCHEMA_INSTANCE_PREFIX;
import static org.eclipse.persistence.oxm.XMLConstants.SCHEMA_PREFIX;
import static org.eclipse.persistence.oxm.XMLConstants.STRING_QNAME;
import static org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType.XSI_NIL;

public class PLSQLOXDescriptorBuilder extends PublisherDefaultListener {

    public static final String ITEMS_MAPPING_ATTRIBUTE_NAME = "items";

    protected String targetNamespace;
    protected Stack<ListenerHelper> stac = new Stack<ListenerHelper>();
    protected Map<String, XMLDescriptor> descriptorMap = new HashMap<String, XMLDescriptor>();
    protected String packageName = null;

    public PLSQLOXDescriptorBuilder(String targetNamespace) {
        this.targetNamespace = targetNamespace;
    }

    public List<XMLDescriptor> getDescriptors() {
        if (descriptorMap.isEmpty()) {
            return null;
        }
        ArrayList<XMLDescriptor> al = new ArrayList<XMLDescriptor>();
        al.addAll(descriptorMap.values());
        return al;
    }

    @Override
    public void beginPackage(String packageName) {
        // trim-off package name
        int dotIdx = packageName.indexOf('.');
        if (dotIdx > -1) {
            this.packageName = packageName.substring(dotIdx+1);
        }
    }
    @Override
    public void beginPlsqlTable(String tableName, String targetTypeName) {
        TableHelper tableHelper = new TableHelper(tableName, targetTypeName.toLowerCase(), targetTypeName);
        stac.push(tableHelper);
    }
    @Override
    public void endPlsqlTable(String tableName, String typeDDL, String typeDropDDL) {
        ListenerHelper top = stac.pop();
        ListenerHelper next  = stac.peek();
        TableHelper tableHelper = null;
        if (next.isTable()) {
            tableHelper = (TableHelper)next;
            next = top; // switch around stack order
        }
        else if (top.isTable()) {
            tableHelper = (TableHelper)top;
        }
        String tableAlias = tableHelper.targetTypeName().toLowerCase();
        XMLDescriptor xdesc = descriptorMap.get(tableAlias);
        if (xdesc == null) {
            xdesc = new XMLDescriptor();
            xdesc.setAlias(tableHelper.tableAlias());
            xdesc.setJavaClassName(tableName.toLowerCase() + COLLECTION_WRAPPER_SUFFIX);
            xdesc.getQueryManager();
            xdesc.setDefaultRootElement(tableHelper.targetTypeName());
            XMLSchemaURLReference schemaReference = new XMLSchemaURLReference("");
            schemaReference.setSchemaContext("/" + tableHelper.targetTypeName());
            schemaReference.setType(XMLSchemaReference.COMPLEX_TYPE);
            xdesc.setSchemaReference(schemaReference);
            NamespaceResolver nr = new NamespaceResolver();
            nr.setDefaultNamespaceURI(targetNamespace);
            xdesc.setNamespaceResolver(nr);
        }
        boolean itemsMappingFound =
            xdesc.getMappingForAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME) == null ? false : true;
        if (next.isRecord()) {
            if (!itemsMappingFound) {
                XMLCompositeCollectionMapping itemsMapping = new XMLCompositeCollectionMapping();
                itemsMapping.setAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME);
                itemsMapping.setXPath("item");
                XMLField xField = (XMLField)itemsMapping.getField();
                xField.setRequired(true);
                itemsMapping.useCollectionClassName("java.util.ArrayList");
                itemsMapping.setReferenceClassName(((RecordHelper)next).recordName().toLowerCase());
                xdesc.addMapping(itemsMapping);
            }
            tableHelper.nestedIsComplex();
        }
        else  {
            if (!itemsMappingFound) {
                if (!next.isComplex()) {
                    XMLCompositeDirectCollectionMapping itemsMapping = new XMLCompositeDirectCollectionMapping();
                    itemsMapping.setAttributeElementClass(
                        attributeClassFromDatabaseType((DefaultListenerHelper)next));
                    itemsMapping.setAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME);
                    itemsMapping.setUsesSingleNode(true);
                    itemsMapping.setXPath("item/text()");
                    XMLField xField = (XMLField)itemsMapping.getField();
                    xField.setRequired(true);
                    itemsMapping.useCollectionClassName("java.util.ArrayList");
                    AbstractNullPolicy nullPolicy = itemsMapping.getNullPolicy();
                    nullPolicy.setNullRepresentedByEmptyNode(false);
                    nullPolicy.setMarshalNullRepresentation(XSI_NIL);
                    nullPolicy.setNullRepresentedByXsiNil(true);
                    itemsMapping.setNullPolicy(nullPolicy);
                    xdesc.getNamespaceResolver().put(SCHEMA_INSTANCE_PREFIX,
                        W3C_XML_SCHEMA_INSTANCE_NS_URI); // to support xsi:nil policy
                    xdesc.addMapping(itemsMapping);
                }
                else {
                    XMLCompositeCollectionMapping itemsMapping = new XMLCompositeCollectionMapping();
                    itemsMapping.setAttributeName(ITEMS_MAPPING_ATTRIBUTE_NAME);
                    itemsMapping.setXPath("item");
                    XMLField xField = (XMLField)itemsMapping.getField();
                    xField.setRequired(true);
                    itemsMapping.useCollectionClassName("java.util.ArrayList");
                    itemsMapping.setReferenceClassName(((TableHelper)next).tableName().toLowerCase() +
                        COLLECTION_WRAPPER_SUFFIX);
                    xdesc.addMapping(itemsMapping);
                }
            }
            if (next.isTable()) {
                ((TableHelper)next).nestedIsComplex();
            }
        }
        if (!itemsMappingFound) {
            descriptorMap.put(tableAlias, xdesc);
        }
    }
    @Override
    public void beginPlsqlRecord(String plsqlRecordName, String targetTypeName, int numFields) {
        RecordHelper recordHelper = new RecordHelper(plsqlRecordName, targetTypeName, numFields);
        stac.push(recordHelper);
        String recordAlias = targetTypeName.toLowerCase();
        XMLDescriptor xdesc = descriptorMap.get(recordAlias);
        if (xdesc == null) {
            xdesc = new XMLDescriptor();
            xdesc.setAlias(recordAlias);
            xdesc.setJavaClassName(plsqlRecordName.toLowerCase());
            xdesc.setDefaultRootElement(targetTypeName);
            xdesc.getQueryManager();
            XMLSchemaURLReference schemaReference = new XMLSchemaURLReference();
            schemaReference.setSchemaContext("/" + targetTypeName);
            schemaReference.setType(XMLSchemaReference.COMPLEX_TYPE);
            xdesc.setSchemaReference(schemaReference);
            NamespaceResolver nr = new NamespaceResolver();
            nr.setDefaultNamespaceURI(targetNamespace);
            xdesc.setNamespaceResolver(nr);
            descriptorMap.put(recordAlias, xdesc);
        }
    }

    @Override
    public void endPlsqlRecordField(String fieldName, int idx) {
        ListenerHelper top = stac.pop();
        ListenerHelper listenerHelper = stac.peek();
        if (listenerHelper.isRecord()) {
            RecordHelper recordHelper = (RecordHelper)stac.peek();
            XMLDescriptor xdesc = descriptorMap.get(recordHelper.targetTypeName().toLowerCase());
            String lfieldName = fieldName.toLowerCase();
            if (xdesc.getMappingForAttributeName(lfieldName) == null) {
                if (top.isComplex()) {
                    if (top.isTable()) {
                        TableHelper tblHelper = (TableHelper)top;
                        if (tblHelper.isNestedComplex()) {
                            XMLCompositeObjectMapping fieldMapping = new XMLCompositeObjectMapping();
                            fieldMapping.setAttributeName(lfieldName);
                            fieldMapping.setXPath(lfieldName);
                            XMLField xField = (XMLField)fieldMapping.getField();
                            xField.setRequired(true);
                            fieldMapping.setReferenceClassName(tblHelper.tableName().toLowerCase());
                            xdesc.addMapping(fieldMapping);
                        }
                        else {
                            XMLCompositeDirectCollectionMapping fieldMapping =
                                new XMLCompositeDirectCollectionMapping();
                            String foo = tblHelper.targetTypeName().toLowerCase();
                            XMLDescriptor xdesc2 = descriptorMap.get(foo);
                            if (xdesc2 != null) {
                                XMLCompositeDirectCollectionMapping itemsMapping =
                                    (XMLCompositeDirectCollectionMapping)xdesc2.getMappingForAttributeName(
                                    ITEMS_MAPPING_ATTRIBUTE_NAME);
                                Class<?> attributeElementClass = itemsMapping.getAttributeElementClass();
                                fieldMapping.setAttributeElementClass(attributeElementClass);
                            }
                            else {
                                fieldMapping.setAttributeElementClass(String.class); //TODO
                            }
                            fieldMapping.setAttributeName(lfieldName);
                            fieldMapping.setUsesSingleNode(true);
                            fieldMapping.setXPath(lfieldName + "/item/text()");
                            XMLField xField = (XMLField)fieldMapping.getField();
                            xField.setRequired(true);
                            fieldMapping.useCollectionClassName("java.util.ArrayList");
                            AbstractNullPolicy nullPolicy = fieldMapping.getNullPolicy();
                            nullPolicy.setNullRepresentedByEmptyNode(false);
                            nullPolicy.setMarshalNullRepresentation(XSI_NIL);
                            nullPolicy.setNullRepresentedByXsiNil(true);
                            fieldMapping.setNullPolicy(nullPolicy);
                            xdesc.getNamespaceResolver().put(SCHEMA_INSTANCE_PREFIX,
                                W3C_XML_SCHEMA_INSTANCE_NS_URI); // to support xsi:nil policy
                            xdesc.addMapping(fieldMapping);
                        }
                    }
                    else if (top.isRecord()) {
                        XMLCompositeObjectMapping fieldMapping = new XMLCompositeObjectMapping();
                        fieldMapping.setAttributeName(lfieldName);
                        fieldMapping.setXPath(lfieldName);
                        XMLField xField = (XMLField)fieldMapping.getField();
                        xField.setRequired(true);
                        fieldMapping.setReferenceClassName(((RecordHelper)top).recordName().toLowerCase());
                        xdesc.addMapping(fieldMapping);
                    }
                }
                else {
                    XMLDirectMapping fieldMapping = new XMLDirectMapping();
                    fieldMapping.setAttributeName(lfieldName);
                    XMLField xField = new XMLField(lfieldName + "/text()");
                    xField.setRequired(true);
                    QName qnameFromDatabaseType = qnameFromDatabaseType(top);
                    xField.setSchemaType(qnameFromDatabaseType);
                    // special case to avoid Calendar problems
                    if (qnameFromDatabaseType == DATE_QNAME) {
                        fieldMapping.setAttributeClassification(java.sql.Date.class);
                        xField.addXMLConversion(DATE_QNAME, java.sql.Date.class);
                        xField.addJavaConversion(java.sql.Date.class, DATE_QNAME);
                        xdesc.getNamespaceResolver().put(SCHEMA_INSTANCE_PREFIX,
                            W3C_XML_SCHEMA_INSTANCE_NS_URI);
                        xdesc.getNamespaceResolver().put(SCHEMA_PREFIX, W3C_XML_SCHEMA_NS_URI);
                    }
                    else {
                        Class<?> attributeClass = (Class<?>)XMLConversionManager.getDefaultXMLTypes().
                            get(qnameFromDatabaseType);
                        if (attributeClass == null) {
                            attributeClass =  Object_Class;
                        }
                        fieldMapping.setAttributeClassification(attributeClass);
                    }
                    fieldMapping.setField(xField);
                    AbstractNullPolicy nullPolicy = fieldMapping.getNullPolicy();
                    nullPolicy.setNullRepresentedByEmptyNode(false);
                    nullPolicy.setMarshalNullRepresentation(XSI_NIL);
                    nullPolicy.setNullRepresentedByXsiNil(true);
                    fieldMapping.setNullPolicy(nullPolicy);
                    xdesc.getNamespaceResolver().put(SCHEMA_INSTANCE_PREFIX,
                        W3C_XML_SCHEMA_INSTANCE_NS_URI); // to support xsi:nil policy
                    xdesc.addMapping(fieldMapping);
                }
            }
        }
        else {
            System.identityHashCode(listenerHelper);
        }
    }
    @Override
    public void endMethodArg(String argName) {
        stac.pop();
    }
    @Override
    public void handleSqlType(String sqlTypeName, int typecode, String targetType) {
        stac.push(new SqltypeHelper(sqlTypeName));
    }
    @Override
    public void handleObjectType(String objectTypename, String targetTypeName, int numAttributes) {
        stac.push(new ObjectTypeHelper(objectTypename, targetTypeName, numAttributes));
    }

    public static Class<?> attributeClassFromDatabaseType(DefaultListenerHelper helper) {
        if (!helper.isComplex()) {
            String typeName = helper.targetTypeName();
            if (typeName == null) {
                if (helper instanceof SqltypeHelper) {
                    typeName = ((SqltypeHelper)helper).sqlTypeName();
                }
                else if (helper instanceof ObjectTypeHelper) {
                    typeName = ((ObjectTypeHelper)helper).objectTypename();
                }
                else if (helper instanceof SqlArrayTypeHelper) {
                    typeName = ((SqlArrayTypeHelper)helper).arrayTypename();
                }
            }
            if ("NUMBER".equals(typeName)) {
                return BIGDECIMAL;
            }
            if ("INTEGER".equals(typeName)) {
                return INTEGER;
            }
            else if ("BOOLEAN".equals(typeName)) {
                return BOOLEAN;
            }
            else if ("DATE".equals(typeName)) {
                return JavaSqlDate_Class;
            }
            // TODO - more conversions
        }
        // default is String
        return STRING;
    }

    public static <T extends ListenerHelper> QName qnameFromDatabaseType(T helper) {
        if (!helper.isComplex()) {
            String typeName = helper.targetTypeName();
            if (typeName == null) {
                if (helper instanceof SqltypeHelper) {
                    typeName = ((SqltypeHelper)helper).sqlTypeName();
                }
                if (typeName == null) {
                    if (helper instanceof ObjectTypeHelper) {
                        typeName = ((ObjectTypeHelper)helper).objectTypename();
                    }
                }
            }
            if ("VARCHAR2".equals(typeName) || "VARCHAR".equals(typeName)) {
                return STRING_QNAME;
            }
            else if ("NUMBER".equals(typeName)) {
                return DECIMAL_QNAME;
            }
            else if ("INTEGER".equals(typeName)) {
                return INTEGER_QNAME;
            }
            else if ("BOOLEAN".equals(typeName)) {
                return BOOLEAN_QNAME;
            }
            else if ("DATE".equals(typeName)) {
                return DATE_QNAME;
            }
            // TODO - more conversions
        }
        return ANY_SIMPLE_TYPE_QNAME;
    }
}
TOP

Related Classes of org.eclipse.persistence.tools.dbws.oracle.PLSQLOXDescriptorBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.