com.netspective.axiom.schema.BasicSchema.java Source code

Java tutorial

Introduction

Here is the source code for com.netspective.axiom.schema.BasicSchema.java

Source

/*
 * Copyright (c) 2000-2004 Netspective Communications LLC. All rights reserved.
 *
 * Netspective Communications LLC ("Netspective") permits redistribution, modification and use of this file in source
 * and binary form ("The Software") under the Netspective Source License ("NSL" or "The License"). The following
 * conditions are provided as a summary of the NSL but the NSL remains the canonical license and must be accepted
 * before using The Software. Any use of The Software indicates agreement with the NSL.
 *
 * 1. Each copy or derived work of The Software must preserve the copyright notice and this notice unmodified.
 *
 * 2. Redistribution of The Software is allowed in object code form only (as Java .class files or a .jar file
 *    containing the .class files) and only as part of an application that uses The Software as part of its primary
 *    functionality. No distribution of the package is allowed as part of a software development kit, other library,
 *    or development tool without written consent of Netspective. Any modified form of The Software is bound by these
 *    same restrictions.
 *
 * 3. Redistributions of The Software in any form must include an unmodified copy of The License, normally in a plain
 *    ASCII text file unless otherwise agreed to, in writing, by Netspective.
 *
 * 4. The names "Netspective", "Axiom", "Commons", "Junxion", and "Sparx" are trademarks of Netspective and may not be
 *    used to endorse or appear in products derived from The Software without written consent of Netspective.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT,
 * ARE HEREBY DISCLAIMED.
 *
 * NETSPECTIVE AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE OR ANY THIRD PARTY AS A
 * RESULT OF USING OR DISTRIBUTING THE SOFTWARE. IN NO EVENT WILL NETSPECTIVE OR ITS LICENSORS BE LIABLE FOR ANY LOST
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN
 * IF IT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 */
package com.netspective.axiom.schema;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import com.netspective.axiom.SqlManager;
import com.netspective.axiom.schema.column.BasicColumn;
import com.netspective.axiom.schema.table.BasicIndex;
import com.netspective.axiom.schema.table.BasicTable;
import com.netspective.axiom.schema.table.TablesCollection;
import com.netspective.axiom.sql.Queries;
import com.netspective.axiom.sql.Query;
import com.netspective.axiom.sql.collection.QueriesCollection;
import com.netspective.axiom.sql.collection.QueryDefinitionsCollection;
import com.netspective.axiom.sql.dynamic.QueryDefinitions;
import com.netspective.commons.io.InputSourceLocator;
import com.netspective.commons.xdm.XdmParseContext;
import com.netspective.commons.xdm.XmlDataModelSchema;
import com.netspective.commons.xdm.exception.DataModelException;
import com.netspective.commons.xml.template.Template;
import com.netspective.commons.xml.template.TemplateCatalog;
import com.netspective.commons.xml.template.TemplateContentHandler;
import com.netspective.commons.xml.template.TemplateProducer;
import com.netspective.commons.xml.template.TemplateProducerParent;
import com.netspective.commons.xml.template.TemplateProducers;

public class BasicSchema
        implements Schema, TemplateProducerParent, XmlDataModelSchema.ConstructionFinalizeListener {
    private static final Log log = LogFactory.getLog(BasicSchema.class);
    private static int counter = 0;
    public static final String TEMPLATEELEMNAME_DATA_TYPE = "data-type";
    public static final String TEMPLATEELEMNAME_TABLE_TYPE = "table-type";
    public static final String TEMPLATEELEMNAME_INDEX_TYPE = "index-type";
    public static final String TEMPLATEELEMNAME_PRESENTATION = "presentation";
    public static final String TEMPLATEELEMNAME_HIBERNATE = "hibernate";
    public static final String TEMPLATEELEMNAME_HIBERNATE_ID = "hibernate-id";
    public static final XmlDataModelSchema.Options XML_DATA_MODEL_SCHEMA_OPTIONS = new XmlDataModelSchema.Options();
    public static final TableComparator TABLE_COMPARATOR = new TableComparator();
    public static final TableTreeNodeComparator TABLE_TREE_NODE_COMPARATOR = new TableTreeNodeComparator();

    static {
        XML_DATA_MODEL_SCHEMA_OPTIONS.setIgnorePcData(true);

        // these template consumers use dynamic namespaces but we need XDM to be able to document them at runtime
        // so we need to tell it that certain classes are consumers
        TemplateCatalog.registerNamespaceForClass("/schema/(.*)/data-type", BasicColumn.ATTRNAME_TYPE,
                BasicColumn.class, true, true);
        TemplateCatalog.registerNamespaceForClass("/schema/(.*)/table-type", BasicTable.ATTRNAME_TYPE,
                BasicTable.class, true, true);
        TemplateCatalog.registerNamespaceForClass("/schema/(.*)/index-type", BasicIndex.ATTRNAME_TYPE,
                BasicIndex.class, true, true);
    }

    private SqlManager sqlManager;
    private String name = "schema" + (counter++);
    private String xmlNodeName;
    private Tables tables = new TablesCollection();
    private Queries views = new QueriesCollection();
    private TemplateProducer tableTypes;
    private TemplateProducer indexTypes;
    private TemplateProducer dataTypes;
    private TemplateProducers templateProducers;
    private Schema.TableTree structure;
    private InputSourceLocator inputSourceLocator;
    private String logicalDeleteUpdateSqlSetClauseFormat = "record_status_id = 0";

    public BasicSchema(SqlManager sqlManager) {
        setSqlManager(sqlManager);
    }

    public InputSourceLocator getInputSourceLocator() {
        return inputSourceLocator;
    }

    public void setInputSourceLocator(InputSourceLocator inputSourceLocator) {
        this.inputSourceLocator = inputSourceLocator;
    }

    public SqlManager getSqlManager() {
        return sqlManager;
    }

    public void setSqlManager(SqlManager sqlManager) {
        this.sqlManager = sqlManager;
    }

    public String getPresentationTemplatesNameSpaceId() {
        return "/schema/" + getName() + "/presentation";
    }

    public String getDataTypesTemplatesNameSpaceId() {
        return "/schema/" + getName() + "/data-type";
    }

    public String getTableTypesTemplatesNameSpaceId() {
        return "/schema/" + getName() + "/table-type";
    }

    public String getIndexTypesTemplatesNameSpaceId() {
        return "/schema/" + getName() + "/index-type";
    }

    public String getHibernateIdTemplatesNameSpaceId() {
        return "/schema/" + getName() + "/hibernate-id";
    }

    public String getHibernateTemplatesNameSpaceId() {
        return "/schema/" + getName() + "/hibernate";
    }

    public TemplateProducers getTemplateProducers() {
        if (templateProducers == null) {
            templateProducers = new TemplateProducers();
            templateProducers.add(getTableTypes());
            templateProducers.add(getIndexTypes());
            templateProducers.add(getDataTypes());
        }
        return templateProducers;
    }

    public TemplateProducer getDataTypes() {
        if (dataTypes == null)
            dataTypes = new TemplateProducer(getDataTypesTemplatesNameSpaceId(), TEMPLATEELEMNAME_DATA_TYPE, "name",
                    "type", false, false);
        return dataTypes;
    }

    public TemplateProducer getTableTypes() {
        if (tableTypes == null)
            tableTypes = new TemplateProducer(getTableTypesTemplatesNameSpaceId(), TEMPLATEELEMNAME_TABLE_TYPE,
                    "name", "type", false, false);
        return tableTypes;
    }

    public TemplateProducer getIndexTypes() {
        if (indexTypes == null)
            indexTypes = new TemplateProducer(getIndexTypesTemplatesNameSpaceId(), TEMPLATEELEMNAME_INDEX_TYPE,
                    "name", "type", false, false);
        return indexTypes;
    }

    /**
     * This method will be called by the DataModelSchema automatically when all the children have been added. We call
     * the other methods "finishConstruction" so they are not called automatically by the DataModelSchema. We want to
     * do all construction finalization in this method only.
     */
    public void finalizeConstruction(XdmParseContext pc, Object element, String elementName)
            throws DataModelException {
        getTables().finishConstruction();

        try {
            TemplateContentHandler handler = (TemplateContentHandler) pc.getParser().getContentHandler();
            AttributesImpl dialogsPackageAttrs = new AttributesImpl();
            dialogsPackageAttrs.addAttribute(null, null, "package", "CDATA", "schema." + getName());
            Template dialogsPackage = new Template("schema." + getName() + "-tables", handler,
                    new InputSourceLocator(pc.getInputSrcTracker(), pc.getLocator().getLineNumber(),
                            pc.getLocator().getColumnNumber()),
                    handler.getTemplatCatalog(), handler.getDynamicTemplatesProducer(), null, "dialogs", "dialogs",
                    dialogsPackageAttrs);

            // now go through and generate dialog templates for each of the tables
            Tables tables = getTables();
            for (int i = 0; i < tables.size(); i++) {
                Table table = tables.get(i);
                table.addSchemaRecordEditorDialogTemplates(dialogsPackage);
            }

            handler.addDynamicTemplate(dialogsPackage);
        } catch (SAXException e) {
            throw new DataModelException(pc, e);
        }
    }

    public static String translateNameForMapKey(String name) {
        return name.toUpperCase();
    }

    public String getName() {
        return name;
    }

    public String getNameForMapKey() {
        return translateNameForMapKey(name);
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getXmlNodeName() {
        return xmlNodeName == null ? name : xmlNodeName;
    }

    public void setXmlNodeName(String xmlNodeName) {
        this.xmlNodeName = xmlNodeName;
    }

    public void addTable(Table table) {
        tables.add(table);
    }

    public Table createTable() {
        return new BasicTable(this);
    }

    public Table createTable(Class cls) throws NoSuchMethodException, InstantiationException,
            IllegalAccessException, InvocationTargetException {
        if (Table.class.isAssignableFrom(cls)) {
            Constructor c = cls.getConstructor(new Class[] { Schema.class });
            return (Table) c.newInstance(new Object[] { this });
        } else
            throw new RuntimeException("Don't know what to do with with class: " + cls);
    }

    public Tables getTables() {
        return tables;
    }

    public void addView(Query view) {
        views.add(view);
    }

    public Query createView() {
        return new Query();
    }

    public Queries getViews() {
        return views;
    }

    public Tables getApplicationTables() {
        Tables result = new TablesCollection();
        for (int i = 0; i < tables.size(); i++) {
            Table table = tables.get(i);
            if (table.isApplicationTable())
                result.add(table);
        }
        return result;
    }

    public Column getColumn(String tableName, String tableColumn) {
        Table table = tables.getByName(tableName);
        return table != null ? table.getColumns().getByName(tableColumn) : null;
    }

    public QueryDefinitions getQueryDefinitions() {
        QueryDefinitions result = new QueryDefinitionsCollection();
        for (int i = 0; i < tables.size(); i++) {
            Table table = tables.get(i);
            if (table.isApplicationTable())
                result.add(table.getQueryDefinition());
        }
        return result;
    }

    /* ------------------------------------------------------------------------------------------------------------- */

    public String getLogicalDeleteUpdateSqlSetClauseFormat() {
        return logicalDeleteUpdateSqlSetClauseFormat;
    }

    public void setLogicalDeleteUpdateSqlSetClauseFormat(String sqlFormat) {
        this.logicalDeleteUpdateSqlSetClauseFormat = sqlFormat;
    }

    /* ------------------------------------------------------------------------------------------------------------- */

    public String toString() {
        return tables.toString();
    }

    /* ------------------------------------------------------------------------------------------------------------- */

    public Schema.TableTree getStructure() {
        if (structure == null)
            structure = new BasicTableTree();

        return structure;
    }

    public DataAccessLayerGenerator generateDataAccessLayer(File rootDir, String rootNameSpace, String dalClassName)
            throws IOException {
        DataAccessLayerGenerator dalGen = new DataAccessLayerGenerator(getStructure(), rootDir, rootNameSpace,
                dalClassName);
        dalGen.generate();
        return dalGen;
    }

    public static class TableComparator implements Comparator {
        public int compare(Object o1, Object o2) {
            Table t1 = (Table) o1;
            Table t2 = (Table) o2;

            return Collator.getInstance().compare(t1.getName().toUpperCase(), t2.getName().toUpperCase());
        }
    }

    public static class TableTreeNodeComparator implements Comparator {
        public int compare(Object o1, Object o2) {
            TableTreeNode n1 = (TableTreeNode) o1;
            TableTreeNode n2 = (TableTreeNode) o2;

            return Collator.getInstance().compare(n1.getTable().getName().toUpperCase(),
                    n2.getTable().getName().toUpperCase());
        }
    }

    protected class BasicTableTree implements TableTree {
        private List children = new ArrayList();

        public BasicTableTree() {
            Tables tables = getTables();
            Set sortedChildren = new TreeSet(TABLE_TREE_NODE_COMPARATOR);
            for (int i = 0; i < tables.size(); i++) {
                Table table = tables.get(i);
                if (table.isApplicationTable() && !table.isChildTable())
                    sortedChildren.add(table.createTreeNode(this, null, 1));
            }
            children.addAll(sortedChildren);
        }

        public Schema getSchema() {
            return BasicSchema.this;
        }

        public List getChildren() {
            return children;
        }

        public String toString() {
            StringBuffer sb = new StringBuffer();

            sb.append(getSchema().getName());
            sb.append("\n");

            for (int c = 0; c < children.size(); c++)
                sb.append(children.get(c));

            return sb.toString();
        }

        public void generateDataAccessLayer(DataAccessLayerGenerator generator) {
        }
    }
}