/
codebase/
codebase/area/
codebase/doc/
codebase/etc/
codebase/src/net/sourceforge/pain/data/trigger/
codebase/src/net/sourceforge/pain/logic/
codebase/src/net/sourceforge/pain/logic/affect/
codebase/src/net/sourceforge/pain/logic/event/
codebase/src/net/sourceforge/pain/logic/event/deploy/
codebase/src/net/sourceforge/pain/logic/event/guitool/
codebase/src/net/sourceforge/pain/logic/event/guitool/event/
codebase/src/net/sourceforge/pain/logic/fn/util/
codebase/src/net/sourceforge/pain/logic/trigger/
codebase/src/net/sourceforge/pain/logic/trigger/impl/
codebase/src/net/sourceforge/pain/network/console/
codebase/src/net/sourceforge/pain/network/console/telnet/
codebase/src/net/sourceforge/pain/network/guitool/
codebase/src/net/sourceforge/pain/plugin/
codebase/src/net/sourceforge/pain/plugin/command/
codebase/src/net/sourceforge/pain/plugin/reset/
codebase/src/net/sourceforge/pain/plugin/shutdown/
codebase/src/net/sourceforge/pain/plugin/social/
codebase/src/net/sourceforge/pain/util/
db/doc/javadoc/resources/
db/src/net/sourceforge/pain/util/
gui/
gui/lib/
gui/src/net/sourceforge/pain/tools/guitool/dbbrowse/
gui/src/net/sourceforge/pain/tools/guitool/dialog/
gui/src/net/sourceforge/pain/tools/guitool/menu/
gui/src/net/sourceforge/pain/tools/guitool/resources/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/explorer/
tests/
tests/src/
tests/src/net/sourceforge/pain/db/data/
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);
    }
}