Chapter 13. Interception of Array Element Access

This chapter will show you how to intercept access to the individual elements of an array. The concepts are similar to the interception we have seen previously, but a few configuration options are introduced. Array interception can currently only be configured via xml. There are three steps involved.

13.1. Replacing Array Access

To achieve array interception we need to replace all access to arrays within a selected set of classes. The arrayreplacement element is used for this. You can either specify a particular class using the class attribute or a class expression using the expr attribute:

    
   <arrayreplacement class="org.acme.POJOWithArray"/>
   <arrayreplacement expr="class(org.acme.*)"/>

         

13.2. Preparing Array Fields

If we want to intercept an array's elements, that array field needs to be woven, using either a prepare or a bind expression. If that field is within a class picked out by an arrayreplacement expression it gets all the hooks for arrayreplacement to take place. The following xml along with the previous arrayreplacement weaves org.acme.POJOWithArray.ints for array element interception.

    
   <prepare expr="field(int[] org.acme.POJOWithArray->ints)"/>

         

13.3. Binding Advices to array element access

To bind advices to the access of array elements, you use a arraybind element. It binds advices to all arrays woven for array access. You can use the type attribute to specify if you want the interception to take place when setting elements in the array, getting elements from the array, or both. Valid values for the type attribute are: READ_WRITE, READ_ONLY and WRITE_ONLY. An example is shown below:

    
   <interceptor class="org.acme.TestInterceptor"/>
   <arraybind type="READ_ONLY">
      <interceptor-ref name="org.acme.TestInterceptor"/>
   </arraybind>

         

arraybind currently only supports interceptor-ref and advice as child elements. before, after, throwing and finally are not yet supported for array interception. for arrays.

13.4. Invocation types for array element access interception

Writing aspects for array element interception is more or less the same as for any other joinpoint. However, array element interception comes with its own hierarchy of Invocation clases. Which one of these is used depends on what is being itercepted. The hierarchy is shown below (all the classes live in the org.jboss.aop.array package):

    
ArrayElementInvocation
-ArrayElementReadInvocation
--BooleanArrayElementReadInvocation  -Element read from a boolean[]
--ByteArrayElementReadInvocation     -Element read from a byte[]
--CharArrayElementReadInvocation     -Element read from a char[]
--DoubleArrayElementReadInvocation   -Element read from a double[]
--FloatArrayElementReadInvocation    -Element read from a float[]
--IntArrayElementReadInvocation      -Element read from a int[]
--LongArrayElementReadInvocation     -Element read from a long[]
--ObjectArrayElementReadInvocation   -Element read from a Object[], String[] etc.
--ShortArrayElementReadInvocation    -Element read from a shore[]
-ArrayElementWriteInvocation
--BooleanArrayElementWriteInvocation -Element written to a boolean[]
--ByteArrayElementWriteInvocation    -Element written to a byte[]
--CharArrayElementWriteInvocation    -Element written to a char[]
--DoubleArrayElementWriteInvocation  -Element written to a double[]
--FloatArrayElementWriteInvocation   -Element written to a float[]
--IntArrayElementWriteInvocation     -Element written to a int[]
--LongArrayElementWriteInvocation    -Element written to a long[]
--ObjectArrayElementWriteInvocation  -Element written to a Object[], String[] etc.
--ShortArrayElementWriteInvocation   -Element written to a short[]

         

The write invocation classes allow you access to the value the element is being set to. ArrayElementReadInvocation defines a method to get hold of the value being set:


   public abstract Object getValue();    

         

The sub-classes override this value, and also define a more fine-grained value to avoid using the wrapper classes where appropriate, as shown in the following methods from DoubleArrayElementWriteInvocation:


   public Object getValue()
   {
      return new Double(value);
   }

   public double getDoubleValue()
   {
      return value;
   }

         

When reading an array element the invocation's return value contains the value read. For all array invocations you can get the index of the element being accessed by calling ArrayElementInvocation.getIndex().