JBoss.orgCommunity Documentation

Chapter 4. Developing a Validator

4.1. Create the Validator OSGi bundle
4.2. Establish Bundle Dependencies
4.3. Implement the Module
4.4. Implement the Tests
4.5. Create the Maven POM

This section will describe how to create a validator as part of the Scribble project structure. The same approach can also be used to create a validator module outside the scope of the Scribble project.

To explain how to create a validator, we will use the 'connectedness' validator as an example.

This section will explain how to create the OSGi bundle, for the validator, from within the Eclipse environment.

The first step is to create the plugin project, using the New->Project->Plugin Project menu item. When the dialog window is displayed, uncheck the "Use default location" checkbox, and browse to find the appropriate location for the new project.

For this project, the location will be the tools/bundles/org.scribble.validator.connectedness folder within the Scribble project structure. It will be necessary to create the folder for the org.scribble.validator.connectednesss part of the location - the folder being named after the OSGi bundle identity.

Ensure the 'Create java project' checkbox is ticked, and then set the source folder to be src/main/java and set the Target Platform to a standard 'OSGi Framework'.

Then press the Next button to set some details associated with the plugin, such as the version, description, provider, etc.

In this example, we will be registering the validator using the OSGi registerService method. This is performed in the bundle activator, whose class is set in the plugin details. For example, in the start method of the created Activator, we would have:

	public void start(BundleContext context) throws Exception {
        Properties props = new Properties();
        
        ProtocolValidator validator=new ConnectednessValidator();
        
        context.registerService(ProtocolValidator.class.getName(), 
				validator, props);
	}		
		

Depending on the type of bundle being developed, it may have a different set of dependencies than the ones required by this 'connectedness' validator. However the configuration approach will be the same.

Go to the META-INF/MANIFEST.MF file and select it. This will cause the plugin manifest editor to be displayed.

Select the Dependencies tab and select the other bundles that will be required, or preferrably select the packages to be imported (as this avoids dependency on specific bundles, and instead just identifies the packages required). For this example validator, we just need to add the packages from the org.scribble.common bundle which is used by all Scribble plugins. However if additional packages were required, then they could be added as imported packages.

Each module will be different, and therefore discussing specific implementation details will not be possible.

However validation modules will tend to access the complete model, but possibly only be interested in certain parts of it. Therefore usually the validation modules will define an implementation of the org.scribble.protocol.model.Visitor interface.

The actual main class within the validator module would implement the org.scribble.protocol.validation.ProtocolValidator interface.

There may also exist specialised implementations of the ProtocolValidator interface that help support the validation process. For example, the ProtocolComponentValidator which triggers a ProtocolComponentValidatorRule based on the type of the model component. The visitor is used to traverse the model to identify the model components being validated. So its possible, if validation of only a couple of model component types is required, to derive a specialisation of the ProtocolComponentValidator class with the relevant rule implementations.

Tests can be implemented in two ways, depending upon the nature of the bundle.

If the bundle is representing an implementation of a common interface, where the result returned from the bundle is the key point, then integration tests associated with the interface can be useful.

For example, there is a special bundle used to provide a Conformance Test Kit for the protocol parser, projector and monitor. This means that the same set of integration tests can be used regardless of the implementation of those components being used.

The other set of tests that are useful are specific to the bundle implementation. In standard Java plugins, these tests will usually be provided within the bundle itself, by defining the JUnit test classes within the src/java location, with any required resources being placed in src/resources.

However using Tycho to build the plugins and OSGi bundles means that it is better to locate these bundle implementation specific tests in a companion test plugin located in the tools/tests sub-folder.

The next step is to create the JUnit test. First create the appropriate package within the src/java location.

Then select the New->Other->JUnit Test Case menu item associated with the package. When this is first performed, you will be asked which version of JUnit should be used. Select the New JUnit 4 radio button.

After pressing the Next button, you will be asked about adding JUnit to the classpath.

Choose the Open the build path property page option and press the Ok button. The reason for not adding JUnit directly, is that this would cause it to be included in the list of bundle dependencies in the OSGi manifest, which would mean that the runtime environment that includes the validator would also have a dependency on JUnit.

Therefore we need to add the JUnit jars to the Eclipse project in a different way. In the build path dialog, select the Libraries tab and then select the Add Library button. When the list of libraries is presented, select the JUnit entry and press Next where the JUnit version should be set to JUnit4 and then press the Finish button.

We need to create a pom.xml for both the main plugin (or OSGi bundle) and the test plugin.

The best approach is to copy the pom.xml file from one of the other modules, and simply update the relevant sections (e.g. artifact id, description and dependencies).

Once the pom.xml for the module has been defined, it needs to be linked into the pom.xml of its parent. This is tools/bundles for the main bundle, and tools/tests for the test plugins.