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 }