///////////////////////////////////////////////////////////////
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
///////////////////////////////////////////////////////////////

[[howto-create-sideeffect,Create a SideEffect]]
= Create a SideEffect =

SideEffects are defined in <<def-sideeffect>>.

If you want to reproduce what's explained in this tutorial, remember to depend on the Core Bootstrap artifact:

include::../../../../core/bootstrap/build/docs/buildinfo/artifact.txt[]

At runtime you will need the Core Runtime artifact too. See the <<howto-depend-on-polygene>> tutorial for details.

== Typed SideEffect ==

A typed SideEffect is a Java class that implements the MixinType it can be used on:

[snippet,java]
-----------
source=tutorials/introduction/tenminutes/src/main/java/org/apache/polygene/demo/tenminute/MailNotifySideEffect.java
tag=allClass
-----------

The MailNotifySideEffect is implemented as an abstract class, since we are not interested in the many other methods in
the Confirmable interface. Extending the SideEffectOf is a convenience mechanism, instead of an explicit @SideEffectFor
annotation on a private field, which can be used in rare occasions when you are not able to extend. This base class
defines the next field, which is set up by the Polygene™ runtime and points to the next fragment in the call stack. We can
also see that the MailService, HasLineItems and HasCustomer are provided to the side-effect, which is done with
dependency injection. Polygene™ also supports dependency injection via constructors and methods.

It can be used as follows;

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/sideeffects/OrderEntity.java
tag=body
-----------

Methods of the SideEffect Fragment will be called after the Mixin invocation.

== Generic SideEffect ==

A generic SideEffect is a Java class that implements java.lang.reflect.InvocationHandler which allows it to be used on any
arbitrary MixinType.

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/sideeffects/MyGenericSideEffect.java
tag=body
-----------

It can be used as follows;

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/sideeffects/AnyMixinType.java
tag=body
-----------

Methods of the SideEffect Fragment will be called before the Mixin invocation.


=== AppliesTo ===

For generic SideEffects that should only trigger on methods with specific annotations or fulfilling some expression, add
@AppliesTo annotation to the SideEffect class which points to either triggering annotation(s), or to AppliesToFilter
implementation(s).

The SideEffect is invoked if one of the triggering annotations is found or one of the AppliesToFilter accepts the
invocation. In other words the AppliesTo arguments are OR'ed.

Here is how the declaration goes ;

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/sideeffects/MyGenericSideEffect.java
tag=appliesTo
-----------

And how to use the annotation ;

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/sideeffects/AnyMixinType.java
tag=annotation
-----------

Here only the doSomething() method will see the SideEffect applied whereas the doSomethingElse() method won't.

Finally here is how to implement an AppliesToFilter:

[snippet,java]
-----------
source=manual/src/main/java/org/apache/polygene/manual/recipes/sideeffects/MyAppliesToFilter.java
tag=filter
-----------

