package net.sourceforge.pain.data;
import net.sourceforge.pain.db.*;
import java.util.*;
/**
* role can be considered as type of object, every object could have only one role of the specified class
*/
public abstract class Role extends DbObject implements LogicalObject {
/**
* used for default getSuperroles method impl
*/
private static final Class[] emptySuper = new Class[0];
/**
* every LogicalObject may have as many Roles as it want to have
* All it's roles linked with one Root object.
* This field is a reference to the LogicalObject root
*/
private static final int ROOT = 0;
/**
* Number of subrroles of this Role in LogicalObject.
* Subrroles is Dynamic SubClasses of this Role.
*/
private static final int NSUBROLES = 1;
public static final int LAST_BASE_FIELD_INDEX = 1;
/** used by db during startup */
public Role() {
}
protected Role(PainDB db) {
super(db);
}
final void init(Root root) {
setReference(ROOT, root);
}
/**
Every Role subclass MUST call provideSuperSchema();
*/
protected final int fillSuperSchema(byte[] types, String[] names) {
types[ROOT] = DbType.REFERENCE;
names[ROOT] = "root";
types[NSUBROLES] = DbType.INT;
names[NSUBROLES] = "nsubroles";
return 1;
}
/** PAiN has dynamic inheritance model,
every type(role) should know own superroles with deep=1
this method could be overriden by impl
returns array of Role classes
*/
protected Class[] getSuperroles() {
return emptySuper;
}
void incNSubroles() {
setInt(NSUBROLES, getInt(NSUBROLES) + 1);
}
public boolean hasSubroles() {
return getInt(NSUBROLES) > 0;
}
void decNSubroles() {
setInt(NSUBROLES, getInt(NSUBROLES) - 1);
}
/** helpers:
Used to avoid explicit owner extraction before cast to another type
*/
public final Role getRole(Class typeClass) {
if (typeClass == getClass()) {
return this;
}
return getRoot().getRole(typeClass);
}
public final boolean is(Class typeClass) {
if (typeClass == getClass()) {
return true;
}
return getRoot().is(typeClass);
}
public final Role addRole(Class typeClass) throws Exception {
return getRoot().addRole(typeClass);
}
public final void removeRole(Class typeClass) throws Exception {
getRoot().removeRole(typeClass);
}
public final void detach() {
getRoot().removeRole(this);
}
public int getRoleClassId() {
return ((DbOid) getDbClass().getOid()).getIndexId(); // using paindb low level internals!
}
public boolean sameObjectAs(LogicalObject obj) {
if (obj == this) {
return true;
}
if (obj.getClass() == Root.class) {
return getRoot() == obj;
}
return getRoot() == ((Role) obj).getRoot();
}
public Iterator rolesIterator() {
return getRoot().rolesIterator();
}
protected Root getRoot() {
return (Root) getReference(ROOT);
}
public void _nullRoot() {
setReference(ROOT, null);
}
final void _delete() {
super.delete();
}
/** will delete whole object with all roles */
public void delete() {
getRoot().delete();
}
}