DPML
Component Types
HomeUtilitiesStationMetroDepotTransit
Component Types
Tutorial Objective

All of the component tutorials presented so-far have focussed on the implementation class and associated deployment data. In this tutorial we address the subject of component types a their role in providing default information associated with a particular component class.

What is a Component Type ?

The following characteristics of a component class are directly associated with the implementation class:

  • thread-safety policy
  • lifecycle graph
  • service interface restrictions

In addition, component deployment default and runtime constraints can be associated with a component type enabling simplification of deployment data and faster processing during deployment (via build-time preprocessing on constraints). As such - the following additional features can be associated with a component type:

  • lifestyle policy
  • collection policy
  • component name
  • context entry criteria
  • bundled part defintions
  • logging channel names
  • default activation policy
Type Creation

The following build.xml file demonstrates the use of the Metro type task. The type task handles the creation of an XML document collocated with the component class under the type suffix (e.g. org/acme/Demo.type).

<?xml version="1.0" encoding="UTF-8" ?>

<project xmlns:transit="antlib:net.dpml.transit" 
    xmlns:x="dpml:depot">

  <target name="init" depends="standard.init">
    <x:plugin uri="link:part:dpml/metro/dpml-metro-tools" urn="metro"/>
  </target>

  <target name="build" depends="standard.build">
    <type xmlns="metro" class="org.acme.Demo" name="demo" threadsafe="true" collection="soft">
      <services>
        <service class="org.acme.Widget"/>
      </services>
      <state>
        <trigger event="initialization">
          <transition name="start" target="started">
            <operation name="startup" method="start"/>
          </transition>
        </trigger>
        <state name="started">
          <transition name="stop" target="../stopped">
            <operation name="stop" method="stop"/>
          </transition>
          <trigger event="termination">
            <apply id="stop"/>
          </trigger>
        </state>
        <state name="stopped">
          <transition name="start" target="../started">
            <operation name="start" method="start"/>
          </transition>
        </state>
      </state>
    </type>
  </target>

</project>

In the above type defintion we have requested the creation of a type datastructure for the class org.acme.Demo. In this definition we have declared that the component implementation publishes a single service interface (org.acme.Widget), thread-safe capability, a default name and collection policy, and a lifecycle state graph. The component deployment definition within our Depot project declaration can now simplificed down to the following:

<index ..... >

  <project name="acme-type-demo" basedir="type">
    <types>
      <type id="jar"/>
      <component xmlns="link:xsd:dpml/lang/dpml-component#1.0" type="org.acme.Demo"/>
    </types>
    <dependencies>
      <test>
        <include ref="ant/ant-junit"/>
        <include ref="dpml/transit/dpml-transit-main"/>
      </test>
    </dependencies>
  </project>
  
  ...
  
</index>
Component Example

tutorial/components/type:

Demo.java The demo component implementing the Widget service interface together with support for a custom lifecycle.
Widget.java An example service interface implemented in the Demo class.
DemoTestCase.java The testcase.

Testcase result reflect the demo component deployment including invocation of an operation against the Widget service interface.

test:
    [junit] Executing forked test.
    [junit] Running org.acme.test.DemoTestCase
    [junit] [14219] [INFO   ] (demo): startup
    [junit] [14219] [INFO   ] (demo): doing stuff
    [junit] [14219] [INFO   ] (demo): shutdown
    [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 1.047 sec
Summary