| << §4 Callin Binding | ↑ Table of Contents ↑ | §6 Object Teams API >> | 
§5 Team Activation
The concept of Activation
false, all affected callin bindings
                  				are disabled.
                  
               §5.1 Effect of team activation ↑ §5
↑ §5
               Activating a team instance has the effect of enabling all its callin bindings. 
                  	All effects defined in §4 apply only if a corresponding 
                  	team instance is active.
                  	The order of team activation controls the order of callin executions. 
                  	If more than one team intercepts calls to the same base method, the most recently activated 
                  	team has highest priority in that its before or replace callins are executed first while its after 
                  	callins are executed last.
                  		
                  
               
§5.1.1 Global vs. thread local team activation ↑ §5.1
↑ §5.1
                  While thread local activation only enables the callin bindings of a team instance for a certain thread, global activation activates the team instance for all threads of the application.
§5.1.2 Effect on garbage collection ↑ §5.1
↑ §5.1
                  Any active team is referenced by internal infrastructure. Thus, a team cannot be reclaimed by the garbage collector while it is active.
§5.2 Explicit team activation ↑ §5
↑ §5
               (a) Activation block
                  A team can be activated thread local by the block construct
within (myTeam) { stmts }If stmts has only one statement this can be abbreviated to
within (myTeam) stmt
In these statements, myTeam must denote a team instance. 
                     		For the time of executing this block, this team instance is activated for the current thread, 
                     		which has entered the within block.
                     			
                     
                  
The within block statement guarantees that it leaves
                     		the team in exactly the same activation state as it was in when
                     		entering this block. This includes the cases of exceptions, meaning
                     		that deactivation will also occur if the execution of the block
                     		terminates abnormally.
                     			
                     
                  
(b) Imperative activation
                  Each team class implicitly provides methods from the predefined interface 
                     		org.objectteams.ITeam (super interface of all team classes) to control team 
                     		activation disregarding the block structure of the program. The methods activate() 
                     		and deactivate() are used to activate and deactivate a team instance for 
                     		the current thread.
                     If a team should be de-/activated for another thread this can be done by the methods 
                     activate(Thread aThread) and deactivate(Thread aThread). 
                     In order to achieve global activation for all threads the predefined constant 
                     org.objectteams.Team.ALL_THREADS is passed to these methods (e.g. 
                     activate(Team.ALL_THREADS)).
                     Note, that this methods make no guarantees with respect to exceptions.
                     			
                     
                  
(c) Multiple and mixed activations
                  - If activate()is invoked on a team instance that has been explicitly activated before, this statement has no effect at all (note the difference in §5.3.(a) below).
 The same applies to deactivating an inactive team.
- If a team was already active when entering a withinblock, it will remain active after leaving the block.
- If the team was active on entry of a withinblock and ifdeactivate()is invoked on the same team instance from within thewithinblock, leaving the block will re-activate the team.
§5.3 Implicit team activation ↑ §5
↑ §5
               Implicit team activation is intended to ensure that whenever the control flow is passed to a team or one of its roles, the team is implicitly activated for the current thread. Implicit activation can be configured at different levels (see §5.3.(d)).
When implicit activation is enabled a programmer may assume, that whenever a role forwards calls to its base object via callout, the callin bindings of the same role will be active at that time. Exceptions to this rule have to be programmed explicitly.
(a) Team level methods
                  While executing a team level method, the target team
                     	    is always active. Activation is reset to the previous state
                     	    when leaving the team method, unless the team has been explicitly activated during
                     	    execution of the team method by a call to activate().
                     	    Explicit activation is stronger than implicit activation and thus persists after the
                     	    team level method terminates. Ie., leaving a team level method will never reset
                     	    an explicit activation.
                     			
                     
                  
(b) Methods of externalized roles
                  Invoking a method on an externalized role (see §1.2.2) also has the effect of temporary activation of the team containing the role for the current thread. Regarding deactivation the rule of §5.3.(a) above applies accordingly.
(c) Nested teams
                  Implicit activation has additional consequences for nested teams (see §1.5):
- Implicit activation of a team causes the activation of its outer teams.
- Implicit deactivation of a team causes the deactivation of its inner teams.
(d) Configuring implicit activation
                  Implicit activation is disabled by default and can be enabled by adding the annotation
                     				@org.objectteams.ImplicitTeamActivation, which can be applied to a type or a method.
                     				When applied to a method it is ensured that invoking this method will trigger implicit activation.
                     				When the annotation is applied to a type this has the same effect as applying it to all externally
                     				visible methods of the type. Member types are not affected and have to be annotated separately.
                     
                  
The runtime environment can be configured globally by defining the system property 
                     				ot.implicit.team.activation to one of these values:
                     
                  
- NEVER
- Implicit activation is completely disabled.
- ANNOTATED
- This is the default: implicit activation applies only where declared by @ImplicitTeamActivation.
- ALWAYS
- Implicit activation applies to all externally visible methods (this was the default in OTJLD versions ≤1.2)
Note that among the different mechanisms for activation, within is strongest, 
                  	followed by (de)activate(), weakest is implicit activation. In this sense, 
                  	explicit imperative (de)activation may override the block structure of implicit activation 
                  	(by explicit activation within a team level method), but not that of a within 
                  	block (by deactivation from a within block).
                  		
                  
               
§5.4 Guard predicates ↑ §5
↑ §5
               
               The effect of callins can further be controlled using so called guard predicates. Guards appear at four different levels:
- callin method binding
- role method
- role class
- team class
Guards can be specified as regular guards or base guards, 
                  	which affects the exact point in the control flow, where the guard will be evaluated.
                  		
                  
               
(a) General syntax for guards
                  A guard is declared using the keyword when followed by a 
                     		boolean expression in parentheses:
                     			
                     
                  
when (predicateExpression)
Depending on the kind of guard different objects are in scope using
                     special identifiers like this, base.
                     Any predicate expression that evaluates to true enables
                     the callin binding(s) to which it applies.
                     Evaluation to false disables the callin binding(s).
                     			
                     
                  
(b) No side effects
                  A guard predicate should have no side effects. A compiler should optionally check this condition, but inter-procedural analysis actually depends on the availability of appropriate means to mark any method as side-effect free.
(c) Exceptions
                  A guard predicate should not throw any exceptions. 
                     			   Yet, any exception thrown within a guard predicate cause the guard to evaluate to false 
                     			   rather than propagating the exception, meaning that the evaluation of a guard predicate will never
                     			   interrupt the current base behaviour.
                     			   A compiler should flag any checked exception that is thrown within a guard.
                     			   Such diagnosis should by default be treated as an error, with the option of configuring
                     			   its severity to warning or ignore.
                     			
                     
                  
§5.4.1 Regular guards ↑ §5.4
↑ §5.4
                  This group of guards evaluates within the context of a given role. These guards are evaluated after a callin target is lifted and before a callin bound role method is invoked.
(a) Method binding guards
                     A guard may be attached to a callin method binding as in:
void roleMethod(int ir) <- after void baseMethod(int ib) when (ir > MyTeam.this.threshold);
Such a guard only affects the callin binding to which it is attached, 
                        			i.e., this specific callin binding is only effective, 
                        			if the predicate evaluates to true.
                        			
                        			The following values are within the scope of the predicate expression, 
                        			and thus can be used to express the condition:
                        				
                        
                     
- The role instance denoted by this.
 Features of the role instance can also be accessed relative tothiswith or without explicit qualifyingthis.
- The team instance denoted by a qualified this reference as in 
                           				MyTeam.this.
- If the callin binding includes signatures (as in the example above): 
                           				Parameters of the role method.
 If parameter mappings are involved, they will be evaluated before evaluating the guard.
(b) Method guards
                     A method guard is similar to a method binding guard, but it applies 
                        			to all callin method bindings of this method.
                        			A method guard is declared between the method signature and the method body:
                        				
                        
                     
void roleMethod(int ir)
  when (ir > MyTeam.this.threshold) { body statements }(c) Role level guards
                     When a guard is specified at the role level, i.e., directly before the class body of a role class, it applies to all callin method bindings of the role class:
protected class MyRole
  when (value > MyTeam.this.threshold)
{
    int value;
    other class body declarations
}The following values are within the scope of the predicate expression:
- The role instance denoted by this(explicit or implicit, see above). Thus, in the examplevaluewill be interpreted as a field of the enclosing role.
- The team instance denoted by a qualified this reference as in MyTeam.this
(d) Team level guards
                     A guard specified in the header of a team class may disable the callin 
                        			bindings of all contained role classes. The syntax corresponds to the syntax 
                        			of role level guards.
                        			The only value directly available within team level guard is the 
                        			team instance (denoted by this) and its features.
                        				
                        
                     
Of course all guards can also access any visible static feature of a visible class.
Even if a guard has no direct effect, because, e.g., a role class has no callin bindings (maybe not even a role-base binding), predicates at such abstract levels are useful, because all predicates are inherited by all sub classes (explicit and implicit).
§5.4.2 Base guards ↑ §5.4
↑ §5.4
                  The intention behind base guards is to prevent lifting of a callin-target
                     		if a guard evaluates to false and thus refuses to invoke the
                     		callin bound role method. Using base guards it is easier to prevent any
                     		side-effects caused by a callin binding, because lifting could cause side-effects
                     		at two levels:
                     			
                     
                  
- Creating a role on-demand already is a side-effect (observable e.g.
                        			by the reflective function hasRole (§6.1))
- Role creation triggers execution of a role constructor (see custom lifting constructor (§2.3.1.(c))) which could produce arbitrary side-effects.
Both kinds of side-effects can be avoided using a base guard which prevents unnecessary lifting.
Any guard (5.4.1 (b)-(e)) can be turned into a base guard by adding 
                     		the modifier base as in:
                     			
                     
                  
protected class MyRole playedBy MyBase
  base when (base.value > MyTeam.this.threshold)
{
    class body declarations
}However, different scoping rules apply for the identifiers that can be used in a base guard:
(a) Base object reference
                     In all base guard predicates the special identifier base 
                        			can be used to denote the base object that is about to be lifted.
                        				
                        
                     
(b) Method binding guards
                     A base method binding guard may access parameters as passed to the
                        			base method. Parameter mappings are not considered.
                        Additionally, for after callin bindings, the identifier result 
                        may be used to refer to the result of the base method (if any).
                        				
                        
                     
Note:
In order to achieve the same effect of accessing the base method's result, a regular binding guard (not a base guard) must use a suitable parameter mapping (see §4.4.(c)).
(c) Method guards
                     In contrast to regular method guards, a base guard attached to a role method cannot access any method parameters. See the next item (d) for values that are actually in scope.
(d) Role level guards
                     Role level base guards may use these values:
- The base instance using the special identifier base.
- The team instance using a qualified this references (MyTeam.this).
(e) Team level guards
                     Team level base guards have the same scope as role level base guards (d). 
                        			However, the type of the role instance is not known here, i.e., here base 
                        			has the static type java.lang.Object.
                        				
                        
                     
(f) Unbound roles
                     In contrast to regular guards, base guards cannot be attached to
                        	unbound role classes nor to their methods.
                        	Only team level base guards are independent of role binding.
                        				
                        
                     

§5.4.3 Multiple guards ↑ §5.4
↑ §5.4
                  Due to the different ranges of applicability different guards may affect the same method binding. 
                     		In that case all applicable guards are conjoined using a logical and.
                     Any guard is interpreted as the conjunction of these predicates (if present):
                     			
                     
                  
- The direct predicate expression of the guard.
- The next outer guard along the chain method binding -> method -> role level -> team level
- The guard at the same level that is inherited from the implicit super role.
- The guard at the same level that is inherited from the explicit super role.
Example code (Guard Predicates):
| 1 | public team class ATM { | 
| 2 | private Bank myBank; | 
| 3 | public class ForeignAccount playedBy Account | 
| 4 | base when (!ATM.this.myBank.equals(base.getBank())) | 
| 5 |   { | 
| 6 |     callin void debitWithFee(int amount) { | 
| 7 | base.debitWithFee(fee+amount); | 
| 8 | } | 
| 9 | void debitWithFee(int i) <- replace void debit(int amount) | 
| 10 | base when (amount < 1000); | 
| 11 | } | 
| 12 | } | 
§5.5 Unanticipated team activation ↑ §5
↑ §5
               If an application should be adapted unanticipatedly by one or more teams, this can be achieved without explicitly changing the program code of this application.
General activation via config file:
                  	Instead of adding the team initialization
                  	and activation code to the main program, it is possible to add the respective teams via a config file.
                  	Every line of this text file contains the fully qualified name of a compiled team, which has to be available
                  	on the classpath.
                  For the instantiation of these teams the default constructor is used, which means adding a team to
                  an application this way requires the team to provide a default constructor.
                  The activation order (see §5.1) for these teams corresponds to the order 
                  in which they are listed in the config file.
                  	Lines starting with a '#' denote comment lines.
                  		
                  
               
Example config file:
# Config file for an ObjectTeams application: mypackage1.MyTeam1 # ... mypackageM.MyTeamN
To get this config file recognized by the application the VM argument
'-Dot.teamconfig=<config_file_name>'
                  	has to be used when starting the application.
                  		
                  
               
Note:
In the ObjectTeams Development Tooling (OTDT) teams are activated unanticipatedly via a special tab in the "Run-Configuration" (see OTDT features), instead.Activation adjustment example:
                  	Teams added via the config file mechanism are activated by default. Because no reference to them is
                  	stored anywhere, it is not possible to deactivate them later.
                  	If deactivation of unanticipated added teams is required, this can be achieved by adding a manager team
                  	via config file and encapsulate the actual functionality in another team managed by the manager team.
                  	This way a functional team can be activated and deactivated as needed.
                  		
                  
               
Example code (Activation Adjustment):
| 1 | public team class MyManagerTeam { | 
| 2 | private FunctionalTeam myFunctionalTeam = new FunctionalTeam(); | 
| 3 |   protected class MyRole playedBy MyApplication { | 
| 4 |     void startAdaption() { myFunctionalTeam.activate(); } | 
| 5 | startAdaption <- before startMethod; | 
| 6 |     void stopAdaption() { myFunctionalTeam.deactivate(); } | 
| 7 | stopAdaption <- after stopMethod; | 
| 8 | } | 
| 9 | } | 
# Config file for the manager team example:
MyManagerTeamEffects:
- startMethodand- stopMethodare methods which demand the activation and deactivation respectively.
- If the activation/deactivation depends on other conditions these can be checked in addition.
| << §4 Callin Binding | ↑ Table of Contents ↑ | §6 Object Teams API >> | 
 all news
 all news RSS feed
 RSS feed

Effects:
The team in this example causes that an additional fee has to be payed while debiting less than 1000 Euros from a "foreign" account.Accountobjects only getForeignAccountroles, if they belong to a different bank than the surroundingATMteam.It accesses the bank of the base via the
baseidentifier.debitWithFeeto calls where the base method argumentamountis lower than 1000.Account.debitcauses a replace callin todebitWithFeeonly if both predicates evaluate to true.