/*
* Fenix Framework, a framework to develop Java Enterprise Applications.
*
* Copyright (C) 2013 Fenix Framework Team and/or its affiliates and other contributors as indicated by the @author tags.
*
* This file is part of the Fenix Framework. Read the file COPYRIGHT.TXT for more copyright and licensing information.
*/
package pt.ist.fenixframework.backend.jvstm;
import java.lang.reflect.Field;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pt.ist.fenixframework.backend.jvstm.pstm.DomainClassInfo;
import pt.ist.fenixframework.backend.jvstm.pstm.VersionedSubject;
import pt.ist.fenixframework.core.AbstractDomainObjectAdapter;
import pt.ist.fenixframework.core.DomainObjectAllocator;
import pt.ist.fenixframework.core.SharedIdentityMap;
public abstract class JVSTMDomainObject extends AbstractDomainObjectAdapter {
private static final Logger logger = LoggerFactory.getLogger(JVSTMDomainObject.class);
// this should be final, but the ensureOid and restoreOid methods prevent it
private long oid;
// We need to have the default constructor, because we've added the allocate-instance constructor
protected JVSTMDomainObject() {
super(); // top-level constructor will invoke ensureOid()
}
protected JVSTMDomainObject(DomainObjectAllocator.OID oid) {
super(oid);
this.oid = (Long) oid.oid;
}
@Override
protected void ensureOid() {
try {
// find successive ids until one is available
while (true) {
this.oid = DomainClassInfo.getNextOidFor(this.getClass());
Object cached = SharedIdentityMap.getCache().cache(this);
if (cached == this) {
// break the loop once we got this instance cached
return;
}
if (logger.isDebugEnabled()) {
logger.debug("Another object was already cached with the same key as this new object: {}",
Long.toHexString(oid));
}
}
} catch (Exception e) {
logger.debug("Exception in ensureOid:", e);
throw new UnableToDetermineIdException(e);
}
}
// dealing with domain object identifiers
@Override
public Long getOid() {
return this.oid;
}
@Override
public final String getExternalId() {
return Long.toHexString(this.oid);
// return String.valueOf(this.oid);
}
public jvstm.VBoxBody addNewVersion(String attrName, int txNumber) {
VersionedSubject vs = getSlotNamed(attrName);
if (vs != null) {
return vs.addNewVersion(txNumber);
}
logger.warn("!!! WARNING !!!: addNewVersion couldn't find the appropriate slot");
return null;
}
public VersionedSubject getSlotNamed(String attrName) {
Class myClass = this.getClass();
while (myClass != Object.class) {
try {
Field f = myClass.getDeclaredField(attrName);
f.setAccessible(true);
return (VersionedSubject) f.get(this);
} catch (NoSuchFieldException nsfe) {
myClass = myClass.getSuperclass();
} catch (IllegalAccessException iae) {
throw new Error("Couldn't find attribute " + attrName + ": " + iae);
} catch (SecurityException se) {
throw new Error("Couldn't find attribute " + attrName + ": " + se);
}
}
logger.warn("Couldn't find attribute {}", attrName);
return null;
}
}