MetaBoss
User Guides
Synopsis
Beginner's Guide
Configuration Guide
Design Studio Guide
Programming Model Guide
Testing Framework Guide
'How To ...' Guides
References
Synopsis
Design Model Reference
Design Model UML Profile
Test Schema Reference
MetaBoss design library
Run-time libraries API
Dev-time libraries API
HatMaker Example
Synopsis
Enterprise Model Description
Enterprise Model Reference
SystemTest Example
WebServices Example
Miscellaneous
About MetaBoss
Quality Assurance
Compatibility Notes
Acknowledgments
Glossary
Change Log
Version 1.4.0001
Built on 15 Dec 2005 22:31:47

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:

  1. The actual interface implementation class. It must be a non-abstract class which implements the entire interface (ie. all methods must be implemented).
  2. 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:

  1. Create the directory for the handcoded source. We use ${metaboss_home}/examples/AlmaMater/Source

  2. 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.

  3. 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.

  4. 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:

    1. 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.
    2. Obtain access to one or more Domain objects (ie. establish database connections) using JNDI lookup.
    3. Navigate to the desired domain objects or build a collection of the desired domain objects. This is where the most interesting stuff happens!
    4. 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.
    5. Build result structure and return. This step is only necessary if there is an output data.

  5. 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:

Handcoded source directory structure.

Building and packaging the handcoded implementation

Having created implementation classes you could build and package them in one of two ways:

  1. 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

  2. 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.