Skip to content

Commit

Permalink
Add support for URI-to-path mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
agarciadom committed May 22, 2024
1 parent 6eb326b commit fcdcb0b
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 14 deletions.
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@ To build and test the Java and native binary versions of the project, run:
Note that for the native binaries, you will need [GraalVM](https://www.graalvm.org/) 17 or newer.
It is recommended to use [SDKMAN](https://sdkman.io/) for installing and managing JDKs.

## Running

To produce Emfatic sources from an `.ecore` file, using the all-in-one JAR file in `build/libs/*-all.jar`:

```sh
java -jar path/to/Ecore2Emfatic-VERSION-all.jar path/to/your.ecore
```

When using one of the native binaries, this can be simplified to:

```sh
path/to/Ecore2Emfatic path/to/your.ecore
```

## Using native binaries as a Git filter

In order to compute differences between `.ecore` file versions using a Git `textconv`, first add the native binary to your path.
Expand Down Expand Up @@ -51,3 +65,24 @@ index 84da8c9..f611dd1 100644
+ private = 3;
}
```

## Providing URI mappings

If your `.ecore` files import other metamodels through URIs, you can provide mappings from URIs to specific `.ecore` files or folders via the `--from` and `--to` options:

```sh
path/to/Ecore2Emfatic --from platform:/resource --to path/to/base/folder your.ecore
```

You can specify multiple pairs of `--from` and `--to` options, as in:

```sh
path/to/Ecore2Emfatic --from A --to B --from C --to D your.ecore
```

If you are using this tool as a `textconv` filter via Git, you would need to provide these options in your repository's configuration.
For example:

```sh
git config diff.ecore.textconv "Ecore2Emfatic --from A --to B"
```
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dependencies {
implementation("io.micronaut.serde:micronaut-serde-jackson")
implementation("org.eclipse.emfatic:org.eclipse.emfatic.core:1.1.0")
implementation("org.eclipse.platform:org.eclipse.core.resources:3.13.700")
testImplementation('org.hamcrest:hamcrest:2.2')
runtimeOnly("ch.qos.logback:logback-classic")
}

Expand Down
71 changes: 61 additions & 10 deletions src/main/java/org/eclipse/emfatic/cli/Ecore2EmfaticCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,37 @@

import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.core.annotation.TypeHint;
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

@TypeHint(value = {
EEnumLiteral[].class,
EParameter[].class,
EStringToStringMapEntryImpl[].class,
ETypeParameter[].class
EEnumLiteral[].class,
EParameter[].class,
EStringToStringMapEntryImpl[].class,
ETypeParameter[].class
})
@Command(
name = "Ecore2Emfatic",
description = "Generates Emfatic sources from an .ecore file",
mixinStandardHelpOptions = true
)
@Command(name = "Ecore2Emfatic", description = "Generates Emfatic sources from an .ecore file", mixinStandardHelpOptions = true)
public class Ecore2EmfaticCommand implements Runnable {

@Parameters(index="0")
static class URIMapping {
@Option(names = { "-f", "--from" })
String from;

@Option(names = { "-t", "--to"})
String to;
}

@ArgGroup(exclusive = false, multiplicity = "0..*")
private List<URIMapping> uriMappings;

@Parameters(index = "0")
private String pathToFile;

public static void main(String[] args) throws Exception {
Expand All @@ -54,7 +68,44 @@ public void run() {
ResourceSet rs = new ResourceSetImpl();
rs.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl());

Map<URI, URI> uriMap = rs.getURIConverter().getURIMap();
if (uriMappings != null) {
applyURIMappingsTo(uriMap);
}

Resource r = rs.getResource(URI.createFileURI(pathToFile), true);
System.out.println(new Writer().write(r, null, null));
}

protected void applyURIMappingsTo(Map<URI, URI> uriMap) {
for (URIMapping mapping : uriMappings) {
if (mapping.from == null) {
throw new IllegalArgumentException("Missing from");
}
if (mapping.to == null) {
throw new IllegalArgumentException("Missing to");
}

try {
File fTargetPath = new File(mapping.to).getCanonicalFile();
String sPath = fTargetPath.getAbsolutePath();
if (fTargetPath.isDirectory()) {
// If the target is a directory, ensure both source and target URIs are "prefix" URIs
// (i.e. that they end in a slash)
if (!mapping.from.endsWith("/")) {
mapping.from += "/";
}
if (!sPath.endsWith("/")) {
sPath += "/";
}
}

URI mappedURI = URI.createURI(mapping.from, true);
URI fileURI = URI.createFileURI(sPath);
uriMap.put(mappedURI, fileURI);
} catch (IOException e) {
throw new IllegalArgumentException("Could not compute canonical path for " + mapping.to);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,42 @@
import io.micronaut.configuration.picocli.PicocliRunner;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.env.Environment;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertTrue;

public class Ecore2EmfaticCommandTest {

@Test
public void testWithCommandLineOption() throws Exception {
public void testStandaloneMetamodel() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
System.setOut(new PrintStream(baos));

try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)) {
String[] args = new String[] { "src/test/resources/OO.ecore" };
PicocliRunner.run(Ecore2EmfaticCommand.class, ctx, args);
assertTrue(baos.toString().contains("PackageableElement"));
assertThat("Should see a PackageableElement in the output",
baos.toString(), containsString("PackageableElement"));
}
}

@Test
public void testMetamodelWithPlatformImport() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
System.setOut(new PrintStream(baos));

try (ApplicationContext ctx = ApplicationContext.run(Environment.CLI, Environment.TEST)) {
String[] args = new String[] {
"--from=platform:/resource",
"--to=src/test/resources/platformImport",
"src/test/resources/platformImport/example2/ColoredTree.ecore"
};
PicocliRunner.run(Ecore2EmfaticCommand.class, ctx, args);
assertThat("Should see 'extends Trees.Tree' in the output",
baos.toString(), containsString("extends Trees.Tree"));
}
}
}
11 changes: 11 additions & 0 deletions src/test/resources/platformImport/example/Trees.ecore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="Trees" nsURI="http://eclipse.org/epsilon/examples/trees" nsPrefix="t">
<eClassifiers xsi:type="ecore:EClass" name="Tree">
<eStructuralFeatures xsi:type="ecore:EReference" name="children" upperBound="-1"
eType="#//Tree" containment="true" eOpposite="#//Tree/parent"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="parent" eType="#//Tree"
eOpposite="#//Tree/children"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
</ecore:EPackage>
12 changes: 12 additions & 0 deletions src/test/resources/platformImport/example2/ColoredTree.ecore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="ColoredTree" nsURI="ColoredTree" nsPrefix="ct">
<eClassifiers xsi:type="ecore:EClass" name="ColoredTree" eSuperTypes="platform:/resource/example/Trees.ecore#//Tree">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="color" eType="#//Color"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EEnum" name="Color">
<eLiterals name="RED" value="1"/>
<eLiterals name="GREEN" value="2"/>
<eLiterals name="BLUE" value="3"/>
</eClassifiers>
</ecore:EPackage>

0 comments on commit fcdcb0b

Please sign in to comment.