Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

COSMOS SDD Tooling Examples

This page contains examples of how to use various functions of the SDD tooling. Please use these examples as references as you create your own applications. Prior knowledge of the SDD is assumed.

SDD Programmatic Interface

The SPI is used to read and write SDDs with a Java interface. These examples will take the reader through reading, writing, and creating SDDs.

Creating SDDs

The SPI is controlled through one instance of a session. In order to use any methods in the SPI, a session must first be created.

SPISession session = SPISession.DEFAULT_INSTANCE;

The SPI objects for the most part correspond to the SDD types. These objects are created from factory objects, so let's create these first.

BaseFactory baseFactory = session.createBaseFactory();
ContentUnitFactory cuFactory = session.createContentUnitFactory();
ArtifactFactory artifactFactory = session.createArtifactFactory();

Each package of the SPI APIs have a factory class. To create an SPI object, all required elements and attributes of the SPI object must be passed into the factory method. This means we'll be creating our deployment descriptor close to the end. Let's create our install artifact first.

Artifact install = artifactFactory.createInstallArtifact();
install.setContentReference("installArtifact");

This sets up our install artifact and sets the content reference to "installArtifact" which will map to one of the contents in the package descriptor. Next we'll add some additional content:

Collection<AdditionalContent> additionalContents = new ArrayList<AdditionalContent>();
additionalContents.add(artifactFactory.createAdditionalContent("bom"));
AdditionalContent additionalContent = artifactFactory.createAdditionalContent("readme");
additionalContent.setType("readme");
additionalContents.add(additionalContent);
install.setAdditionalContents(additionalContents);

A Collection of AdditionalContent types was created and two AdditionalContent objects were created through the artifact factory. The createAdditionalContent method requires the content reference to be defined, which also must match an entry in the package descriptor. All required elements and attributes of the SDD types will be required for the factory methods as well in order to create that type. The final step was to call the appropriate setter method on the install artifact for the additional content.

Now that we have an artifact, we can create our installable unit. Remember that installable units require artifacts.

InstallableUnit iu = cuFactory.createInstallableUnit("IU_ID", "IU_TARGET_REF", install);

We pass in our newly created install artifact to the factory method to create our install artifact.

One of the last objects we need to create are the resources in the topology.

Collection<Resource> resources = new ArrayList<Resource>();
Resource resource = baseFactory.createResource("OS", "OperatingSystem");
resource.setName("Windows Vista");
resource.setDescription(new TranslatableString("The operationg system of the computer.", "osDesc"));
resource.setShortDescription(new TranslatableString("Computer's OS", "osShortDesc"));
resources.add(resource);

Here we have added one resource to our SDD. The factory method takes the reference ID and then the resource type as parameters. In the two description elements, we've introduced the ability for the SDD to handle translatable strings. The first parameter is the default string. The second parameter is the translation key in the properties file that will accompany the SDD.

Now we'll create our final object:

byte b[] = {127, 43, 65, 119, 19, 90, 87, 2, 45, 73, 25, 41, 76, 14, 54, 93};
DeploymentDescriptor dd = baseFactory.createDeploymentDescriptor("1.0", b, 
     Calendar.getInstance().getTime(), iu, resources);

We have everything we need and we finally create the deployment descriptor object. We pass in the schema version (usually 1.0), the descriptor UUID, last modified time, our installable unit, and our resources. Similar techniques can be used to create the package descriptor and add additional elements to the SDD.

Reading SDDs

Using only DOM and the SPI

For reading an SDD, we first need a DOM document. There's a few things I like to setup before reading the actual file into memory.

DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setValidating(false);
docBuilderFactory.setNamespaceAware(true);

DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
docBuilder.setErrorHandler(new ErrorHandler()
{
    public void warning(SAXParseException e) throws SAXException {
        printErrorMessage(e);
    }

    public void error(SAXParseException e) throws SAXException {
        printErrorMessage(e);
    }

    public void fatalError(SAXParseException e) throws SAXException {
        printErrorMessage(e);
    }
            
    private void printErrorMessage(SAXParseException e)
    {
        System.out.println("Line: " + e.getLineNumber() + ": " + e.getMessage());
    }
});

With that all set, we'll create the Document object.

Document doc = docBuilder.parse(new InputSource("mySDD.xml"));

And now our deployment descriptor.

SPISession session = SPISession.DEFAULT_INSTANCE;
DeploymentDescriptor dd = (DeploymentDescriptor) session.buildDescriptorFromDocument(doc);

At this point, you can run through all the getter methods to get at the data you need to read.

Using the Validator

The validator has methods to read files from the disk to provide you with a Document object.

SDD_DAS sddDas = new SDD_DASImpl();
Document doc = sddDas.loadDocument(new FileInputStream("mySDD.xml"));
SPISession session = SPISession.DEFAULT_INSTANCE;
DeploymentDescriptor dd = (DeploymentDescriptor) session.buildDescriptorFromDocument(doc);

Writing SDDs

Using only DOM and the SPI

Once you've either created an SDD or read one in to change some values, you probably want to write it back to the system. Let's setup some DOM objects first.

DOMImplementationRegistry domRegistry = DOMImplementationRegistry.newInstance();
DOMImplementationLS domImpl = (DOMImplementationLS) domRegistry.getDOMImplementation("LS");
LSSerializer serializer = domImpl.createLSSerializer();
serializer.getDomConfig().setParameter("format-pretty-print", true);

This will format our xml like we're used to seeing. Otherwise you may see everything on one line. Now we write it to a file.

Document doc = dd.getOwnerDocument();
FileWriter fw = new FileWriter("mySDD.xml");
BufferedWriter bw = new BufferedWriter(fw);

bw.write(lsSerializer.writeToString(doc));
bw.close();

The dd object here is our deployment descriptor.

Using the Validator

The SDD Validator has methods to write documents to the disk. This will write the SDD to the file mySDD.xml. The null parameter corresponds to the encoding, which defaults to UTF-8. The false parameter tells the validator to save the SDD without validating.

SDD_DAS deploymentDescriptorDAS = new SDD_DASImpl();
deploymentDescriptorDAS.saveDocument(dd.getOwnerDocument(), new FileOutputStream("mySDD.xml"), null, false);

Validator

The validator is used to verify the SDD follows the constraints of the schema. It also allows you to specify your own rules to constrain the SDD. First, we'll look at the easiest way to validate the SDD against the schema.

SDD_DAS deploymentDescriptorDAS = new SDD_DASImpl();
Collection<XMLValidationError> validationErrors = deploymentDescriptorDAS.validate(document);
if (validationErrors.size() > 0) 
{
	for (XMLValidationError error : validationErrors) {
		System.err.println(error.getErrorMessage());
	}
}

Using custom rules

If a custom rule is desired, we'll need to create a rule that the validator can understand. To do that, we create a class that implements ValidationRule. ValidationRule has one method to implement.

public Collection<XMLValidationError> validate(InputStream xmlStream)

It receives an InputStream and returns a collection of XMLValidationError objects. Let's take a look at a sample rule.

public class SchemaVersionValidationRule implements ValidationRule 
{
  String schemaVersion;

  public SchemaVersionValidationRule(String schemaVersion) 
  {
    this.schemaVersion = schemaVersion;
  }

  public Collection<XMLValidationError> validate(InputStream xmlStream) 
  {
    Collection<XMLValidationError> validationErrors = new Vector<XMLValidationError>();

    SDD_DAS sddDas = new SDD_DASImpl();
    Document ddDocument = null;
    try
    {
      ddDocument = sddDas.loadDocument(xmlStream);
    }
    catch (Exception e)
    {
      e.printStackTrace();
      System.exit(1);
    }

    Element dd = ddDocument.getDocumentElement();
    String ddSchema = dd.getAttribute("schemaVersion");

    if (!ddSchema.equals(schemaVersion))
    {
      String errorMsg = "The schema version is not " + schemaVersion;
      validationErrors.add(new XMLValidationError(errorMsg, -1, -1, this, XMLValidationError.ERROR));
    }

    return validationErrors;
  }		
}

This custom rule looks at the schema version in the SDD and returns an error if the wrong version is specified. The constructor of the rule is where we specify the version of the schema we want to see in the SDD. Next is the validate method. We setup the Collection of XMLValidationError types first. Then we get the Document object of our SDD. After that, we get the document element and from that we get the schemaVersion element. We compare this against the version passed into the constructor. If they are different, we create a new XMLValidationError object and add it to the collection. Then we return the collection of errors.

To call this custom rule as a part of our normal validation, we do the following.

SDD_DAS ddDAS = new SDD_DASImpl();
ValidationRule customValidationRule = new SchemaVersionValidationRule("1.0");
ddDAS.addValidation(customValidationRule);

Collection<XMLValidationError> validationErrors = ddDAS.validate(ddDocument);
for (XMLValidationError error : validationErrors) 
{
  System.err.println(error.getErrorMessage());
}

Back to the top