| << §5 Team Activation | ↑ Table of Contents ↑ | §7 Role Encapsulation >> |
Object Teams supports reflection with respect to teams, roles, and role-base relationships.
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.Team:
boolean hasRole ( Object aBase ) ;boolean hasRole ( Object aBase, Class expectedRole ) ;expectedRole 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.
Object getRole ( Object aBase ) ;aBase already has a role in the target team, this role is returned.
Otherwise null is returned.
<T> T getRole ( Object aBase, Class<T> expectedRole ) ;aBase already has a role in the target team that is assignable to the type represented by expectedRole,
this role is returned. Otherwise null is returned.
Object[] getAllRoles () ;System.gc()
prior to calling getAllRoles() in order to achieve deterministic results (see also §2.1.(f)).
<T> T[] getAllRoles ( Class<T> expectedRole ) ;expectedRole.
Class expectedRole must be a bound role otherwise an IllegalArgumentException is thrown.
void unregisterRole ( Object aRole ) ;void unregisterRole ( Object aRole, Class roleClass ) ;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.
| 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 | } |
The following reflective methods defined in org.objectteams.Team can be used to inspect the dynamic behavior of a team:
boolean isExecutingCallin () ;boolean isActive () ;boolean isActive ( Thread aThread ) ;aThread.
The Java syntax for so-called class literals, MyClass.class
(see JLS §15.8.2)
can be used for role types with slightly changed semantics: Role types are virtual types (§1.3.1)
that are bound dynamically (§1.3.1.(e)). This applies to role class literals, too.
From this follows the constraint that a role class literal can only be used within the non-static context of a team,
ie., for evaluating a role class literal an enclosing team instance must be in scope.
Unlike regular type checking for role types, the class literal itself does not have a dependent type.
Thus type checking of calls to methods like hasRole(Object, Class) cannot detect, whether the Class instance
has actually been obtained from the correct team instance. Any attempt to pass a class that is not known
as a bound role within the given team results in an IllegalArgumentException at run-time.
A set of pre-defined types exist that do not extend java.lang.Object
and have no features except the operators == and !=.
java.lang.Object
(JLS §9.2)
and also each object referenced by an interface type can be widened to java.lang.Object.
Compilers commonly implement this by declaring java.lang.Object the super-type of all interfaces.
Such implementation has no visible difference with respect to the more complex definition in the JLS.
These predefined types are
org.objectteams.IConfinedorg.objectteams.Team.IConfinedorg.objectteams.Team.ConfinedThese types provide no new functionality but inheriting from these types influences the semantics with respect to encapsulation. The purpose and usage of these types is described in §7.
The following role interface exists for the purpose of allowing explicit lowering:
org.objectteams.Team.ILowerableThis interface was introduced in detail in §2.2.(d).
Every team can be activated and deactivated by predefined methods of the class org.objectteams.Team.
activate() and activate(Thread th)deactivate() and deactivate(Thread th)The usage of these Methods is described in §5.2.(b).
The following Exceptions can be thrown during the execution of an ObjectTeam/Java program:
ResultNotProvidedExceptionLiftingFailedExceptionWrongRoleExceptionDuplicateRoleExceptionRoleCastException| << §5 Team Activation | ↑ Table of Contents ↑ | §7 Role Encapsulation >> |
Effects:
This teams provides a bonus system for registeredAccounts. Every time an amount of more than 1000 is deposited to a registered account, additional 1% of the amount is credited.participatein line 2 uses declared lifting (see §2.3.2) to allow the passedAccountobject to participate the bonus system provided by theSpecialConditionsteam.hasRoleto check whether the base object already has a role of typeBonusAccountin the surrounding team. The expressionBonusAccount.classreturns thejava.lang.Classobject representing the roleBonusAccount(see JLS §15.8.2). This guard ensures, that only accounts explicitly registered viaparticipateare ever decorated with a role of typeBonusAccount.creditBonusto calls where the base method argumentamountis greater than 1000.