Package org.jpox.store.mapped.mapping

Source Code of org.jpox.store.mapped.mapping.ReferenceMapping

/**********************************************************************
Copyright (c) 2005 Andy Jefferson 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:
2007 Andy Jefferson - implement RelationMappingCallbacks
    ...
***********************************************************************/
package org.jpox.store.mapped.mapping;

import org.jpox.ClassLoaderResolver;
import org.jpox.StateManager;
import org.jpox.metadata.AbstractClassMetaData;
import org.jpox.metadata.AbstractMemberMetaData;
import org.jpox.metadata.FieldRole;
import org.jpox.metadata.InheritanceStrategy;
import org.jpox.metadata.MetaDataUtils;
import org.jpox.store.mapped.DatastoreAdapter;
import org.jpox.store.mapped.DatastoreContainerObject;
import org.jpox.store.mapped.MappedStoreManager;
import org.jpox.store.mapped.expression.LogicSetExpression;
import org.jpox.store.mapped.expression.ObjectLiteral;
import org.jpox.store.mapped.expression.QueryExpression;
import org.jpox.store.mapped.expression.ReferenceExpression;
import org.jpox.store.mapped.expression.ScalarExpression;
import org.jpox.util.JPOXLogger;

/**
* Mapping for a reference type.
* This can be used for things like interfaces, or Object which are simply a reference to
* some specific (PersistenceCapable) class. All fields of this type have a list of
* possible "implementations" of the reference type. A column is created for each possible
* implementation of the reference as a FK to the implementation table.
*
* @version $Revision: 1.33 $
*/
public abstract class ReferenceMapping extends MultiMapping implements MappingCallbacks
{
    /**
     * Initialize this JavaTypeMapping with the given DatastoreAdapter for
     * the given FieldMetaData.
     * 
     * @param dba The Datastore Adapter that this Mapping should use.
     * @param fmd FieldMetaData for the field to be mapped (if any)
     * @param container The datastore container storing this mapping (if any)
     * @param clr the ClassLoaderResolver
     */
    public void initialize(DatastoreAdapter dba, AbstractMemberMetaData fmd, DatastoreContainerObject container, ClassLoaderResolver clr)
    {
    super.initialize(dba, fmd, container, clr);
        createColumns(datastoreContainer, fmd, clr);
    }

    /**
     * Convenience method to create a column for each implementation type of this reference.
     * @param datastoreContainer Table to use
     * @param fmd MetaData for the field
     * @param clr The ClassLoaderResolver
     */
    protected void createColumns(DatastoreContainerObject datastoreContainer, AbstractMemberMetaData fmd, ClassLoaderResolver clr)
    {
        // Create columns for each possible implementation type of the reference field
        MappedStoreManager storeMgr = datastoreContainer.getStoreManager();
        if (fmd.getMappedBy() == null)
        {
            datastoreContainer.getStoreManager().createDatastoreColumnsForReferenceField(this,
                datastoreContainer, fmd, clr, fmd.isEmbedded() || fmd.getElementMetaData() != null);
        }
        else
        {
            // Either one end of a 1-1 relation, or the N end of a N-1
            AbstractClassMetaData refCmd = storeMgr.getOMFContext().getMetaDataManager().getMetaDataForInterface(fmd.getType(), clr);
            JavaTypeMapping referenceMapping = null;
            if (refCmd != null && refCmd.getInheritanceMetaData().getStrategyValue() == InheritanceStrategy.SUBCLASS_TABLE)
            {
                // TODO Is this block actually reachable ? Would we specify "inheritance" under "interface" elements?
                // Find the actual tables storing the other end (can be multiple subclasses)
                AbstractClassMetaData[] cmds = storeMgr.getClassesManagingTableForClass(refCmd, clr);
                if (cmds != null && cmds.length > 0)
                {
                    if (cmds.length > 1)
                    {
                        JPOXLogger.PERSISTENCE.warn("Field " + fmd.getFullFieldName() + " represents either a 1-1 relation, or a N-1 relation " +
                            "where the other end uses \"subclass-table\" inheritance strategy and more than 1 subclasses with a table. " +
                        "This is not fully supported by JPOX");
                    }
                }
                else
                {
                    // No subclasses of the class using "subclasses-table" so no mapping!
                    // TODO Throw an exception ?
                    return;
                }
                // TODO We need a mapping for each of the possible subclass tables
                referenceMapping = storeMgr.getDatastoreClass(cmds[0].getFullClassName(), clr).getIDMapping();
            }
            else
            {
                String[] implTypes = MetaDataUtils.getInstance().getImplementationNamesForReferenceField(fmd,
                    FieldRole.ROLE_FIELD, clr);
                for (int j=0; j<implTypes.length; j++)
                {
                    referenceMapping = storeMgr.getDatastoreClass(implTypes[j], clr).getIDMapping();
                    JavaTypeMapping mapping = dba.getMapping(clr.classForName(implTypes[j]), storeMgr);
                    mapping.setReferenceMapping(referenceMapping);
                    this.addJavaTypeMapping(mapping);
                }
            }
        }
    }

    /* (non-Javadoc)
     * @see org.jpox.store.mapping.JavaTypeMapping#getJavaType()
     */
    public Class getJavaType()
    {
        return null;
    }

    /* (non-Javadoc)
     * @see org.jpox.store.mapping.Mapping#getSampleValue()
     */
    public Object getSampleValue(ClassLoaderResolver clr)
    {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    // ---------------------------------- JDOQL Query Methods -------------------------------------

    /* (non-Javadoc)
     * @see org.jpox.store.mapping.Mapping#newLiteral(org.jpox.store.QueryStatement, java.lang.Object)
     */
    public ScalarExpression newLiteral(QueryExpression qs, Object value)
    {
        ScalarExpression expr = new ObjectLiteral(qs, this, value, value.getClass().getName());
        return expr;
    }

    public ScalarExpression newScalarExpression(QueryExpression qs, LogicSetExpression te)
    {
        ScalarExpression expr = new ReferenceExpression(qs, this, te);
        return expr;
    }

    // -------------------------- MappingCallbacks methods ----------------------------

    /**
     * Method executed just after a fetch of the owning object, allowing any necessary action
     * to this field and the object stored in it.
     * @param sm StateManager for the owner.
     */
    public void postFetch(StateManager sm)
    {
    }

    /**
     * Method executed just after the insert of the owning object, allowing any necessary action
     * to this field and the object stored in it.
     * @param sm StateManager for the owner
     */
    public void postInsert(StateManager sm)
    {
    }

    /**
     * Method executed just afer any update of the owning object, allowing any necessary action
     * to this field and the object stored in it.
     * @param sm StateManager for the owner
     */
    public void postUpdate(StateManager sm)
    {
    }

    /**
     * Method executed just before the owning object is deleted, allowing tidying up of any
     * relation information.
     * @param sm StateManager for the owner
     */
    public void preDelete(StateManager sm)
    {
        boolean isDependentElement = fmd.isDependent();
        if (!isDependentElement)
        {
            // Not dependent so do nothing, or should we null here ?
            return;
        }

        // Loop through all implementations
        for (int i=0;i<javaTypeMappings.length;i++)
        {
            final JavaTypeMapping mapping = javaTypeMappings[i];
            if (mapping instanceof PersistenceCapableMapping)
            {
                // makes sure field is loaded
                int fieldNumber = getFieldMetaData().getAbsoluteFieldNumber();
                sm.getObjectManager().getApiAdapter().isLoaded(sm, fieldNumber);
                Object pc = sm.provideField(fieldNumber);
                if (pc != null)
                {
                    // Null out the FK in the datastore using a direct update (since we are deleting)
                    sm.replaceField(fieldNumber, null, true);
                    sm.getStoreManager().getPersistenceHandler().updateObject(sm, new int[]{fieldNumber});

                    // delete object
                    sm.getObjectManager().deleteObjectInternal(pc);
                }
            }
        }
    }
}
TOP

Related Classes of org.jpox.store.mapped.mapping.ReferenceMapping

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.