<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE aop PUBLIC
   "-//JBoss//DTD JBOSS AOP 1.0//EN"
   "http://www.jboss.org/aop/dtd/jboss-aop_1_0.dtd">
<aop>

<!--
   | DO NOT MODIFY THIS FILE
   |
   | This is internal PAT's AOP configuration file.
-->


<!--
   | @@pat.root
-->
<introduction expr="class(@pat.root)">
    <mixin transient="false">
        <interfaces>
            org.prevayler.PrevalentSystem
        </interfaces>
        <class>org.nthx.pat.PrevalentSystemMixin</class>
        <construction>new org.nthx.pat.PrevalentSystemMixin()</construction>
    </mixin>
</introduction>

<introduction expr="class(@pat.root)">
    <mixin transient="false">
        <interfaces>
            org.nthx.pat.IdentityMap
        </interfaces>
        <class>org.nthx.pat.IdentityMapMixin</class>
        <construction>new org.nthx.pat.IdentityMapMixin()</construction>
    </mixin>
</introduction>


<!--
   | Make PAT's root manageable: save(takeSnapshot),
   | removeObject(identityMap.remove..), etc..
-->
<introduction expr="class(@pat.root)">
    <interfaces>
        org.nthx.pat.Persisteble
    </interfaces>
</introduction>



<!-- BusinessObject's creation.
   | This AOP declaration has to be BEFORE other pat.* declarations.
   | @@pat.bo
-->
<introduction expr="class(@pat.bo)">
    <mixin transient="false">
        <interfaces>
            org.nthx.pat.BusinessObject, org.nthx.pat.Identifiable
        </interfaces>
        <class>org.nthx.pat.IdentifiableMixin</class>
        <construction>new org.nthx.pat.IdentifiableMixin()</construction>
    </mixin>
</introduction>
<introduction expr="class(@pat.root)">
    <mixin transient="false">
        <interfaces>
            org.nthx.pat.BusinessObject, org.nthx.pat.Identifiable
        </interfaces>
        <class>org.nthx.pat.IdentifiableMixin</class>
        <construction>new org.nthx.pat.IdentifiableMixin()</construction>
    </mixin>
</introduction>


<!--
   | Bindings..
   | They are at the end of file, because order of advice, introductions
   | is important in JBossAOP
-->
<typedef name="pat_rootTD" expr="class(@pat.root)" />
<typedef name="pat_boTD" expr="class(@pat.bo)" />

<cflow-stack name="whenNotRecoveringCommands">
    <not-called expr="* *->recoverCommands(..)"/>
</cflow-stack>
<cflow-stack name="whenNotInside_NestedTransaction">
    <not-called expr="java.lang.Object org.nthx.pat.CommandInterceptor->invoke(..)"/>
</cflow-stack>
<cflow-stack name="whenNotInside_NestedBOConstructor">
    <not-called expr="java.lang.Object org.nthx.pat.TopBusinessObjectCreationInterceptor->invoke(..)"/>
</cflow-stack>

<!--
   | @@pat.root
   |
-->
<bind pointcut="execution($typedef{pat_rootTD}->new(..))">
    <interceptor class="org.nthx.pat.RootCreationInterceptor"
     scope="PER_CLASS"/>
</bind>
    
<!--
   | @@pat.bo
   |
-->
<!-- This one is "top-level" only, and not when recovering -->
<bind pointcut="execution($typedef{pat_boTD}->new(..))"
    cflow="(whenNotRecoveringCommands AND whenNotInside_NestedTransaction AND whenNotInside_NestedBOConstructor)" >
    <interceptor class="org.nthx.pat.TopBusinessObjectCreationInterceptor"
     scope="PER_CLASS"/>
</bind>
<!-- This one is applied always, even when recovering Prevayler-->
<bind pointcut="execution($typedef{pat_boTD}->new(..))">
    <interceptor class="org.nthx.pat.BusinessObjectCreationInterceptor"
     scope="PER_CLASS"/>
</bind>


<!--
   | @@pat.transaction
   |
-->
    <!-- This one is "top-level" only, and not when recovering -->
<bind pointcut="execution(* *->@pat.transaction(..))"
    cflow="(whenNotRecoveringCommands AND whenNotInside_NestedTransaction AND whenNotInside_NestedBOConstructor)" >
    <interceptor class="org.nthx.pat.CommandInterceptor" />
</bind>

    
<!--
   | Persisteble.takeSnapshot()
   | Persisteble.removeObject(BO)
   | Root-fields injector. @@pat.root_injected
   |
-->
<aspect class="org.nthx.pat.PersistebleAspect" scope="PER_CLASS"/>
<bind pointcut="execution(void $instanceof{org.nthx.pat.Persisteble}->takeSnapshot())">
    <advice aspect="org.nthx.pat.PersistebleAspect" name="takeSnapshot"/>
</bind>
<bind pointcut="execution(void $instanceof{org.nthx.pat.Persisteble}->removeBO(..))">
    <advice aspect="org.nthx.pat.PersistebleAspect" name="removeBO"/>
</bind>
<bind pointcut="get(* *->@pat.root_injected)">
    <advice aspect="org.nthx.pat.PersistebleAspect" name="injectRoot" />
</bind>

    
</aop>