blob: 53786bd5497d63a175e39a25b99b0dce288f56d9 [file] [log] [blame]
/*
* Copyright (c) 2010-2012, 2015 Eike Stepper (Berlin, 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:
* Simon McDuff - initial API and implementation
*/
package org.eclipse.emf.cdo.server.internal.objectivity.utils;
import org.eclipse.emf.cdo.server.internal.objectivity.bundle.OM;
import org.eclipse.emf.cdo.server.internal.objectivity.db.ObjyObject;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import com.objy.db.FetchCompletedWithErrors;
import com.objy.db.ObjyRuntimeException;
import com.objy.db.app.Session;
import com.objy.db.app.oo;
import com.objy.db.app.ooContObj;
import com.objy.db.app.ooObj;
import com.objy.db.iapp.ActivateInfo;
import com.objy.db.iapp.FetchErrorInfo;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Vector;
/**
* @author Simon McDuff To change the template for this generated type comment go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
public class SmartLock
{
// private static final ContextTracer TRACER_DEBUG = new ContextTracer(OM.DEBUG, SmartLock.class);
private static final ContextTracer TRACER_INFO = new ContextTracer(OM.INFO, SmartLock.class);
private static final ContextTracer TRACER_ERROR = new ContextTracer(OM.ERROR, SmartLock.class);
public static boolean lock(ObjyObject objyObject)
{
ooObj objectToLock = (ooObj)Session.getCurrent().getFD().objectFrom(objyObject.ooId());
if (!objectToLock.isPersistent())
{
return false;
}
ooContObj container = null;
if (objectToLock instanceof ooContObj)
{
container = (ooContObj)objectToLock;
}
else
{
container = objectToLock.getContainer();
}
return lock(container);
}
public static boolean readLock(ooContObj container)
{
container.fetch();
if (container.isUpdated())
{
container.refresh(oo.READ);
return true;
}
try
{
container.lock(oo.READ);
}
catch (Exception e)
{
// In MROW Mode, an Exception occur if we try to upgrade the lock from read to write when the container is
// Locked by someone else.
container.refresh(oo.READ);
}
return false;
}
public static boolean lock(ooContObj container)
{
container.fetch();
if (container.isUpdated())
{
container.refresh(oo.WRITE);
return true;
}
try
{
container.lock(oo.WRITE);
}
catch (Exception e)
{
// In MROW Mode, an Exception occur if we try to upgrade the lock from read to write when the container is
// Locked by someone else.
container.refresh(oo.WRITE);
}
return false;
}
public static boolean unlock(ooObj objectToLock)
{
// ooContObj container = objectToLock.getContainer();
Session.getCurrent().checkpoint(oo.DOWNGRADE_ALL);
return false;
}
/**
* This should replace ooObj.activate. We do not need to call super.activate because we implemented the code in
* ooObj.activate in here. This safeActivate will refresh container in case of errors. >> ... Msg: objref member: test
* with oid: #26-387-1-2 not found or accessible
*
* @param object
* @param fcweEx
*/
@SuppressWarnings("unchecked")
public static void safeActivate(ooObj object, ActivateInfo fcweEx)
{
if (!fcweEx.hasFetchErrors())
{
return;
}
if (TRACER_INFO.isEnabled())
{
TRACER_INFO.trace(" >> Object: " + object.getOid().getStoreString() + " Fetch with errors");
}
Vector<Object> errors = fcweEx.getFetchErrors();
// Make sure there are fetch-error information objects
if (errors != null)
{
// Get Enumeration from Vector
Enumeration<Object> errs = errors.elements();
FetchErrorInfo feInfo = null;
HashSet<Object> hashSet = new HashSet<Object>();
hashSet.add(object.getContainer());
while (errs.hasMoreElements())
{
feInfo = (FetchErrorInfo)errs.nextElement();
TRACER_INFO.trace(" >> ... fieldName: " + feInfo.getFieldName());
TRACER_INFO.trace(" >> ... Msg: " + feInfo.getErrorMessage());
String needFetchingOID = feInfo.getOid().getStoreString();
TRACER_INFO.trace(" >> ... OID: " + needFetchingOID);
try
{
TRACER_INFO.trace(" >> Trying to refetch the object....");
String contID = "#" + feInfo.getOid().getDB() + "-" + feInfo.getOid().getOC() + "-" + "1-1";
TRACER_INFO.trace("contID: " + contID);
ooContObj tempCont = (ooContObj)Session.getCurrent().getFD().objectFrom(contID);
if (!hashSet.contains(tempCont))
{
hashSet.add(tempCont);
}
}
catch (ObjyRuntimeException ex)
{
TRACER_ERROR.trace("FATAL", ex);
}
}
Iterator<Object> itrCont = hashSet.iterator();
int numCont = 0;
while (itrCont.hasNext())
{
ooContObj cont = (ooContObj)itrCont.next();
if (cont.isUpdated())
{
TRACER_INFO.trace("RECOVER : REFRESH CONT " + cont.getOid().getStoreString());
cont.refresh(oo.READ);
numCont++;
}
}
if (numCont != 0)
{
// End while more fetch-error information objects
object.markFetchRequired();
object.fetch();
}
else
{
throw new FetchCompletedWithErrors("Fetch completed but errors occurred", object, fcweEx.getFetchErrors());
}
}
}
}