close

Filter

loading table of contents...

Content Application Developer Manual / Version 2010

Table Of Contents

5.2 Aspects

Aspects are a feature that allows you to add new functionality to existing content beans without modifying the content bean source code itself, either because the content bean source code is not available, or to create a reusable extension. When access to the content bean source code is available, using aspects is usually not necessary.

Note

Note

Since 1907.1 Aspects are deprecated. When Aspects were introduced, the content beans were available as binary artifacts only, and for projects there was no other way but Aspects to enhance them. Nowadays, the Blueprint content beans are shipped as source code, and it is much easier to change them directly.

Terminology

Beans designed for extension by aspects are called aspect aggregators and implement the com.coremedia.cae.aspect.AspectAggregator interface. Typically, these will be content beans, extending com.coremedia.cae.aspect.contentbean.AbstractAspectAggregatorContentBean, but this is not a requirement. In the sections to follow, it is assumed your aspect aggregators are content beans.

An aspect is a bean to be "attached" to or associated with an aspect aggregator. Aspects have a name, and an aspect aggregator instance can have at most one aspect bean with a given name associated with it.

Setting up the Aspect Infrastructure

Aspect aggregators must implement the com.coremedia.cae.aspect.AspectAggregator interface. To make existing content beans aspect aware, make sure that they inherit from AbstractAspectAggregatorContentBean (rather than AbstractContentBean) and adjust your parent content bean definitions. Also, aspect aggregators need an AspectsProvider. The CompoundAspectsProvider in this example serves as a registry for plugins adding aspects to your content beans.

<bean id="aspectsProviders" class="org.springframework.beans.factory.config.ListFactoryBean">
  <property name="sourceList">
    <list value-type="com.coremedia.cae.aspect.provider.AspectsProvider"/>
  </property>
</bean>

<bean id="aspectsProvider" class="com.coremedia.cae.aspect.provider.CompoundAspectsProvider">
  <property name="aspectsProviders" ref="aspectsProviders"/>
</bean>

<bean id="contentBeanBase" abstract="true" class="AbstractAspectAggregatorContentBean">
  <property name="aspectsProvider" ref="aspectsProvider"/>
</bean>

<bean id="contentBeanFactory:YourType" class="com.yourcompany.YourTypeContentBean" parent="contentBeanBase">
  ...
</bean>

Example 5.1. Add aspect support to content beans


Registering Aspects

To create a new aspect, implement the Aspect interface and add the new behavior to this class, by adding bean properties, for instance. Choose an adequate AspectsProvider to provide instances of these beans. For instance, for an aspect to be added to content beans, choose the ContentBeanAspectsProvider. This provider needs its own content bean factory instance whose configuration will determine which content types the aspect should apply to.

<!-- factory to create aspect bean instances -->
<bean id="myAspectContentBeanFactory"
      class="com.coremedia.objectserver.beans.SpringContentBeanFactory"/>

<!-- configuration to map MyDoctype to MyDoctypeAspectContentBean -->
<bean name="myAspectContentBeanFactory:MyDoctype"
      class="com.mycompany.MyDoctypeAspectContentBean"
      scope="prototype">
  <property name="aggregatorContentBeanFactory"
            ref="contentBeanFactory"/>
</bean>

<!-- aspects provider for the new aspect -->
<bean id="myAspectsProvider"
      class="com.coremedia.cae.aspect.provider.ContentBeanAspectsProvider">
  <property name="contentBeanFactory"
            ref="myAspectContentBeanFactory"/>
</bean>

<!-- register the aspects provider -->
<customize:append id="addMyAspectProvider" bean="aspectsProviders">
  <list>
    <ref bean="myAspectsProvider"/>
  </list>
</customize>

Example 5.2. Registering an aspects provider for content beans


On the other hand, to add aspects to arbitrary Java beans which are not content beans, use a BeanFactoryAspectsProvider instead. The aspect implementation class should also implement the AspectAggregatorAware interface to have access to the aspect aggregator. Define your aspect bean as a prototype bean with name like beanNameOfAspectProvider:classNameOfAggregatorBean where "classNameOfAggregatorBean" is the fully qualified class name of the bean the aspect will be applied to. You might use super classes or interfaces here as well.

<bean id="myAspectsProvider"
      class="com.coremedia.cae.aspect.provider.BeanFactoryAspectsProvider"/>

<bean name="myAspectContentBeanFactory:com.mycompany.MyBean"
      class="com.mycompany.MyBeanAspectImpl" scope="prototype">
  ...
</bean>

Example 5.3. Definition of an aspects provider for arbitrary Java beans


Working with Aspects

Aspects added to aggregator beans by an aspects provider are available in code by calling the getAspects or getAspectsByName methods:

Collection<? extends Aspect> aspects = contentBean.getAspects();
Map<String, ? extends Aspect> aspectsByName = contentBean.getAspectsByName();

In templates, use the map returned by getAspectsByName to access an aspect of the aggregator by its name:

self.aspectByName['myAspect'].myProperty

Search Results

Table Of Contents