package net.sourceforge.pain.data;
import net.sourceforge.pain.db.*;
import net.sourceforge.pain.logic.*;
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;
protected 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 final 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);
}
final int getRoleClassId() {
return getDbClass().pain_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 final 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();
}
/**
* remove method for this iterator will delete trigger as dbobject
*/
public final Iterator getTriggersByEventType(int eventType) {
return getRoot().getTriggersByEventType(eventType);
}
/**
* remove method for this iterator will delete trigger as dbobject
*/
public final Iterator getRoleTriggers() {
return getRoot().getRoleTriggers(this);
}
public final Iterator getAffects() {
return getRoot().getAffects();
}
public final boolean isAffected(int affectType) {
return getRoot().isAffected(affectType);
}
public final AffectData getAffectData(int affectType) {
return getRoot().getAffectImage(affectType);
}
}