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
(Configure & run the adaptor generator)
Line 193: Line 193:
 
### '''Model''': the newly created ''adaptormodel'' in the ''YourProviderProjectName'' project
 
### '''Model''': the newly created ''adaptormodel'' in the ''YourProviderProjectName'' project
 
### '''Target''': The YourProviderProjectName project
 
### '''Target''': The YourProviderProjectName project
 +
### '''Runner''': Acceleo Plug-in Application
 
## Press '''Apply'''
 
## Press '''Apply'''
 
## Press '''Close'''.
 
## Press '''Close'''.

Revision as of 08:58, 16 October 2015

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.

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

  1. In Create 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 Instantiate an adaptor model, you will do the very basic step of creating an empty adaptor EMF model.
  3. In Define your adaptor model, you will model your adaptor specification.
  4. In Configure & run the adaptor generator, you will configure the code generator in order to generate source code for your project - based on the model you have defined.
  5. In Browsing the generated code, you will get an understanding of the overall structure of the generated code.
  6. In Fill in the internal implementation of the adaptor, you will perform the manual coding of the remaining parts of the adaptor
  7. In Run the adaptor, you are ready to run.

Are you interested in initiating an OSLC4J Provider without the use of the code generator? You will find the instructions under Create an OSLC4J project very usuful anyway.

Eclipse Setup

Make sure your environment is setup appropriately as instructed on Eclipse Setup

OSLC4J Project Setup for code generation

Introduction

First of all, decide on the following 2 values for your particular project. In these instructions we will use the following generic values.

* ProjectName: YourProviderProjectName
* PackageName: your.base.package.name

Create an OSLC4J project

This information is based on the tutorial from the MBAT Tutorial on Implementing OSLC Consumers and Providers with OSLC4J

  1. Create a JAVA EE Web Application
    1. File-->New-->Project…
    2. Select Web/Dynamic Web Project
    3. As project name, specify YourProviderProjectName
    4. On the final step of the wizard, check the “Generate web.xml …“ option
    5. Select Finish
  2. Convert project to Maven
    1. Right click on the project, and select Configure --> Convert to Maven Project
    2. In the window that appears, select “war” under Packaging
  3. Configure the project
    1. Create a folder test at the root of the project
    2. Create the sub-folders launches & resources under the new folder test
    3. Copy the 3 configuration files from the Configuration File Templates into the corresponding folders:
      1. /YourProviderProjectName/pom.xml
      2. /YourProviderProjectName/WebContent/WEB-INF/web.xml
      3. /YourProviderProjectName/test/resources/jetty.xml
      4. If necessary, refresh your Eclipse workspace by right clicking on /YourProviderProjectName -> Refresh
    4. Search and replace each of the following keywords with the specific values for your project
      1. ProjectName: YourProviderProjectName
      2. PackageName: your.base.package.name
    5. If you get the error “Project configuration is not up-to-date with pom.xml”, simply right click on the YourProviderProjectName project and select Maven-->Update Project….
  4. Activate Project Facet JAX-RS
    1. Right click the project & Select properties
    2. Open Project Facets
    3. Select JAX-RS (REST Web Services)
    4. Click Further Configuration required…
    5. In the new window that appears
      1. Set Type: Disable Library Configuration
      2. Enter JAX-RS servlet class name: org.apache.wink.server.internal.servlet.RestServlet
      3. Under URL mapping pattern:
        1. Remove the existing one
        2. Add a new one /services/*
  5. Further project configuration
    1. right click the project & select Properties
    2. select Deployment Assembly
    3. Add…
    4. In the new window that appears
      1. select Java Build Path Entries
      2. click Next >
      3. select Maven Dependencies
      4. click Finish
      5. click Apply
      6. click OK
  6. Create a new Run configuration
    1. Select the menu Run-->Run Configurations …
    2. Select Maven Build
    3. Create a new Configuration (Right click on "Maven Build" -> "New")
    4. Enter a name for the new configuration (such as Launch YourProviderProjectName)
    5. Set the Base directory to ${workspace_loc:/ YourProviderProjectName}
    6. Set Goal as jetty:run-exploded
    7. Switch to tab JRE
      1. Set Runtime JRE to Workspace default JRE…
    8. Switch to tab Source
      1. Click Add…
      2. In the new window, select Project and click OK
        1. Check the YourProviderProjectName project
        2. Check the “add required projects of selected projects” option
        3. Click OK
    9. Switch to Tab Common
      1. Select Shared Files
      2. Click Browse…
      3. In the window that appears, select the recently created folder “test/launches” under the YourProviderProjectName project
      4. click OK
    10. Click Apply
    11. Clock Close

Instantiate an adaptor model

  1. Create a new folder adaptorModel in the YourProviderProjectName Project. (This is where the adaptorModel will be created.)
  2. Open the adaptor_interface.ecore model in the org.eclipse.lyo.oslc4j.adaptormodel project (folder model)
  3. Expand the ecore model until the AdaptorInterface EClass
  4. Right-click on the AdaptorInterface EClass & select Create Dynamic Instance …
  5. In the dialog that appears
    1. select the folder adaptorModel under the YourProviderProjectName project as the “parent folder”
    2. choose a suitable File name for the adaptor model - AdaptorInterface.xmi is fine.
  6. Right-click on the newly created AdaptorInterface.xmi file, and select open with --> Other … --> EMF Facet Model Browser.

Eclipse Note: There are 2 ways to open/view/edit the adaptor model, which will be used below:

  • EMF Facet Model Browser: A better interface when creating new EMF instances in the model, as well as being able to jump to specific types of instances within the model.
  • Sample Reflective Ecore Model Editor: A good interface when composing EMF models of other EMF models (See below).

Define your adaptor model

Now that the project is setup, you will specify the desired functionality of your OSLC Adaptor through a graphical model.

The adaptor metal-model being instantiated is illustrated below. It consists of 2 main branches:

  • The left side of the meta-model is a model of the OSLC core resources as defined in the OSLC Core Specification.
  • The right side of the meta-model is a model of a typical OSLC domain specification.

OSLCToolAdaptorMetalModel.png

We will refer to this meta-model to explain how to define your adaptor model instance.

Load existing domain specifications

Note: These steps are optional, but recommended

While an adaptor model can be completely defined from en empty instance, it is recommended to reuse some pre-defined domain specification models. (that is, this step can be skipped if your model uses no standard domain specifications)

  1. In the Project Explorer window, right-click on the newly created AdaptorInterface.xmi file, and select open with --> Other … --> Sample Reflective Ecore Model Editor.
  2. In the newly opened window, right-click and select the context menu Load Resource …
  3. Select Browse Workspace …
  4. Expand the model folder of the org.eclipse.lyo.oslc4j.adaptormodel project.
  5. Select the desired domain specification(s) that you intend to use. (Note that these domain specification models are composed of each other. That is, including one – say ChangeManagement – may indirectly include another – in this case CoreSpecifications.)
  6. Press OK.
  7. Elements of the loaded domain specification models can now be referenced in the AdaptorInterface model you are creating.

Note: At any point when modelling your adaptor, you can repeat the above steps in order to load and use other domain specifications.

Define right-side of adaptor model

  1. Right-click on AdaptorInterface(1) instance and select New Child --> Specification(5)
    1. This instance is a simple container of domain specifications and namespaces. No properties defined.
  2. Recall: as detailed in section Load existing domain specifications, you can always reuse any pre-defined domain specification models. The following steps are only necessary for user-specific domain specifications, that you prefer to embed into your own adaptor model.
  3. Define any number of additional domain specifications. For each such domain specification:
    1. Right-click on the Specification(5) 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")
    2. Right-click on the Specification(5) instance and select New Child --> DomainSpecification(7)
      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(9) and/or ResourceProperty(8) instances as desired.
      3. Note that a Resource instance can refer to ResourceProperties from any other domainSpecification in the model.

Define left-side of adaptor model

  1. In the Project Explorer window, right-click on AdaptorInterface.xmi file, and select open with --> Other … --> EMF Facet Model Browser
  2. In the newly opened window, double-click on the AdaptorInterface(1) EMF instance to open its Properties window, and configure it.
    1. Note: To view and change properties of a model element, you can (a) right-click on the EMF instance within the Instances frame, and select Show Properties View or (b) double-click on the instance.
    2. The properties’ meaning is as follows:
      1. name: the name of your adaptor (for example, use the same name as your project name)
      2. javaClassBaseNamespace: 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.base.package.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”)
  3. Right-click on AdaptorInterface instance and select “New Child --> ServiceProviderCatalog(2)
    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.
  4. Right-click on the ServiceProviderCatalog instance and select “New Child --> Publisher(4)
    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.
  5. Right-click on the ServiceProviderCatalogue instance and select “New Child --> ServiceProvider(3)
    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.
  6. From each of the defined ServiceProviders, proceed down to create and define Services(10) & Capabilities(11,12,13).
    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(11,12,13), make sure you define each of their Resource Types property. (Which are defined either under the Specifiation(5) 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.

Configure & run the adaptor generator

Now that your adaptor is specified in the model, it is time to generate the corresponding code.

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

  1. Define a "run configuration" for adaptor code generation
    1. Select Run --> Run Configurations …
    2. Select Acceleo Application
    3. Press the New launch configuration button
      1. Name: something practical such as Generate YourProviderProjectName
      2. Project: select the org.eclipse.lyo.oslc4j.codegenerator project
      3. Main class: org.eclipse.lyo.oslc4j.codegenerator.main.Generate
      4. Model: the newly created adaptormodel in the YourProviderProjectName project
      5. Target: The YourProviderProjectName project
      6. Runner: Acceleo Plug-in Application
    4. Press Apply
    5. Press Close.
  2. Bug fix – Did you compose your model from other models (section Load existing domain specifications) and reference some of its elements in your adaptor model? Currently, the way EMF models reference each other in the xmi files causes problems with the code generator. Before you trigger the code generator, perform the following steps: (These steps need to be repeated if the adaptor model is later changed to include further references).
    1. Copy the workspace location of any loaded resources (EMF models)
      1. In the Project Explorer window, right-click on the AdaptorInterface.xmi file, and select open with --> Other … --> Sample Reflective Ecore Model Editor.
      2. In the newly opened window, right-click and select the context menu Load Resource …
      3. Select Browse Workspace …
      4. Select the domain specification EMF model that you have earlier loaded.
      5. Copy the path to the xmi file selected into the clipboard (it will be something like platform:/resource/org.eclipse.lyo.oslc4j.adaptormodel/model/someSpecification.xmi)
      6. Press Cancel.
    2. In the Project Explorer window, right-click on the AdaptorInterface.xmi file, and select open with --> XML Editor
    3. Search and replace each href entry that refers to your domain specification.
      1. Replace href values that look like href="../../org.eclipse.lyo.oslc4j.adaptormodel/model/someSpecification.xmi#//... with the copied value (which ought to look more like href="platform:/resource/org.eclipse.lyo.oslc4j.adaptormodel/model/someSpecification.xmi#//...").
    4. Repeat these steps for each domain specification model you have loaded and referenced.
  3. Once you are satisfied with your model, generate the adaptor code
    1. Select Run > Run Configurations …
    2. Select the Generate YourProviderProjectName configuration
    3. Press Run.
  4. 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.base.package.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.base.package.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.base.package.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.base.package.name.servlet
    • Contains necessary classes for the project such as ServiceProviderFactory, ServletListener, etc.
  4. Package: your.base.package.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.
  5. 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.base.package.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