blob: c74a789797459584a08310daf5fa260c39dc9643 [file] [log] [blame]
/*
* Copyright (c) 2010-2013, 2016 Eike Stepper (Loehne, Germany) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ibrahim Sallam - initial API and implementation
*/
package org.eclipse.emf.cdo.server.internal.objectivity.db;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.server.internal.objectivity.ObjectivityStoreAccessor;
import org.eclipse.emf.cdo.server.internal.objectivity.bundle.OM;
import org.eclipse.emf.cdo.server.internal.objectivity.clustering.ObjyPlacementManager;
import org.eclipse.emf.cdo.server.internal.objectivity.mapper.ITypeMapper;
import org.eclipse.emf.cdo.server.internal.objectivity.mapper.ObjyMapper;
import org.eclipse.emf.cdo.server.internal.objectivity.utils.OBJYCDOIDUtil;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import com.objy.as.app.Class_Object;
import com.objy.db.ObjyRuntimeException;
import com.objy.db.app.ooId;
import java.util.WeakHashMap;
public class ObjyObjectManager
{
private static final ContextTracer TRACER_DEBUG = new ContextTracer(OM.DEBUG, ObjyObjectManager.class);
// private static final ContextTracer TRACER_INFO = new ContextTracer(OM.INFO, ObjyObjectManager.class);
// private Map<Long, ObjyObject> idToObjyObjectMap = new ReferenceValueMap.Weak<Long, ObjyObject>();
private WeakHashMap<Long, ObjyObject> idToObjyObjectMap = new WeakHashMap<Long, ObjyObject>();
private ObjyPlacementManager globalPlacementManager = null;
public static int newObjCount = 0;
public static int newInternalObjCount = 0;
public static long getObjectTime = 0;
public static long updateObjectTime = 0;
public static long resourceCheckAndUpdateTime = 0;
public ObjyObjectManager(ObjyPlacementManager placementManager)
{
globalPlacementManager = placementManager;
}
public int sizeOfObjectMap()
{
return idToObjyObjectMap.size();
}
/**
*
*/
public ObjyObject newObject(EClass eClass, ooId nearObject)
{
if (nearObject == null)
{
// TODO - we might need to use annotation for placement.
nearObject = globalPlacementManager.getNearObject(null, null, eClass);
}
if (TRACER_DEBUG.isEnabled())
{
TRACER_DEBUG.trace("Create new object of type " + eClass.getName() + " near object " + (nearObject != null ? nearObject.getStoreString() : null));
}
Class_Object newClassObject = newClassObject(eClass, nearObject);
ObjyObject objyObject = new ObjyObject(newClassObject);
// idToObjyObjectMap.put(OBJYCDOIDUtil.getLong(objyObject.ooId()), objyObject);
if (TRACER_DEBUG.isEnabled())
{
newObjCount++;
}
return objyObject;
}
/**
* @param eClass
* @return
*/
// public Class_Object newClassObject(EClass eClass, ooId nearObject)
// {
// return newClassObject(eClass, nearObject/*, null*/);
// }
/**
* Creates an Objy 'Class_Object' from an eClass. This will construct a shell Class_Object in the store using the
* schema.
*/
private Class_Object newClassObject(EClass eClass, ooId nearObject/* , InitializeValue init */)
{
// we don create classes on the fly...
// TODO - can we pre-create using the model?
ObjyClass objyClass = ObjySchema.getOrCreate(eClass);
// System.out.println(">> Create new object of type " + eClass.getName() + " near object " + (nearObject != null ?
// nearObject
// .getStoreString() : null));
Class_Object newClassObject = Class_Object.new_persistent_object(objyClass.getASClass(), nearObject, false);
if (TRACER_DEBUG.isEnabled())
{
ObjyObjectManager.newInternalObjCount++;
}
// if (init != null)
// {
// init.init(newClassObject);
// }
// Initialize the object
for (EStructuralFeature feature : eClass.getEAllStructuralFeatures())
{
if (!(feature instanceof EAttribute || feature instanceof EReference) || !ObjyObject.isPersistent(feature))
{
continue;
}
ITypeMapper mapper = ObjyMapper.INSTANCE.getTypeMapper(feature);
if (mapper == null)
{
if (TRACER_DEBUG.isEnabled())
{
TRACER_DEBUG.trace("Can't find mapper for feature " + feature.getName());
}
continue;
}
// Class_Position attr = objyClass.resolve_position(feature.getName());
mapper.initialize(newClassObject, feature);
// TODO - verify the need for this (see ESessionImpl in the old code)
// if (init != null)
// {
// init.init(feature);
// }
}
return newClassObject;
}
/**
* return an ObjyObject based on the id passed. usually this is used for existing object when trying to modify them.
*/
public ObjyObject getObject(CDOID id)
{
if (id == null)
{
return null;
}
ooId oid = OBJYCDOIDUtil.getooId(id);
return getObject(oid);
}
/**
* return an ObjyObject based on the ooId passed.
*/
public ObjyObject getObject(ooId oid)
{
ObjyObject objyObject = null;
if (oid == null)
{
return objyObject;
}
// System.out.println("ObjyObjectManager.getObject_ooId("+oid.getStoreString()+")");
objyObject = idToObjyObjectMap.get(OBJYCDOIDUtil.getLong(oid));
if (objyObject == null)
{
try
{
objyObject = getObjectFromClassObject(Class_Object.class_object_from_oid(oid));
}
catch (ObjyRuntimeException ex)
{
ex.printStackTrace();
}
}
return objyObject;
}
/***
* The following are utility function that get the base attributes from the object.
*
* @param objyObject
* @return replaced by the ones in ObjyObject. public Object getEContainer(ObjyObject objyObject) { Class_Position
* position = objyObject.objyClass().resolve_position(ooBaseClass.ClassName_containerid); ooId oid = (ooId)
* SingleReferenceMapper.INSTANCE.getValue(objyObject, null, position, 0); return getObject(oid); } public
* Object getEResource(ObjyObject objyObject) { Class_Position position =
* objyObject.objyClass().resolve_position(ooBaseClass.ClassName_resourceid); ooId oid = (ooId)
* SingleReferenceMapper.INSTANCE.getValue(objyObject, null, position, 0); return getObject(oid); } public int
* getEContainingFeature(ObjyObject objyObject) { Class_Position position =
* objyObject.objyClass().resolve_position(ooBaseClass.ClassName_containerfeatureid); Integer value =
* (Integer)IntegerTypeMapper.INSTANCE.getValue(objyObject, null, position, 0); return value == null ? 0 :
* value; } public void setEContainer(ObjyObject objyObject, Object containerID) { //containerID =
* provider.convertToStore(ooObject, containerID); Class_Position position =
* objyObject.objyClass().resolve_position(ooBaseClass.ClassName_containerid);
* SingleReferenceMapper.INSTANCE.setValue(objyObject, null, position, 0, containerID); } public void
* setEResource(ObjyObject objyObject, Object resourceID) { //resourceID = provider.convertToStore(ooObject,
* resourceID); Class_Position position =
* objyObject.objyClass().resolve_position(ooBaseClass.ClassName_resourceid);
* SingleReferenceMapper.INSTANCE.setValue(objyObject, null, position, 0, resourceID); } public void
* setEContainingFeature(ObjyObject objyObject, int containerID) { Class_Position position =
* objyObject.objyClass().resolve_position(ooBaseClass.ClassName_containerfeatureid);
* IntegerTypeMapper.INSTANCE.setValue(objyObject, null, position, 0, containerID); }
*/
/**
* Construct an ObjyObject from an existing Class_Object and add it to the idToObjyObjectMap.
*
* @param classObject
* @return
*/
private ObjyObject getObjectFromClassObject(Class_Object classObject)
{
ObjyObject objyObject = new ObjyObject(classObject);
idToObjyObjectMap.put(OBJYCDOIDUtil.getLong(objyObject.ooId()), objyObject);
return objyObject;
}
/***
* TODO - Remove the eClass and just use the objyObject attributes to do the clean up.
*
* @param objyObject
*/
public void remove(ObjyObject objyObject)
{
if (TRACER_DEBUG.isEnabled())
{
TRACER_DEBUG.trace("ObjyObjectManager.delete(" + objyObject.ooId().getStoreString() + ")");
}
// //remove it from it's resource.
// Object resource = objyObject.getEResource();
// // locate the ObjyObject.
// ObjyObject resourceObject = this.getObject((ooId)resource);
synchronized (idToObjyObjectMap)
{
idToObjyObjectMap.remove(OBJYCDOIDUtil.getLong(objyObject.ooId()));
}
}
// we could've used the CDO copy revision technique, but it will be expensive
// to create the new copy over the Java/JNI boundaries, doing a low level
// copy is faster.
public ObjyObject copyRevision(ObjectivityStoreAccessor storeAccessor, ObjyObject objyObject)
{
if (TRACER_DEBUG.isEnabled())
{
TRACER_DEBUG.trace("ObjyObjectManager.copyRevision(" + objyObject.ooId().getStoreString() + ")");
}
EClass eClass = ObjySchema.getEClass(storeAccessor.getStore(), objyObject.objyClass());
ObjyObject newObjyRevision = objyObject.copy(eClass, this);
return newObjyRevision;
}
public ObjyPlacementManager getGlobalPlacementManager()
{
return globalPlacementManager;
}
}