MetaBoss Beginner's Guide
Description of the handcoded service implementation
Overview
Our model includes the MiscellaneousQueries service specification at the
CRS->Public Interfaces->Service Modules->Reporting->MiscellaneousQueries model path.
For all services, including this one, MetaBoss has generated the Java interface representing the service interface. It has also
generated all Data Type, Structure and Message classes (they are used as inputs and outputs to the service operations).
The generated interface com.almamater.crs.services.reporting.BSMiscellaneousQueries
corresponds to the service we are looking at. We are required to implement this service, which means prepare the source of the implementation,
build it and package together with the rest of the code. We will now describe all these steps in more detail.
Index
What are we required create from the programming model prospective
What are we required to create from the business requirements prospective
Creating the handcoded implementation
Building and packaging the handcoded implementation
What are we required create from the programming model prospective
MetaBoss programming model extensively uses JNDI-based interface/implementation separation technique.
This allows client code to only ever see interfaces and not implementations or even implementation factories.
JNDI mechanism is configured at the deployment time and instantiates necessary implementations at run-time.
This mechanism requires that each interface implementation consists of at least two classes:
- The actual interface implementation class. It must be a non-abstract class which implements the entire interface
(ie. all methods must be implemented).
- The JNDI object factory class. This class must implement javax.naming.spi.ObjectFactory class, which only
requres one method - getObjectInstance() returning an instance of the interface implementation object.
At the deployment time these two classes are made available on the classpath
and JNDI is configurred to instantiate the implementation class (via the object factory) when
someone is looking up corresponding interface. This mechanism is further discussed in the
System Componentisation chapter of the
MetaBoss Programming Model Guide.
What are we required to create from the business requirements prospective
From the business requirements prospective we have to implement
the MiscellaneousQueries service which provides two specialised search operations:
findFreeTeachers - the operation must find all Teachers who are not listed as Supervisor
or Lecturer on any course. The operation has no inputs and returns zero or more Teacher details structures
findStudentAcquaintances - the operation must find all Teachers and Students who are
familiar with the given Student. Students are familiar when they are enrolled in the same Course.
Teacher is familiar with the Student if he or she is a Supervisor or Lecturer on any of the Courses attended by
the given Student. The operation takes Student identifier structure as an input and returns zero or more Teacher details structures and
zero or more Student details structures.
Creating the handcoded implementation
We will now create handcoded implementation files step by step:
Create the directory for the handcoded source.
We use ${metaboss_home}/examples/AlmaMater/Source
Create the directory tree hierarchy, which corresponds
to the package hierarchy: com/almamater/crs/services/reporting/impl. Note that by doing that we
are placing our implementation package (impl) under the interface package (com.almamater.crs.services.reporting).
We could have placed the implementation anywhere, but MetaBoss good practice is
to locate all implementation packages under the interface package.
Start up your favorite Java IDE (We use Eclipse) to create
source files. The ${metaboss_home}/examples/AlmaMater/Release/lib/BSAlmaMaterCRS.jar, which was created during generation step
contains the com.almamater.crs.services.reporting.BSMiscellaneousQueries interface which we are
implementing. You can place this jar on the project classpath.
Create the com.almamater.crs.services.reporting.impl.BSMiscellaneousQueriesImpl
implementation class. We hope that the file we have provided is annotated enough for you to
follow what is going on there. Nevertheless, let's see what typical service implementation consists of:
- Disassemble and validate the input data. Error should be returned if validation is not successfull. This step is only necessary if there is an input data.
- Obtain access to one or more Domain objects (ie. establish database connections) using JNDI lookup.
- Navigate to the desired domain objects or build a collection of the desired domain objects. This is where the most interesting stuff happens!
- If necessary modify data in the located entity objects. This step is only necessary for update type services and we do not have them in this example.
- Build result structure and return. This step is only necessary if there is an output data.
Create the com.almamater.crs.services.reporting.impl.BSMiscellaneousQueriesFactory
object factory. The factory is simply returning an instance of the service.
The only sophistication is there is that it is creating only one implementation at the first request
and than returns it all the time. It can do that because it knows that this partucular
impplementation is reentrant and multi-thread safe. In caces where this is not the case, the
factory can return brand new instance of the implementation every time.
The resulting source directory should look like the one below:
Building and packaging the handcoded implementation
Having created implementation classes you could build and package them in one of two
ways:
Introduce the implementation directory to the MetaBoss Builder
Task in ant, so the builder will pick up the handcoded classes and package them together with the
generated ones. This is done in two strokes:
Specify 'implssrcdir' attribute to MetaBoss builder as follows:
<MetaBossBuilder modeldir="${designstudio.model.dir}"
ref="Enterprise/systems[CRS]"
gendir="${build.dir}/generatedsource"
classdir="${build.dir}/classes"
libdir="${release.dir}/lib"
implssrcdir="Source">
This attribute tells the builder where to look for the handcoded implementation sources.
Include 'impl' implementation subpackage into the Business Services implementation module as follows:
<BusinessServicesImplementationModule>
<DomainSupportImplementation/>
<GeneratedImplementation type="xmldevsimulator"/>
<IncludeHandcodedImplementation type="impl"/>
</BusinessServicesImplementationModule>
This will package the handcoded classes into the ${metaboss_home}/examples/AlmaMater/Release/lib/BSAlmaMaterCRSImpl.jar
If you find it too complex, simply compile the handcoded source files
and package them into the separate java archive. This archive will have to be placed onto the classpath together with generated jars.
|