Package org.apache.ddlutils.model

Source Code of org.apache.ddlutils.model.ForeignKey

package org.apache.ddlutils.model;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 java.util.HashSet;
import java.util.Iterator;

import org.apache.commons.collections.set.ListOrderedSet;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
* Represents a database foreign key.
*
* @version $Revision: 504014 $
*/
public class ForeignKey implements Cloneable
{
    /** The name of the foreign key, may be <code>null</code>. */
    private String _name;
    /** The target table. */
    private Table _foreignTable;
    /** The name of the foreign table. */
    private String _foreignTableName;
    /** The references between local and remote columns. */
    private ListOrderedSet _references = new ListOrderedSet();
    /** Whether this foreign key has an associated auto-generated index. */
    private boolean _autoIndexPresent;

    /**
     * Creates a new foreign key object that has no name.
     */
    public ForeignKey()
    {
        this(null);
    }
   
    /**
     * Creates a new foreign key object.
     *
     * @param name The name of the foreign key
     */
    public ForeignKey(String name)
    {
        _name = name;
    }

    /**
     * Returns the name of this foreign key.
     *
     * @return The name
     */
    public String getName()
    {
        return _name;
    }

    /**
     * Sets the name of this foreign key.
     *
     * @param name The name
     */
    public void setName(String name)
    {
        _name = name;
    }

    /**
     * Returns the foreign table.
     *
     * @return The foreign table
     */
    public Table getForeignTable()
    {
        return _foreignTable;
    }

    /**
     * Sets the foreign table.
     *
     * @param foreignTable The foreign table
     */
    public void setForeignTable(Table foreignTable)
    {
        _foreignTable     = foreignTable;
        _foreignTableName = (foreignTable == null ? null : foreignTable.getName());
    }

    /**
     * Returns the name of the foreign table.
     *
     * @return The table name
     */
    public String getForeignTableName()
    {
        return _foreignTableName;
    }
   
    /**
     * Sets the name of the foreign table. Please note that you should not use this method
     * when manually constructing or manipulating the database model. Rather utilize the
     * {@link #setForeignTable(Table)} method.
     *
     * @param foreignTableName The table name
     */
    public void setForeignTableName(String foreignTableName)
    {
        if ((_foreignTable != null) && !_foreignTable.getName().equals(foreignTableName))
        {
            _foreignTable = null;
        }
        _foreignTableName = foreignTableName;
    }

    /**
     * Returns the number of references.
     *
     * @return The number of references
     */
    public int getReferenceCount()
    {
        return _references.size();
    }

    /**
     * Returns the indicated reference.
     *
     * @param idx The index
     * @return The reference
     */
    public Reference getReference(int idx)
    {
        return (Reference)_references.get(idx);
    }

    /**
     * Returns the references.
     *
     * @return The references
     */
    public Reference[] getReferences()
    {
        return (Reference[])_references.toArray(new Reference[_references.size()]);
    }

    /**
     * Returns the first reference if it exists.
     *
     * @return The first reference
     */
    public Reference getFirstReference()
    {
        return (Reference)(_references.isEmpty() ? null : _references.get(0));
    }

    /**
     * Adds a reference, ie. a mapping between a local column (in the table that owns this foreign key)
     * and a remote column.
     *
     * @param reference The reference to add
     */
    public void addReference(Reference reference)
    {
        if (reference != null)
        {
            for (int idx = 0; idx < _references.size(); idx++)
            {
                Reference curRef = getReference(idx);

                if (curRef.getSequenceValue() > reference.getSequenceValue())
                {
                    _references.add(idx, reference);
                    return;
                }
            }
            _references.add(reference);
        }
    }

    /**
     * Removes the given reference.
     *
     * @param reference The reference to remove
     */
    public void removeReference(Reference reference)
    {
        if (reference != null)
        {
            _references.remove(reference);
        }
    }

    /**
     * Removes the indicated reference.
     *
     * @param idx The index of the reference to remove
     */
    public void removeReference(int idx)
    {
        _references.remove(idx);
    }

    /**
     * Determines whether this foreign key uses the given column as a local
     * column in a reference.
     *
     * @param column The column to check
     * @return <code>true</code> if a reference uses the column as a local
     *         column
     */
    public boolean hasLocalColumn(Column column)
    {
        for (int idx = 0; idx < getReferenceCount(); idx++)
        {
            if (column.equals(getReference(idx).getLocalColumn()))
            {
                return true;
            }
        }
        return false;
    }

    /**
     * Determines whether this foreign key uses the given column as a foreign
     * column in a reference.
     *
     * @param column The column to check
     * @return <code>true</code> if a reference uses the column as a foreign
     *         column
     */
    public boolean hasForeignColumn(Column column)
    {
        for (int idx = 0; idx < getReferenceCount(); idx++)
        {
            if (column.equals(getReference(idx).getForeignColumn()))
            {
                return true;
            }
        }
        return false;
    }
   
    /**
     * Determines whether this foreign key has an auto-generated associated index.
     *
     * @return <code>true</code> if an auto-generated index exists
     */
    public boolean isAutoIndexPresent()
    {
        return _autoIndexPresent;
    }

    /**
     * Specifies whether this foreign key has an auto-generated associated index.
     *
     * @param autoIndexPresent <code>true</code> if an auto-generated index exists
     */
    public void setAutoIndexPresent(boolean autoIndexPresent)
    {
        _autoIndexPresent = autoIndexPresent;
    }

    /**
     * {@inheritDoc}
     */
    public Object clone() throws CloneNotSupportedException
    {
        ForeignKey result = (ForeignKey)super.clone();

        result._name             = _name;
        result._foreignTableName = _foreignTableName;
        result._references       = new ListOrderedSet();

        for (Iterator it = _references.iterator(); it.hasNext();)
        {
            result._references.add(((Reference)it.next()).clone());
        }

        return result;
    }

    /**
     * {@inheritDoc}
     */
    public boolean equals(Object obj)
    {
        if (obj instanceof ForeignKey)
        {
            ForeignKey otherFk = (ForeignKey)obj;

            // Note that this compares case sensitive
            // Note also that we can simply compare the references regardless of their order
            // (which is irrelevant for fks) because they are contained in a set
            EqualsBuilder builder = new EqualsBuilder();

            if ((_name != null) && (_name.length() > 0) && (otherFk._name != null) && (otherFk._name.length() > 0))
            {
                builder.append(_name, otherFk._name);
            }
            return builder.append(_foreignTableName, otherFk._foreignTableName)
                          .append(_references,       otherFk._references)
                          .isEquals();
        }
        else
        {
            return false;
        }
    }

    /**
     * Compares this foreign key to the given one while ignoring the case of identifiers.
     *
     * @param otherFk The other foreign key
     * @return <code>true</code> if this foreign key is equal (ignoring case) to the given one
     */
    public boolean equalsIgnoreCase(ForeignKey otherFk)
    {
        boolean checkName = (_name != null) && (_name.length() > 0) &&
                            (otherFk._name != null) && (otherFk._name.length() > 0);

        if ((!checkName || _name.equalsIgnoreCase(otherFk._name)) &&
            _foreignTableName.equalsIgnoreCase(otherFk._foreignTableName))
        {
            HashSet otherRefs = new HashSet();

            otherRefs.addAll(otherFk._references);
            for (Iterator it = _references.iterator(); it.hasNext();)
            {
                Reference curLocalRef = (Reference)it.next();
                boolean   found       = false;

                for (Iterator otherIt = otherRefs.iterator(); otherIt.hasNext();)
                {
                    Reference curOtherRef = (Reference)otherIt.next();

                    if (curLocalRef.equalsIgnoreCase(curOtherRef))
                    {
                        otherIt.remove();
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    return false;
                }
            }
            return otherRefs.isEmpty();
        }
        else
        {
            return false;
        }
    }

    /**
     * {@inheritDoc}
     */
    public int hashCode()
    {
        return new HashCodeBuilder(17, 37).append(_name)
                                          .append(_foreignTableName)
                                          .append(_references)
                                          .toHashCode();
    }

    /**
     * {@inheritDoc}
     */
    public String toString()
    {
        StringBuffer result = new StringBuffer();

        result.append("Foreign key [");
        if ((getName() != null) && (getName().length() > 0))
        {
            result.append("name=");
            result.append(getName());
            result.append("; ");
        }
        result.append("foreign table=");
        result.append(getForeignTableName());
        result.append("; ");
        result.append(getReferenceCount());
        result.append(" references]");

        return result.toString();
    }

    /**
     * Returns a verbose string representation of this foreign key.
     *
     * @return The string representation
     */
    public String toVerboseString()
    {
        StringBuffer result = new StringBuffer();

        result.append("ForeignK ky [");
        if ((getName() != null) && (getName().length() > 0))
        {
            result.append("name=");
            result.append(getName());
            result.append("; ");
        }
        result.append("foreign table=");
        result.append(getForeignTableName());
        result.append("] references:");
        for (int idx = 0; idx < getReferenceCount(); idx++)
        {
            result.append(" ");
            result.append(getReference(idx).toString());
        }

        return result.toString();
    }
}
TOP

Related Classes of org.apache.ddlutils.model.ForeignKey

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.