§6.1.(a) Interface to the role registry

Each team instance internally has a registry of known role objects indexed by their base object. Programmers may make use of this registry using the following reflective methods defined in org.objectteams.ITeam:

boolean hasRole ( Object aBase ) ;
This method checks whether a role for the passed base object already exists in the target team.
boolean hasRole ( Object aBase, Class roleType ) ;
This method checks whether a instance of type roleType as a role for the passed base object aBase already exists in the target team. The role may also be of any subtype of the specified role type.
If roleType is not a member type of the current team an IllegalArgumentException is thrown.
Object getRole ( Object aBase ) ;
If the passed base object aBase already has a role in the target team, this role is returned. Otherwise null is returned.
<T> T getRole ( Object aBase, Class<T> roleType ) ;
If the passed base object aBase already has a role in the target team that is assignable to the type represented by roleType, this role is returned. Otherwise null is returned.
If roleType is not a member type of the current team an IllegalArgumentException is thrown.
Object[] getAllRoles () ;
Retrieves all existing (registered) bound roles (§2.1.(a)) in the target team.
This method uses internal structures of weak references. For that reason it may return role instances which were about to be reclaimed by the garbage collector. If performance permits, it is thus advisable to always call System.gc() prior to calling getAllRoles() in order to achieve deterministic results (see also §2.1.(f)).
<T> T[] getAllRoles ( Class<T> roleType ) ;
Retrieves all existing (registered) bound roles (§2.1.(a)) in the target team that are assignable to the type represented by roleType.
If roleType is not a member type of the current team an IllegalArgumentException is thrown.
See the note about garbage collection above.
void unregisterRole ( Object aRole ) ;
This method unregisters the passed role object from the target team. Thus the corresponding base looses this role. After calling this method the role should no longer be used.
void unregisterRole ( Object aRole, Class roleType ) ;
This method unregisters the passed role object from the target team. Thus the corresponding base loses this role. After calling this method the role should no longer be used. The only difference to the previous method is improved speed because no search for the corresponding registry has to be performed.
If roleType is not a member type of the current team an IllegalArgumentException is thrown.

It is desirable and possible to use these methods within guards (see §5.4). These methods allow to write the specification of guards in a more concise and more expressive way. Determined by the signature, the first four methods can only be used in a base-level guard (§5.4.2) because they require a reference to a base object.

Example code (Guards and Reflection):
1
public team class SpecialConditions {
2
  public void participate(Account as BonusAccount ba) {}
3
  public class BonusAccount playedBy Account
4
    base when(SpecialConditions.this.hasRole(base, BonusAccount.class))
5
  {
6
    callin void creditBonus(int amount) {
7
      base.creditBonus(amount + bonus);
8
    }
9
    void creditBonus(int amount) <- replace void credit(int i)
10
      base when (i > 1000);
11
  }
12
}
Effects:
This teams provides a bonus system for registered Accounts. Every time an amount of more than 1000 is deposited to a registered account, additional 1% of the amount is credited.
  • The team level method participate in line 2 uses declared lifting (see §2.3.2) to allow the passed Account object to participate the bonus system provided by the SpecialConditions team.
  • The base guard in line 4 uses the reflective method hasRole to check whether the base object already has a role of type BonusAccount in the surrounding team. The expression BonusAccount.class returns the java.lang.Class object representing the role BonusAccount (see JLS §15.8.2). This guard ensures, that only accounts explicitly registered via participate are ever decorated with a role of type BonusAccount.
  • The method binding guard in line 10 restricts the callin to creditBonus to calls where the base method argument amount is greater than 1000.