Package org.jpox.store.rdbms.key

Source Code of org.jpox.store.rdbms.key.ForeignKey$FKAction

/**********************************************************************
Copyright (c) 2003 Mike Martin (TJDO) and others. All rights reserved.
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.

Contributors:
2003 Andy Jefferson - equality operator
2004 Andy Jefferson - deleteAction, updateAction, MetaData interface
    ...
**********************************************************************/
package org.jpox.store.rdbms.key;

import java.util.ArrayList;

import org.jpox.exceptions.JPOXException;
import org.jpox.metadata.ForeignKeyAction;
import org.jpox.metadata.ForeignKeyMetaData;
import org.jpox.store.mapped.DatastoreAdapter;
import org.jpox.store.mapped.DatastoreClass;
import org.jpox.store.mapped.DatastoreField;
import org.jpox.store.mapped.mapping.JavaTypeMapping;
import org.jpox.store.rdbms.adapter.RDBMSAdapter;

/**
* Representation of a foreign key to another table.
*
* @version $Revision: 1.15 $
**/
public class ForeignKey extends Key
{
    /** Constant representing that we should cascade the action. */
    public static final FKAction CASCADE_ACTION = new FKAction(1, "CASCADE");
   
    /** Constant representing that we should restrict the action. */
    public static final FKAction RESTRICT_ACTION = new FKAction(2, "RESTRICT");
   
    /** Constant representing that we should null the foreign key */
    public static final FKAction NULL_ACTION = new FKAction(3, "SET NULL");
   
    /** Constant representing that we should set the FK to default value. */
    public static final FKAction DEFAULT_ACTION = new FKAction(4, "SET DEFAULT");
   
    /** Inner class representing an action on the FK. */
    public static class FKAction
    {
        int type;
        String keyword;
       
        /**
         * Constructor
         * @param type the type of this action
         * @param keyword the keyword (name) of this action
         */
        public FKAction(int type, String keyword)
        {
            this.type = type;
            this.keyword = keyword;
        }
       
        /**
         * Accessor for the type
         * @return the type
         */
        public int getType()
        {
            return type;
        }
       
        /**
         * Accessor for the keyword
         * @return the keyword
         */
        public String getKeyword()
        {
            return keyword;
        }
    }
   
    private boolean initiallyDeferred;
    private DatastoreClass refTable;
    private DatastoreAdapter dba;
   
    /** Action to perform on update */
    private FKAction updateAction;
   
    /** Action to perform on delete */
    private FKAction deleteAction;

    private ArrayList refColumns = new ArrayList();

    /**
     * Constructor.
     * @param initiallyDeferred Whether the constraints are deferred
     */
    public ForeignKey(boolean initiallyDeferred)
    {
        super(null);

        this.initiallyDeferred = initiallyDeferred;
        this.refTable = null;
        this.dba = null;
    }

    /**
     * Constructor.
     * @param mapping The type mapping for this Foreign-key field
     * @param dba Datastore adapter
     * @param refTable Referred to table
     * @param initiallyDeferred Whether they are deferred
     */
    public ForeignKey(JavaTypeMapping mapping, DatastoreAdapter dba, DatastoreClass refTable, boolean initiallyDeferred)
    {
        super(mapping.getDatastoreContainer());
        this.initiallyDeferred = initiallyDeferred;
        this.refTable = refTable;
        this.dba = dba;

        if (refTable.getIDMapping() == null)
        {
            throw new JPOXException("ForeignKey ID mapping is not initilized for "+mapping+". Table referenced: " + refTable.toString()).setFatal();
        }

        for (int i=0; i<refTable.getIDMapping().getNumberOfDatastoreFields(); i++)
        {
          setDatastoreField(i, mapping.getDataStoreMapping(i).getDatastoreField(), refTable.getIDMapping().getDataStoreMapping(i).getDatastoreField());
        }
    }
   
    /**
     * Convenience mutator for setting the specification based on MetaData
     * @param fkmd ForeignKey MetaData definition
     */
    public void setForMetaData(ForeignKeyMetaData fkmd)
    {
        if (fkmd == null)
        {
            return;
        }
       
        if (fkmd.getName() != null)
        {
            setName(fkmd.getName());
        }

        ForeignKeyAction deleteAction = fkmd.getDeleteAction();
        if (deleteAction != null)
        {
            if (deleteAction.equals(ForeignKeyAction.CASCADE))
            {
                setDeleteAction(ForeignKey.CASCADE_ACTION);
            }
            else if (deleteAction.equals(ForeignKeyAction.RESTRICT))
            {
                setDeleteAction(ForeignKey.RESTRICT_ACTION);
            }
            else if (deleteAction.equals(ForeignKeyAction.NULL))
            {
                setDeleteAction(ForeignKey.NULL_ACTION);
            }
            else if (deleteAction.equals(ForeignKeyAction.DEFAULT))
            {
                setDeleteAction(ForeignKey.DEFAULT_ACTION);
            }
        }

        ForeignKeyAction updateAction = fkmd.getUpdateAction();
        if (updateAction != null)
        {
            if (updateAction.equals(ForeignKeyAction.CASCADE))
            {
                setUpdateAction(ForeignKey.CASCADE_ACTION);
            }
            else if (updateAction.equals(ForeignKeyAction.RESTRICT))
            {
                setUpdateAction(ForeignKey.RESTRICT_ACTION);
            }
            else if (updateAction.equals(ForeignKeyAction.NULL))
            {
                setUpdateAction(ForeignKey.NULL_ACTION);
            }
            else if (updateAction.equals(ForeignKeyAction.DEFAULT))
            {
                setUpdateAction(ForeignKey.DEFAULT_ACTION);
            }
        }

        if (fkmd.isDeferred())
        {
            initiallyDeferred = true;
        }
    }

    /**
     * Accessor for deleteAction.
     * @return Returns the deleteAction.
     */
    public FKAction getDeleteAction()
    {
        return deleteAction;
    }
   
    /**
     * Mutator for deleteAction.
     * @param deleteAction The deleteAction to set.
     */
    public void setDeleteAction(FKAction deleteAction)
    {
        this.deleteAction = deleteAction;
    }
   
    /**
     * Accessor for updateAction.
     * @return Returns the updateAction.
     */
    public FKAction getUpdateAction()
    {
        return updateAction;
    }
   
    /**
     * Mutator for updateAction.
     * @param updateAction The updateAction to set.
     */
    public void setUpdateAction(FKAction updateAction)
    {
        this.updateAction = updateAction;
    }

    /**
     * Method to add a Column.
     * @param col The column to add
     * @param refCol The column to reference
     **/
    public void addDatastoreField(DatastoreField col, DatastoreField refCol)
    {
        setDatastoreField(columns.size(), col, refCol);
    }

    /**
     * Set the datastore field for the specified position <code>seq</code>
     * @param seq the specified position
     * @param col the datastore field
     * @param refCol the foreign (refered) datastore field
     */
    public void setDatastoreField(int seq, DatastoreField col, DatastoreField refCol)
    {
        if (table == null)
        {
            table = col.getDatastoreContainerObject();
            refTable = (DatastoreClass) refCol.getDatastoreContainerObject();
            dba = table.getStoreManager().getDatastoreAdapter();
        }
        else
        {
            if (!table.equals(col.getDatastoreContainerObject()))
            {
                throw new JPOXException("Cannot add " + col + " as FK column for " + table).setFatal();
            }
            if (!refTable.equals(refCol.getDatastoreContainerObject()))
            {
                throw new JPOXException("Cannot add " + refCol + " as referenced FK column for " + refTable).setFatal();
            }
        }

        setMinSize(columns, seq + 1);
        setMinSize(refColumns, seq + 1);

        columns.set(seq, col);
        refColumns.set(seq, refCol);
    }

    /**
     * Hashcode operator.
     * @return The hashcode
     **/
    public int hashCode()
    {
        return super.hashCode() ^ refColumns.hashCode();
    }

    /**
     * Equality operator.
     * @param obj Object to compare against
     * @return Whether they are equal.
     **/
    public boolean equals(Object obj)
    {
        if (obj == this)
        {
            return true;
        }
        if (!(obj instanceof ForeignKey))
        {
            return false;
        }

        ForeignKey fk = (ForeignKey)obj;
        if (!refColumns.equals(fk.refColumns))
        {
            return false;
        }
       
        // TODO Add update-action, delete-action here

        return super.equals(obj);
    }

    /**
     * Stringify method. Generates the foreign key statement ready for use in an SQL call.
     * @return String version of this object.
     **/
    public String toString()
    {
        StringBuffer s = new StringBuffer("FOREIGN KEY ");
        s.append(getColumnList(columns));

        // Referenced table
        if (refTable != null)
        {
            // Include the referenced column list because some RDBMS require it (e.g MySQL)
            s.append(" REFERENCES ");
            s.append(refTable.toString());
            s.append(" ").append(getColumnList(refColumns));
        }

        // Delete action
        if (deleteAction != null && ((RDBMSAdapter)dba).supportsForeignKeyDeleteAction(deleteAction))
        {
             s.append(" ON DELETE ").append(deleteAction.getKeyword());
        }

        // Update action
        if (updateAction != null && ((RDBMSAdapter)dba).supportsForeignKeyUpdateAction(updateAction))
        {
            s.append(" ON UPDATE ").append(updateAction.getKeyword());
        }

        // Deferral of constraints
        if (initiallyDeferred && ((RDBMSAdapter)dba).supportsDeferredConstraints())
        {
            s.append(" INITIALLY DEFERRED");
        }
       
        s.append(" ");

        return s.toString();
    }
}
TOP

Related Classes of org.jpox.store.rdbms.key.ForeignKey$FKAction

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.