001    /*
002     * Cumulus4j - Securing your data in the cloud - http://cumulus4j.org
003     * Copyright (C) 2011 NightLabs Consulting GmbH
004     *
005     * This program is free software: you can redistribute it and/or modify
006     * it under the terms of the GNU Affero General Public License as
007     * published by the Free Software Foundation, either version 3 of the
008     * License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     * GNU Affero General Public License for more details.
014     *
015     * You should have received a copy of the GNU Affero General Public License
016     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017     */
018    package org.cumulus4j.store;
019    
020    import javax.jdo.PersistenceManager;
021    
022    import org.cumulus4j.store.model.ClassMeta;
023    import org.cumulus4j.store.model.DataEntry;
024    import org.cumulus4j.store.model.ObjectContainer;
025    import org.datanucleus.identity.IdentityUtils;
026    import org.datanucleus.metadata.AbstractClassMetaData;
027    import org.datanucleus.store.ExecutionContext;
028    
029    /**
030     * Helper class for replacing object-references when storing a 1-1- or 1-n- or m-n-relationship
031     * inside an {@link ObjectContainer}.
032     *
033     * @author Marco หงุ่ยตระกูล-Schulze - marco at nightlabs dot de
034     */
035    public final class ObjectContainerHelper
036    {
037            /**
038             * If <code>false</code>, store object-ID in {@link ObjectContainer}.
039             * If <code>true</code>, store {@link DataEntry#getDataEntryID() dataEntryID} in {@link ObjectContainer}.
040             */
041            private static final boolean USE_DATA_ENTRY_ID = true;
042    
043            private ObjectContainerHelper() { }
044    
045            @SuppressWarnings("unused")
046            public static Object entityToReference(ExecutionContext ec, PersistenceManager pmData, Object entity)
047            {
048                    Cumulus4jStoreManager storeManager = (Cumulus4jStoreManager) ec.getStoreManager();
049                    Object objectID = ec.getApiAdapter().getIdForObject(entity);
050                    if (objectID == null)
051                            throw new IllegalStateException("executionContext.getApiAdapter().getIdForObject(entity) returned null for " + entity);
052    
053                    storeManager.setClassNameForObjectID(objectID, entity.getClass().getName());
054    
055                    if (USE_DATA_ENTRY_ID) {
056                            ClassMeta classMeta = storeManager.getClassMeta(ec, entity.getClass());
057                            return DataEntry.getDataEntryID(pmData, classMeta, objectID.toString());
058                    }
059    
060                    return objectID;
061            }
062    
063            @SuppressWarnings("unused")
064            public static Object referenceToEntity(ExecutionContext ec, PersistenceManager pmData, Object reference)
065            {
066                    if (reference == null)
067                            return null;
068    
069                    if (USE_DATA_ENTRY_ID) {
070                            DataEntry dataEntry = DataEntry.getDataEntry(pmData, ((Long)reference).longValue());
071                            AbstractClassMetaData cmd = dataEntry.getClassMeta().getDataNucleusClassMetaData(ec);
072                            return IdentityUtils.getObjectFromIdString(dataEntry.getObjectID(), cmd, ec, true);
073                    }
074    
075                    return ec.findObject(reference, true, true, null);
076            }
077    
078            @SuppressWarnings("unused")
079            public static Long referenceToDataEntryID(ExecutionContext ec, PersistenceManager pmData, Object reference)
080            {
081                    if (reference == null)
082                            return null;
083    
084                    if (USE_DATA_ENTRY_ID)
085                            return (Long)reference;
086    
087                    Cumulus4jStoreManager storeManager = (Cumulus4jStoreManager) ec.getStoreManager();
088                    String clazzName = storeManager.getClassNameForObjectID(reference, ec.getClassLoaderResolver(), ec);
089                    Class<?> clazz = ec.getClassLoaderResolver().classForName(clazzName);
090                    ClassMeta classMeta = storeManager.getClassMeta(ec, clazz);
091                    return DataEntry.getDataEntryID(pmData, classMeta, reference.toString());
092            }
093    }