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

Difference between revisions of "Lyo/AdaptorCodeGeneratorWorkshop"

< Lyo
(Known bugs and workarounds)
(TIPS - Reusing existing domain specifications)
Line 171: Line 171:
 
# Select the newly created configuration
 
# Select the newly created configuration
 
# Click '''Run'''
 
# Click '''Run'''
 
= TIPS - Reusing existing domain specifications =
 
While an adaptor model can be completely defined from scratch, it is possible to compose a model from existing model parts, such as predefined standard domain specification models.
 
# In the EMF editor, right-click and select the context menu '''Load Resource...'''
 
# Select '''Browse Workspace...'''
 
# Select the desired domain specification(s) that you intend to use. (See subsection below for examples)
 
# Press '''OK'''.
 
# Elements of the loaded domain specification models can now be referenced in the adaptor model you are creating.
 
 
== OSLC Core and Domain Specifications ==
 
The project ''adaptormodel'' in the Lyo Core repository git://git.eclipse.org/gitroot/lyo/org.eclipse.lyo.core.git, contains the following OSLC standard Specifications:
 
* OSLC Architecture Management
 
* OSLC Change Management
 
* OSLC Core Specification
 

Revision as of 15:11, 21 October 2016

News: An alternative graphical modelling approach is now available. See the Graphical Toolchain Modelling and Code Generation Workshop.

  • The approach supports the modelling of a complete toolchain (including interactions between OSLC servers and clients), as well as a single server and/or client.
  • The prototype is however under development and its features may change over time.

Introduction

The instructions below guide you through the process of developing an OSLC4J provider using a code generator. The generated code is based on a specification of your adaptor model, as defined by an EMF model.

A general demonstration of the code generator can be found here.

Working with a model of the adaptor allows you to work at a higher level of abstraction, without needing to deal with all the technical details of the OSLC standard (such as Linked Data, RDF, etc.). However, a basic understanding of the Linked Data and OSLC concepts remains necessary in order to build a valid model. For an introduction to Linked Data and OSLC, the following resources on open-services.net can be recommended: Linked Data and OSLC Tutorial (2015 Update)

The steps take you from creating an initial Eclipse project to code generate and run your adaptor.

  1. In Setup an OSLC4J project, you will create an empty project that is configured to start developing an OSLC4J adaptor. The instructions target the Lyo code generator. Yet, after these steps, you may also be able to proceed with manually developing your adaptor.
  2. In Develop OSLC4J adaptor through the EMF model, you will specify your adaptor functionality through an EMF model, from which almost complete code will be generated.

But first, make sure your environment is setup appropriately as instructed on Eclipse Setup

Sample Project

As a complement when following the instructions below, this sample OSLC4J project contains a basic but complete adaptor model that can be used as a starting point and/or a reference. The project has a complete setup, as well as a small enough adaptor model to generate complete but compilable code.

Setup an OSLC4J project

Create and setup an Eclipse OSLC4J project as instructed under Setup an OSLC4J project. The project will then be populated with the generated code needed.

Develop OSLC4J adaptor through the EMF model

From the above steps, you can proceed and manually develop the necessary java classes that correspond to the OSLC resources and the services for your adaptor. Alternatively, you can specify the desired functionality of your OSLC Adaptor - at a higher level of abstraction - through a graphical EMF model. From such a model, the Lyo Code Generator can then produce the bulk of the code necessary to realize the modeled functionality.

Note: The sample OSLC4J project discussed above can also be used as a starting point to build your own model instead.

Instantiate an adaptor model

  1. For convenience, create a new folder adaptorModel in the YourProviderProjectName Project, in order to store the adaptor EMF model in.
  2. Right-click on the adaptorModel folder, and select New-->Other...
    1. In the Wizards window, search and select Adaptorinterface Model, then press Next
    2. choose a suitable file name for the adaptor model, then press Next
    3. For Model Object, select Adaptor Interface, then press Finish
  3. the adaptor model is now created, and is opened using a basic EMF editor.

Define the adaptor model

You can now specify the desired functionality of your OSLC Adaptor through the graphical model.

The adaptor model is an instance of the metal-model illustrated below (For clarity, not all properties are illustrated in the diagram). We will refer to this meta-model to explain how to define your adaptor model instance.

The model consists of 3 main parts:

  • Domain Specification - Modelling the OSLC domain specification(s) to be exposed and/or consumed by the adaptor, as defined in the OSLC Core Specification.
  • Server - modelling the OSLC resources - and their corresponding services - to be exposed by the adaptor.
  • Client - modelling the interactions - as a client - that the adaptor might have with other OSLC servers.

OSLCToolAdaptorMetalModel.png

Define the Domain Specifications

  1. In the EMF editor, expand the model to view the AdaptorInterface instance.
  2. Right-click on AdaptorInterface(1) instance and select New Child --> Specification(2)
    1. This instance is a simple container of domain specifications and namespaces. No properties defined.
  3. Define any number of additional domain specifications. (For example, the OSLC RM domain specification defines the namespace URI of http://open-services.net/ns/rm# with a preferred namespace prefix of oslc_rm. You can here define your own specific domains.) For each such domain specification:
    1. Right-click on the Specification(2) instance and select New Child --> NamespacePrefix(6)
      1. For the newly-created NamespacePrefix, simply provide the prefix for the new domain specification (Note: To view and change properties of a model element, you can (a) right-click on the EMF instance, and select "Show Properties View" or (b) double-click on the instance.)
    2. Right-click on the Specification(2) instance and select New Child --> DomainSpecification(5)
      1. For the newly created DomainSpecification instance, fill-in its properties. (Note that the namespacePrefix property refers to an instance of NamespacePrefix(6))
      2. Define Resource(8) and/or ResourceProperty(7) instances as desired.
      3. Note that a Resource instance can refer to ResourceProperties from any other domainSpecification in the model.

Define the Server

  1. Select the AdaptorInterface(1) EMF instance and configure its Properties.
    1. The properties’ meaning is as follows:
      1. name: the name of your adaptor (for example, use the same name as your project name)
      2. java Class Base Namespace: the name of the base Java root package from which the code of your adaptor will be generated.
        1. Make sure that this value matches your.basepackage.name selected above.
      3. Java Files Base Path: The path of where java files will be generated. (for example, /src/)
      4. Javascript Files Base Path: The path of where javascript files will be generated. (for example, /WebContent)
      5. Jsp Files Base Path: The path of where the Jsp files will be generated. (for example, /WebContent)
  2. Right-click on AdaptorInterface instance and select New Child -->ServiceProviderCatalog(3)
    1. For the newly created catalog, fill-in all its properties as defined according to OSLC.
    2. Note that you can only define 1 catalogue in an adaptor.
  3. Right-click on the ServiceProviderCatalog instance and select New Child -->Publisher(9)
    1. For the newly created Publisher, fill-in all the Publisher properties as defined according to OSLC.
    2. Note that you can only define 1 Publisher for a catalog.
  4. Right-click on the ServiceProviderCatalogue instance and select New Child -->ServiceProvider(10)
    1. For the newly created ServiceProvider, fill-in the ServiceProvider properties (Title, Description) as defined according to OSLC.
    2. (optional) To control the relative URLs used in the ServiceProvider web service, specify the following optional properties:
      1. serviceNamespace - specifies the relative URL for the ServiceProvider JAX-RS Service. For example, "projects" will lead to the url "http://localhost:8080/YourAdaptor/services/projects". The default is "serviceProviders" (leading to the default "http://localhost:8080/YourAdaptor/services/serviceProviders").
      2. instanceID - specifies the relative URL of a single service provider, including the parameter variables necessary to identify a specific service provider. For example, "{projectId}" leads to the url "http://localhost:8080/YourAdaptor/services/projects/1" mapping the value 1 to the projectId parameter in the java code. Other IDs can be "collectionName/{collectionName}/project/{projectName}". The default is "{serviceProviderId}".
    3. Note that you can define one-or-many ServiceProviders for a ServiceProviderCatalogue.
  5. From each of the defined ServiceProviders, proceed down to create and define Services(11) & Capabilities(12).
    1. Make sure you fill-in all properties of each EMF instance you create.
    2. Make sure you satisfy the cardinality of each of the containment relationships as illustrated in the figure above.
    3. When defining the properties of Capabilities(12), make sure you define each of their Resource Types property. (Which are defined either under the Specifiation(2) EMF instance (see section Define right-side of adaptor model), or exist as part of a loaded domain specification (see section Load existing domain specifications).)
    4. (optional) To control the relative URLs used in the web service handling a particular resource, create a BasicCapability with the following properties:
      1. serviceNamespace - specifies whether the relative URL of the resource web service should include the URL of its managing service provider (relativeToServiceProvider), or it should be standalone (independantOfServiceProvider).
      2. instanceID - specifies the relative URL of a single resource, including the parameter variables necessary to identify a specific resource. For example, "{changeRequestId}" leads to the url "http://localhost:8080/YourAdaptor/services/changeRequests/1" mapping the value 1 to the changeRequestId parameter in the java code.

Define the Client(s) Interactions

Currently, the model supports a simple definition of client interactions, by either linking to another adaptorInterface model, or simply listing the set of resources the adaptor expects from its required server.

To define a client interaction with an adaptor for which a model already exists:

  1. right-click on AdaptorInterface(1) instance and select New Child -->Modelled Required Adaptor(14)
  2. For the newly created Required Adaptor instance, fill-in its properties.
    1. Define the URI of the Service Provider Catalog
    2. Define the AdaptorInterface that this client represents.
      • Tips: Instead of modelling all adaptors in a single model, you can instead link to an adaptorInterface defined in another model: (a) right-click in an empty are of the diagram and select the context menu Load Resource... (b) Select Browse Workspace... (c) Select the desired adaptorInterface model that you intend to use. Elements of the loaded model can now be referenced in the adaptor model you are creating.

To define a client interaction with an adaptor that is simply modelled by the set of resources it exposes:

  1. right-click on AdaptorInterface(1) instance and select New Child -->Generic Required Adaptor(14)
  2. For the newly created Required Adaptor instance, fill-in its properties.
    1. Define a name of the server
    2. Define the URI of the Service Provider Catalog
    3. Define the set of Resources(9) that the client expects the server to expose.

Validate the adaptor model

Once the adaptor model is defined, validate it to ensure all required properties are defined as expected.

  1. select and open the adaptor model
  2. Select the menu item Adaptorinterface Editor --> Validate
  3. If any, deal with any error messages that appear.

Generate the adaptor code

Once the adaptor model is defined and validated, you can generate the corresponding code through the following simple step:

Right-click on the adaptor model, and select Acceleo Model to Text --> Generate CodeGenerator

Note: The code generator supports an incremental development of the adaptor model. Any manual changes to the generated code (within designated placeholders) are maintained upon a subsequent change in the adaptor model, and resulting code re-generation.

Upon a successful code generation, all the necessary Java classes for a complete ready-to-run OSLC4J project are produced. The next section gives an overview of the generated code, before proceeding with an explanation of the necessary manual code to be provided.

Browsing the generated code

Besides the AdaptorManager class (see next section), all generated classes have complete functionality, and need not be modified nor complemented with additional manual code. However, the classes contain placeholders that allow the developer to insert additional code and hence modify the generated default code where necessary. such manual code remains intact after subsequent generations, if modifications are placed within the designated placeholders. This allows for the incremental development of the adaptor model, and its resulting code.

  • To illustrate, open a class file in the package your.basepackage.name.resources, and note the following placeholder:
// Start of user code imports
// End of user code
  • Any code entered between these two lines of code is maintained across subsequent generations. In this example, the placeholder is intended for developer-specific imports, but any Java code can be inserted.

The following Java classes are generated based on the adaptor specification model:

  1. Package: your.basepackage.name.resources
    • for each OSLC-resource of relevance to your project, a corresponding Java class is defined. The class includes the appropriate OSLC annotations, instance attributes, getters, setters, etc.
    • Which resource classes are generated? Each resource for which an OSLC-service is defined; as well as - recursively - the resource extending such a resource, and the resources defined for any of its attributes. that is, all resources needed.
  2. Package: your.basepackage.name.services
    • this package contains the JAX-RS classes corresponding to the resource services defined in the model, as well as those for the ServiceProvider and ServiceProviderCatalog.
    • Each JAX-RS class contains the necessary methods that correspond to Query Capabilities, Creation Factories, Dialogs, as well as the CRUD methods to interact with resources - as defined in the adaptor model.
    • Each JAX-RS class contains methods to respond to both HTML and RDF/XML requests.
  3. Package: your.basepackage.name.servlet
    • Contains necessary classes for the project such as ServiceProviderFactory, ServletListener, etc.
  4. Package: your.basepackage.name.clients
    • for each required adaptor, a corresponding Java class is defined.
    • Currently, the class simply provides a GET method for each resource provided by the required server. This class is a starting point to explore the remaining functionality provided by the OslcClient class, and its methods will be expanded in the future.
  5. Package: your.basepackage.name
    • The AdaptorManager class contains the set of methods that will ultimately communicate with the source tool to access its internal data, and eventually expose information as OSLC resources.
    • Only skeletons of the methods are generated. it remains the task of the developer to manual code these methods, as detailed in the next section.
  6. Jsp pages are also generated to handle HTML requests, in the folder webcontent/your/base/package/name. These pages are very useful for debugging purposes:
    • resource presentations
    • query results
    • creation dialogs
    • selection Dialogs
    • ServiceProvider presentations
    • ServiceProviderCatalog presentations

Fill in the internal implementation of the adaptor

The manual code the developer needs to implement is concentrated in a single class - the AdaptorManager class (in the your.basepackage.name package). The methods that need to be provided are:

  • contextInitializeServletListener & contextDestroyServletListener - to implement any application initialisation and termination activities such as establishing a connection to a database.
  • getServiceProviderInfos - returns the set of ServiceProviders
  • for each serviced resource, methods to get, create, search and query such resources.

Run the adaptor

Once the manual code is completed, You are now ready to run the adaptor.

  1. Select the menu Run-->Run Configurations ...
  2. Select the newly created configuration
  3. Click Run

Back to the top