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
(Working with the source code)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
'''''News''''': An alternative graphical modelling approach is now available. See the [[Lyo/ToolchainModellingAndCodeGenerationWorkshop | Graphical Toolchain Modelling and Code Generation Workshop]].
+
#REDIRECT [[Lyo/ToolchainModellingAndCodeGenerationWorkshop | 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.
+
'''''News''''': This workshop is now integrated into the [[Lyo/ToolchainModellingAndCodeGenerationWorkshop | Graphical Toolchain Modelling and Code Generation Workshop]]. The new modelling 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 [https://www.youtube.com/watch?v=nEImx_c6K5U 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: [http://open-services.net/linked-data-and-oslc-tutorial-2015-update/ Linked Data and OSLC Tutorial (2015 Update)]
+
 
+
The steps take you from creating an initial Eclipse project to code generate and run your adaptor.
+
 
+
# In [[Lyo/AdaptorCodeGeneratorWorkshop#Setup_an_OSLC4J_project | 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.
+
# In [[Lyo/AdaptorCodeGeneratorWorkshop#Develop_OSLC4J_adaptor_through_the_EMF_model | 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 [[Lyo/AdaptorCodeGeneratorWorkshop/EclipseSetup | Eclipse Setup]]
+
 
+
= Sample Project =
+
 
+
As a complement when following the instructions below, this [[Media:OSLC4JSampleAdaptor.zip | 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 [[Lyo/creating_OSLC4J_project#Setup_an_OSLC4J_project | 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 [[Media:OSLC4JSampleAdaptor.zip | sample OSLC4J project]] discussed [[Lyo/AdaptorCodeGeneratorWorkshop#Sample Project | above]] can also be used as a starting point to build your own model instead.
+
 
+
== Instantiate an adaptor model ==
+
# For convenience, create a new folder ''adaptorModel'' in the ''YourProviderProjectName'' Project, in order to store the adaptor EMF model in.
+
# Right-click on the ''adaptorModel'' folder, and select '''New-->Other...'''
+
## In the Wizards window, search and select ''Adaptorinterface Model'', then press '''Next'''
+
## choose a suitable file name for the adaptor model, then press '''Next'''
+
## For '''Model Object''', select ''Adaptor Interface'', then press '''Finish'''
+
# 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 [http://open-services.net/bin/view/Main/OslcCoreSpecification?sortcol=table;up=#Service_Provider_Resources 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.
+
 
+
[[File:OSLCToolAdaptorMetalModel.png]]
+
 
+
=== Define the Domain Specifications ===
+
# In the EMF editor, expand the model to view the '''AdaptorInterface''' instance.
+
# Right-click on '''AdaptorInterface(1)''' instance and select '''New Child -->''' '''Specification(2)'''
+
## This instance is a simple container of domain specifications and namespaces. No properties defined.
+
# 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:
+
## Right-click on the '''Specification(2)''' instance and select '''New Child -->''' '''NamespacePrefix(6)'''
+
### 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.)
+
## Right-click on the '''Specification(2)''' instance and select '''New Child -->''' '''DomainSpecification(5)'''
+
### For the newly created DomainSpecification instance, fill-in its properties. (Note that the namespacePrefix property refers to an instance of NamespacePrefix(6))
+
### Define '''Resource(8)''' and/or '''ResourceProperty(7)''' instances as desired.
+
### Note that a Resource instance can refer to ResourceProperties from any other domainSpecification in the model.
+
 
+
=== Define the Server ===
+
# Select the '''AdaptorInterface(1)''' EMF instance and configure its Properties.
+
## The properties’ meaning is as follows:
+
### ''name'': the name of your adaptor (for example, use the same name as your project name)
+
### ''java Class Base Namespace'': the name of the base Java root package from which the code of your adaptor will be generated.
+
#### Make sure that this value matches ''your.basepackage.name'' selected above.
+
### ''Java Files Base Path'': The path of where java files will be generated. (for example, ''/src/'')
+
### ''Javascript Files Base Path'': The path of where javascript files will be generated. (for example, ''/WebContent'')
+
### ''Jsp Files Base Path'': The path of where the Jsp files will be generated. (for example, ''/WebContent'')
+
# Right-click on AdaptorInterface instance and select '''New Child -->ServiceProviderCatalog(3)'''
+
## For the newly created catalog, fill-in all its properties as defined according to OSLC.
+
## Note that you can only define 1 catalogue in an adaptor.
+
# Right-click on the ServiceProviderCatalog instance and select '''New Child -->Publisher(9)'''
+
## For the newly created Publisher, fill-in all the Publisher properties as defined according to OSLC.
+
## Note that you can only define 1 Publisher for a catalog.
+
# Right-click on the ServiceProviderCatalogue instance and select '''New Child -->ServiceProvider(10)'''
+
## For the newly created ServiceProvider, fill-in the ServiceProvider properties (Title, Description) as defined according to OSLC.
+
## (optional) To control the relative URLs used in the ServiceProvider web service, specify the following optional properties:
+
### 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").
+
### 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}".
+
## Note that you can define one-or-many ServiceProviders for a ServiceProviderCatalogue.
+
# From each of the defined ServiceProviders,  proceed down to create and define '''Services(11)''' & '''Capabilities(12)'''.
+
## Make sure you fill-in all properties of each EMF instance you create.
+
## Make sure you satisfy the cardinality of each of the containment relationships as illustrated in the figure above.
+
## 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 [[Lyo/AdaptorCodeGeneratorWorkshop#Define_right-side_of_adaptor_model | Define right-side of adaptor model]]), or exist as part of a loaded domain specification (see section [[Lyo/AdaptorCodeGeneratorWorkshop#Load_existing_domain_specifications | Load existing domain specifications]]).)
+
## (optional) To control the relative URLs used in the web service handling a particular resource, create a BasicCapability with the following properties:
+
### 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).
+
### 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:
+
# right-click on '''AdaptorInterface(1)''' instance and select '''New Child -->Modelled Required Adaptor(14)'''
+
# For the newly created Required Adaptor instance, fill-in its properties.
+
## Define the URI of the Service Provider Catalog
+
## 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:
+
# right-click on '''AdaptorInterface(1)''' instance and select '''New Child -->Generic Required Adaptor(14)'''
+
# For the newly created Required Adaptor instance, fill-in its properties.
+
## Define a name of the server
+
## Define the URI of the Service Provider Catalog
+
## 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.
+
 
+
# select and open the adaptor model
+
# Select the menu item '''Adaptorinterface Editor --> Validate'''
+
# 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:
+
 
+
# 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.
+
# 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.
+
# Package: '''''your.basepackage.name''.servlet'''
+
#* Contains necessary classes for the project such as ServiceProviderFactory, ServletListener, etc.
+
# 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.
+
#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.
+
# 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.
+
# Select the menu '''Run-->Run Configurations ...'''
+
# Select the newly created configuration
+
# 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
+
 
+
= Known bugs and workarounds =
+
 
+
== Problems when composing models ==
+
Did you compose your model from other models (section '''[[Lyo/AdaptorCodeGeneratorWorkshop#TIPS_-_Reusing_existing_domain_specifications | TIPS - Reusing 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).
+
 
+
# Copy the workspace location of any loaded resources (EMF models)
+
## In the ''Project Explorer'' window, right-click on the ''AdaptorInterface.xmi'' file, and select '''open with --> Other … --> Sample Reflective Ecore Model Editor'''.
+
## In the newly opened window, right-click and select the context menu '''Load Resource …'''
+
## Select '''Browse Workspace...'''
+
## Select the domain specification EMF model that you have earlier loaded.
+
## 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'')
+
## Press '''Cancel'''.
+
# In the Project Explorer window, right-click on the ''AdaptorInterface.xmi'' file, and select '''open with --> XML Editor'''
+
# Search and replace each ''href'' entry that refers to your domain specification.
+
## 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#//..."'').
+
# Repeat these steps for each domain specification model you have loaded and referenced.
+

Latest revision as of 14:22, 23 October 2016

News: This workshop is now integrated into the Graphical Toolchain Modelling and Code Generation Workshop. The new modelling approach supports the modelling of a complete toolchain (including interactions between OSLC servers and clients), as well as a single server and/or client.

Back to the top