Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions jamopp.doc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Dependencies
/node_modules

# Production
/build

# Generated files
.docusaurus
.cache-loader

# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
41 changes: 41 additions & 0 deletions jamopp.doc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Website

This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.

### Installation

```
$ npm
```

### Local Development

```
$ npm start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

### Build

```
$ npm build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### Deployment

Using SSH:

```
$ USE_SSH=true npm deploy
```

Not using SSH:

```
$ GIT_USER=<Your GitHub username> npm deploy
```

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
3 changes: 3 additions & 0 deletions jamopp.doc/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};
3 changes: 3 additions & 0 deletions jamopp.doc/docs/development/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Development

Interested in contributing to / developing the extended JaMoPP? Within this section, we provide guidance on its development.
4 changes: 4 additions & 0 deletions jamopp.doc/docs/development/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"position": 5,
"label": "Development"
}
30 changes: 30 additions & 0 deletions jamopp.doc/docs/development/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
sidebar_position: 1
sidebar_label: Setup
---

# Setup

To setup your system / IDEs for developing the extended JaMoPP, you can follow these instructions.

## Eclipse IDE (for Code)

Currently, only the Eclipse IDE is supported for developing the extended JaMoPP.

1. The code requires Java 17 and the Eclipse Modeling Tools 2022-12 with the Maven plugin (needs manual installation) since the project is organized with pure Maven modules.

Hint: You can install the Maven plugin by opening the software installation panel (menu "Help" -> "Install New Software"). Then, you can show a list of update sites for the field "Work with:". From this list, select "2022-12 - https://download.eclipse.org/releases/2022-12", search for "Maven", and select "M2E - Maven Integration for Eclipse" for installation. Afterward, proceed with the installation.
1. After Eclipse is prepared, the Maven modules of the extended JaMoPP can be easily imported from the top-level directory into Eclipse. However, the source code for the Java metamodel is not generated yet.
1. There are two possibilities to generate the source code for the metamodel.

a. Run the build pipeline locally by executing the command `./mvnw clean package` (Linux) or `.\mvnw.cmd clean package` (Windows).

b. In Eclipse, open the file `jamopp.model/src/main/resources/metamodel/java.genmodel`, and execute `Generate Model` (available on right click on "Java" if the EMF Generator editor is opened and only showing a tree view).

## For Documentation

The raw content of this documentation is located in the top-level directory `jamopp.doc`. It uses [Docusaurus](https://docusaurus.io/) as documentation framework.

1. Thus, the documentation requires Node.js 18.16.0 or higher installed on your system.
1. If it is installed, you can run `npm i` in the documentation directory to install the necessary dependencies.
1. Then, `npm start` opens the generated documentation in the browser (defaults to `http://localhost:3000`), which is automatically updated on changes in the documentation files.
16 changes: 16 additions & 0 deletions jamopp.doc/docs/development/workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Workflow

For the development of the extended JaMoPP, we base the workflow on the Gitflow (cf., [the original](https://nvie.com/posts/a-successful-git-branching-model/) or [Atlassian blog post](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) for more information).

1. While the `main` branch hosts the source code of all releases with Git tags, all changes are primarily merged into the (default) `develop` branch.
1. For every bug, feature, release, and other issue, a [GitHub issue](https://github.com/MDSD-Tools/TheExtendedJavaModelParserAndPrinter/issues) needs to be created.
1. For the resolution of an issue (except releases), there should be a separate feature branch, usually branched from the current `develop` branch, with the name `<issue_number>_<meaningful_short_issue_description_with_words_separated_by_underscores>`. Please consider the `CHANGELOG.md` and this documentation, and update them if necessary.
1. If the changes are ready for merging, a pull request needs to be created for meging the feature branch into the `develop` branch. It is reviewed by at least one person. After all comments and issues within the pull request are resolved and the pull request is approved, it is merged, closing the pull request and corresponding GitHub issue.
1. For a release:
1. The following parts should be adapted on the `develop` branch:
* The version number (at least removing the SNAPSHOT part).
* The `CHANGELOG.md`.
* The documentation.
1. Then, merge `develop` into the `main` branch, and create a tag for the new release.
1. Run the `release` GitHub action workflow to build and push the artifacts to the MDSD tools update site and Maven central.
1. Update the version number on the `develop` branch once again (select an appropriate higher version number and re-add the SNAPSHOT part).
5 changes: 5 additions & 0 deletions jamopp.doc/docs/getting-started/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Getting Started

Welcome to the documentation of the extended Java Model Parser and Printer (JaMoPP). It provides tutorials, information about implemented features, and information for developers of JaMoPP.

This section contains tutorials to get started with using the extended JaMoPP.
4 changes: 4 additions & 0 deletions jamopp.doc/docs/getting-started/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"position": 1,
"label": "Getting Started"
}
252 changes: 252 additions & 0 deletions jamopp.doc/docs/getting-started/advanced_features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
---
sidebar_position: 3
sidebar_label: Advanced Features
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Using Advanced Features

This document builds upon the [first steps tutorial](./first_steps.md) and extends it to show advanced features of the extended JaMoPP.

## References

The first advanced feature regards references.

### Resolution

In the previous part, we started to develop a simple calculator by creating a class for the addition of two numbers. Finally, we implement the actual function:

```java title="calculator/Add.java" showLineNumbers
package calculator;

public class Add {
public int calc(int a, int b) {
return a + b;
}
}
```

Again, we parse the file and visualize the resulting model (also in a simplified version to support the readability):

<Tabs lazy>
<TabItem value="simplified-add-vis" label="Simplified Model" default>

```mermaid
classDiagram
direction TB

class `:CompilationUnit` {
namespaces = ["calculator"]
}
class `:Class` {
name = "Add"
}
class `:ClassMethod` {
name = "calc"
}
class `a:OrdinaryParameter`{
name = "a"
}
class `b:OrdinaryParameter` {
name = "b"
}
class `proxyA:Field` {
isProxy = true
name = "a"
}
class `proxyB:Field` {
isProxy = true
name = "b"
}

`:CompilationUnit` *-- `classifiers:List`
`classifiers:List` *-- `:Class` : [0]

`:Class` *-- `annotationsAndModifiers:List`
`annotationsAndModifiers:List` *-- `:Public` : [0]

`:Class` *-- `:ClassMethod` : members[0]
`:ClassMethod` *-- `a:OrdinaryParameter` : parameters[0]
`:ClassMethod` *-- `b:OrdinaryParameter` : parameters[1]
`a:OrdinaryParameter` *-- `pTypeA:Int` : typeReference
`b:OrdinaryParameter` *-- `pTypeB:Int` : typeReference

`:ClassMethod` *-- `:Return` : statement
`:Return` *-- `:AdditiveExpression` : returnValue
`:AdditiveExpression` *-- `children:List`
`children:List` *-- `refParamA:IdentifierReference` : [0]
`children:List` *-- `refParamB:IdentifierReference` : [1]

`refParamA:IdentifierReference` o.. `proxyA:Field` : target [before]
`refParamB:IdentifierReference` o.. `proxyB:Field` : target [before]
`refParamA:IdentifierReference` o.. `a:OrdinaryParameter` : target [after]
`refParamB:IdentifierReference` o.. `b:OrdinaryParameter` : target [after]
```

</TabItem>
<TabItem value="actual-add-vis" label="Actual Model">

```mermaid
classDiagram
direction TB

class `:CompilationUnit` {
namespaces = ["calculator"]
}
class `:Class` {
name = "Add"
}
class `:ClassMethod` {
name = "calc"
}
class `a:OrdinaryParameter` {
name = "a"
}
class `b:OrdinaryParameter` {
name = "b"
}
class `proxyA:Field` {
isProxy = true
name = "a"
}
class `proxyB:Field` {
isProxy = true
name = "b"
}
class `:Package` {
namespaces = ["calculator"]
}

`:CompilationUnit` *-- `classifiers:List`
`classifiers:List` *-- `:Class` : [0]
`:Class` o-- `:Package` : package
`:Class` *-- `modsAdd:List` : annotationsAndModifiers
`modsAdd:List` *-- `pubAdd:Public` : [0]

`:Class` *-- `members:List`
`members:List` *-- `:ClassMethod` : [0]

`:ClassMethod` *-- `modsCalc:List` : modifiers
`modsCalc:List` -- `pubCalc:Public`
`:ClassMethod` *-- `returnTypeCalc:Int` : typeReference
`:ClassMethod` *-- `parameters:List`
`parameters:List` *-- `a:OrdinaryParameter` : [0]
`parameters:List` *-- `b:OrdinaryParameter` : [1]
`a:OrdinaryParameter` *-- `pTypeA:Int` : typeReference
`b:OrdinaryParameter` *-- `pTypeB:Int` : typeReference

`:ClassMethod` *-- `:Block` : statement
`:Block` *-- `statements:List`
`statements:List` *-- `:Return` : [0]
`:Return` *-- `:AdditiveExpression` : returnValue

`:AdditiveExpression` *-- `additiveOperators:List`
`additiveOperators:List` *-- `:Addition` : [0]
`:AdditiveExpression` *-- `children:List`
`children:List` *-- `refParamA:IdentifierReference` : [0]
`children:List` *-- `refParamB:IdentifierReference` : [1]

`refParamA:IdentifierReference` o.. `proxyA:Field` : target [before]
`refParamB:IdentifierReference` o.. `proxyB:Field`: target [before]
`refParamA:IdentifierReference` o.. `a:OrdinaryParameter` : target [after]
`refParamB:IdentifierReference` o.. `b:OrdinaryParameter` : target [after]
```

</TabItem>
</Tabs>

Compared to the first visualization without the `calc` method, the model now includes the method. As a consequence, the parameters, return type (`typeReference` in the actual model), and the statements of the method are also represented with corresponding model elements. In particular, the `AdditiveExpression` for the addition of `a` and `b` contains `IdentifierReference` elements signaling that identifiers are present at this position in the Java code. The actual referenced elements (the method parameters) can be accessed via the `target` EMF reference.

:::warning
The term `Reference` has a double meaning here:

1. It refers to identifiers (referencing types, fields, methods, ...) in Java code which are usually represented by `Reference` elements in the Java meta-model.
2. It refers to EMF references which allow to navigate from model elements representing an identifier in Java code to the model element referenced and identified by the identifier.
:::

References (i.e., the connection between an identifier and its referenced element) need to be resolved to be able to navigate from the identifier to the element in the model. In the current version, the parser creates proxy objects for referenced elements as placeholders for the actual elements. Depending on the parser options, they are resolved during the parsing process or when they are accessed. In both cases, the reference resolution takes the proxy object and tries to find the actual element to replace the proxy object with the found element. Therefore, in the visualization, we included and marked the proxy objects as `target [before]` the reference resolution and the actual `target [after]` the reference resolution.

:::info
The default configuration for the parser options ensures that all proxy objects are transitively resolved during parsing. As a consequence, the models contain only proxy objects if they cannot be resolved.
:::

### Dependencies

To complete the implementation of the `Add` class, we add a custom `toString` method:

```java title="Add.java" showLineNumbers
package calculator;

public class Add {
public int calc(int a, int b) {
return a + b;
}

@Override
public String toString() {
return "calculator.Add";
}
}
```

In this case, `Override` and `String` present dependencies (into the Java standard library). The extended JaMoPP is able to resolve references into dependencies if they are known (i.e., the dependencies' code is given to the parser). In our example and with the default configuration, the Java standard library is automatically found and the references to `Override` and `String` can be resolved. If we alter the configuration, it may be necessary to explicitly register the Java standard library. Then, the class `tools.mdsd.jamopp.model.java.JavaClasspath` provides functionality to perform the registration:

```java
JavaClasspath.registerStdLib();
```

The `JavaClasspath` includes further methods to register zip or jar files which contain the code of dependencies:

```java
JavaClasspath.registerZip(URI.createURI("<path to zip or jar file>"));
```

If a dependency is not known during the parsing or reference resolution, the extended JaMoPP cannot resolve references to this dependency, and unresolvable proxy objects remain in the model.

## Recovery

At last, we altered the configuration so that the references to `Override` and `String` cannot be resolved. Nevertheless, to obtain a model without proxy objects, we apply the trivial recovery strategy for the `ResourceSet` `set` containing the model for `Add` and the proxy objects:

```java
new TrivialRecovery(set).recover();
```

The trivial recovery replaces proxy objects with valid model elements. When we visualize the resulting and relevant model elements, we can look into what the trivial recovery generates:

```mermaid
classDiagram
direction TB

class `:ClassMethod` {
name = "toString"
}
class `string:Class` {
name = "String"
}
class `override:Class` {
name = "Override"
}
class `synthetic:Class` {
name = "SyntheticClass"
}

`:ClassMethod` *-- `:ClassifierReference` : typeReference
`:ClassifierReference` o-- `string:Class` : target

`:ClassMethod` *-- `annotationsAndModifiers:List`
`annotationsAndModifiers:List` *-- `:AnnotationInstance` : [0]
`:AnnotationInstance` o-- `override:Class` : annotation

`synthetic:CompilationUnit` *-- `classifiers:List`
`classifiers:List` *-- `synthetic:Class` : [0]
`classifiers:List` *-- `string:Class` : [1]
`classifiers:List` *-- `override:Class` : [2]
```

Both proxy objects are replaced by two new `Class` elements which are collected in a synthetic `CompilationUnit` so that the resulting models are still valid. Furthermore, the synthetic `CompilationUnit` contains a synthetic `Class` element in which recovered methods and fields are stored. At the same time, this means that the recovery does not take context information into account. If, for example, a method on a `String` is called, the recovered method is not contained in the recovered `String` class element.

## Outlook

This is the end of the advanced tutorial. We introduced the basics of references and their resolution and recovery. If you want more information about these implemented features, have a look at the [guides](../guides/README.md) section.
Loading
Loading