Package org.apache.ojb.broker.metadata.torque

Source Code of org.apache.ojb.broker.metadata.torque.TorqueForeignKeyGenerator

package org.apache.ojb.broker.metadata.torque;

/* Copyright 2002-2005 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.
*/

import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.CollectionDescriptor;
import org.apache.ojb.broker.metadata.DescriptorRepository;
import org.apache.ojb.broker.metadata.FieldDescriptor;
import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

public class TorqueForeignKeyGenerator {
  private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private DescriptorRepository repository;
    private HashMap mappingTables = new HashMap();
    private HashMap foreignKeyVectors = new HashMap();

    public TorqueForeignKeyGenerator(DescriptorRepository repository) {
        this.repository = repository;
    }

    public void buildConstraintsMap() {
        Iterator classDescriptorIterators = this.repository.iterator();
        while (classDescriptorIterators.hasNext()) {
            ClassDescriptor cd = (ClassDescriptor) classDescriptorIterators.next();
            if(cd.isAbstract() || cd.isInterface())
            {
        logger.debug( "Skip constraint build for abstract class/ interface " + cd.getClassNameOfObject() );
            }
            else
            {
                buildConstraints(cd);
                buildOneToOneConstraints(cd);
            }
        }
    }

    public Vector getForeignKeysForTable(String tableName) {
        return (Vector) this.foreignKeyVectors.get(tableName);
    }

    public HashMap getMappingTables() {
        return this.mappingTables;
    }

    private void buildTableFieldDescriptors(FieldDescriptor fieldDescriptors[], TableDescriptor tableDescriptor) {
        for (int i = 0; i < fieldDescriptors.length; i++) {
            tableDescriptor.addColumn(fieldDescriptors[i]);
        }
    }

    private void buildConstraints(ClassDescriptor cd) {
        Vector collectionDescriptors = cd.getCollectionDescriptors();
        for (int i = 0; i < collectionDescriptors.size(); i++) {
            CollectionDescriptor collectionDescriptor = (CollectionDescriptor) collectionDescriptors.get(i);
            if (collectionDescriptor.isMtoNRelation()) {
                buildManyToManyConstraints(cd, collectionDescriptor);
            } else {
                buildOneToManyReferences(cd, collectionDescriptor);
            }
        }
    }

    private void buildManyToManyConstraints(ClassDescriptor cd, CollectionDescriptor collectionDescriptor) {
        Vector columns = new Vector();

        ClassDescriptor itemDescriptor = this.repository.getDescriptorFor(collectionDescriptor.getItemClass());
        buildManyToManyReferences(cd, collectionDescriptor, collectionDescriptor.getFksToThisClass(), columns);
        buildManyToManyReferences(itemDescriptor, collectionDescriptor, collectionDescriptor.getFksToItemClass(), columns);

        if (isImplicitlyMapped(collectionDescriptor.getIndirectionTable())) {
            TableDescriptor mappingTable = new TableDescriptor();
            buildTableFieldDescriptors((FieldDescriptor[]) columns.toArray(new FieldDescriptor[0]), mappingTable);
            mappingTable.setName(collectionDescriptor.getIndirectionTable());
            this.mappingTables.put(mappingTable.getName(), mappingTable);
        }
    }

    private void buildManyToManyReferences(ClassDescriptor cd, CollectionDescriptor collectionDescriptor,
                                           Object keys[], Vector columns)
    {
        if(cd.isAbstract() || cd.isInterface())
        {
      logger.debug( "Skip foreign key build for MtoM, found abstract base class or interface " + cd.getClassNameOfObject() );
            return;
        }
        StringBuffer buffer = new StringBuffer(256);
        buildForeignKeyHeader(cd.getFullTableName(), buffer);

        for (int i = 0; i < keys.length; i++) {
            String columnName = (String) keys[i];

            FieldDescriptor foreignColumn = cd.getPkFields()[i];
            String foreignColumnName = foreignColumn.getPersistentField().getName();
            buildReferenceForColumn(buffer, columnName, foreignColumnName);
            FieldDescriptor fieldDescriptor = (FieldDescriptor)foreignColumn.clone();
            fieldDescriptor.setColumnName(columnName);
            columns.add(fieldDescriptor);
        }
        buffer.append("        </foreign-key>\n");

        addReferenceToTable(collectionDescriptor.getIndirectionTable(), buffer.toString());
    }

    private void buildOneToManyReferences(ClassDescriptor cd, CollectionDescriptor collectionDescriptor) {
        Vector foreignKeyIndices = collectionDescriptor.getForeignKeyFields();
        ClassDescriptor foreignKeyClassDescriptor = this.repository.getDescriptorFor(collectionDescriptor.getItemClass());
        buildForeignKey(cd, foreignKeyIndices, foreignKeyClassDescriptor);
    }


    private void buildOneToOneConstraints(ClassDescriptor classDescriptor) {
        Vector referenceDescriptors = classDescriptor.getObjectReferenceDescriptors();
        for (int i = 0; i < referenceDescriptors.size(); i++) {
            ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) referenceDescriptors.get(i);

            Vector foreignKeyIndices = ord.getForeignKeyFields();
            ClassDescriptor foreignClassDescriptor = this.repository.getDescriptorFor(ord.getItemClass());
            buildForeignKey(foreignClassDescriptor, foreignKeyIndices, classDescriptor);
        }
    }

    private void buildForeignKey(ClassDescriptor foreignClassDescriptor, Vector foreignKeyIndices, ClassDescriptor classDescriptor) {

        if(classDescriptor.isAbstract() || classDescriptor.isInterface())
        {
      logger.debug( "Skip foreign key build, found abstract base class or interface " + classDescriptor.getClassNameOfObject() );
            return;
        }
        StringBuffer buffer = new StringBuffer(256);
        buildForeignKeyHeader(foreignClassDescriptor.getFullTableName(), buffer);

        for (int i = 0; i < foreignKeyIndices.size(); i++) {
            String columnName = null;
            Object obj = foreignKeyIndices.get(i);

            if (obj instanceof Integer)
            {
                int foreignKeyIndex = ((Integer) obj).intValue();
                columnName = classDescriptor.getFieldDescriptorByIndex(foreignKeyIndex).getColumnName();
            }
            else
            {
                    FieldDescriptor fld = classDescriptor.getFieldDescriptorByName((String) obj);
                    if(fld == null)
                    {
            logger.debug( "FieldDescriptor for foreign key parameter \n" + obj + " was not found in ClassDescriptor \n" + classDescriptor );
                    }
                    else columnName = fld.getColumnName();
            }

            FieldDescriptor foreignColumn = foreignClassDescriptor.getPkFields()[i];
            String foreignColumnName = foreignColumn.getColumnName();
            buildReferenceForColumn(buffer, columnName, foreignColumnName);
        }
        buffer.append("        </foreign-key>\n");
        addReferenceToTable(classDescriptor.getFullTableName(), buffer.toString());
    }

    private void buildForeignKeyHeader(String foreignClassName, StringBuffer buffer) {
        buffer.append("        <foreign-key foreignTable=\"");
        buffer.append(foreignClassName);
        buffer.append("\">\n");
    }

    private void buildReferenceForColumn(StringBuffer buffer, String columnName, String foreignColumnName) {
        buffer.append("            <reference local=\"");
        buffer.append(columnName);
        buffer.append("\" foreign=\"");
        buffer.append(foreignColumnName);
        buffer.append("\"/>\n");
    }


    private boolean isImplicitlyMapped(String tableName) {
        Iterator classDescriptorIterator = repository.iterator();

        while (classDescriptorIterator.hasNext()) {
            ClassDescriptor cd = (ClassDescriptor) classDescriptorIterator.next();
            if (tableName.equals(cd.getFullTableName())) {
                return false;
            }
        }

        return true;
    }

    private void addReferenceToTable(String tableName, String reference) {
        Vector tableReferences = (Vector) this.foreignKeyVectors.get(tableName);
        if (tableReferences == null) {
            tableReferences = new Vector();
            this.foreignKeyVectors.put(tableName, tableReferences);

        }
        if (!tableReferences.contains(reference)) {
            tableReferences.add(reference);
        }
    }
}
TOP

Related Classes of org.apache.ojb.broker.metadata.torque.TorqueForeignKeyGenerator

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.