This repository has been archived by the owner on Feb 12, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9d88589
commit e3028b8
Showing
44 changed files
with
2,366 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
# AMF Java Programming Guide | ||
|
||
Java wrapping code for the AMF library can be found in the `org.raml.amf` namespace. | ||
This package provides a Java friendly interface on top of the native Clojure code of the library. | ||
|
||
## Compiling | ||
|
||
At this moment we don't provide any artifacts in any repository to use AMF or these Java bindings, so they must be built manually with the help of Leiningen. | ||
In order to build the library, you fist need to build an 'ubejar' with AMF. To accomplish this, from the main AMF project directory run the following instruction: | ||
|
||
``` bash | ||
$ lein uberjar | ||
``` | ||
After Leiningen has finished you should have a standalone jar for AMF and all its dependencies in the `target/api-modeling-framework-0.1.2-SNAPSHOT-standalone.jar` location. Version might be different from the one at the moment of writing this documentation. | ||
|
||
Once the jar for AMF has been generated, we can generate the Java bindings jar. For that change to the `java` directory in the AMF project and use maven: | ||
|
||
``` bash | ||
mvn package | ||
``` | ||
|
||
After Maven has finished you should have an additional jar in the `target/amf-java-0.1.2-SNAPSHOT.jar` location with the Java bindings. Add both jars into your project to use the AMF Java bindings. | ||
|
||
## Parsing | ||
|
||
Parser can be found in the `org.raml.amf.parsers` package of the project. They can be build using the factories in `org.raml.amf.AMF` | ||
|
||
``` java | ||
DocumentModel model = AMF.RAMLParser().parseFile(new URL("http://test.com/worldmusic/api.raml")); | ||
``` | ||
|
||
Parsers are include for RAML, OpenAPI and the JSON-LD serialisation of the AMF model. | ||
|
||
Parsers can accept options, including a hash-map of URLs to local directories that will be used to resolve references in the parsed documents. | ||
|
||
For instance, in the next snippet all remote references to the URLs prefixed by `http://test.com/worldmusic` will be resolved looking into the local directory `/Users/antoniogarrote/world-music-api`. | ||
|
||
``` java | ||
HashMap<String,String> cacheDirs = new HashMap<>(); | ||
cacheDirs.put("http://test.com/worldmusic","/Users/antoniogarrote/vocabs/world-music-api"); | ||
ParsingOptions options = new ParsingOptions().setCacheDirs(cacheDirs); | ||
|
||
DocumentDocument model = (Document) AMF.RAMLParser().parseFile(new URL("http://test.com/worldmusic/api.raml"), options); | ||
``` | ||
The original parsed text can be retrieved using the `rawText` method. | ||
|
||
## Navigating the Document Model | ||
Parsing will return an instance of a subclass of `DocumentModel` Depending on what is the parsed file, a `Document` a `Fragment` or a `Module` instance will be returned. | ||
|
||
No matter what is the actual Document Model class, the returned model will also include references to all linked references in the model. | ||
|
||
These references can be listed using the `references` method and new instances of `DocumentModel` can be build for these references using the `modelForReference` method: | ||
|
||
``` java | ||
for (URL ref : model.references()) { | ||
DocumentModel refModel = model.modelForReference(ref); | ||
System.out.println("Found a reference model: " + refModel); | ||
} | ||
``` | ||
|
||
## Applying resolution | ||
|
||
To run the resolution algorithm and combine all the documents from the Document Model into a single Domain Model description, the method `resolve` can be invoked. | ||
|
||
``` java | ||
DocumentModel resolvedModel = model.resolve(); | ||
``` | ||
|
||
## Accessing the Domain Model | ||
|
||
The parsed Domain Model can be retrieved from the Document Model instance using the appropriate accessor. | ||
|
||
Fragments returns the encoded Domain Model element using the `encodes` method from the `org.raml.amf.core.document.EncodesDomainModel` interface. | ||
Modules returns the list of declared Domain Model elements using the `declares` method from the `org.raml.amf.core.document.DeclaresDomainModel` interface. | ||
Documents can use both methods to retrieve the top level encoded element and the list of declared elements in the root element. | ||
|
||
``` java | ||
if (model instanceof EncodesDomainModel) { | ||
System.out.println(model.encodes()); | ||
} | ||
|
||
if (targetModel instanceof DeclaresDomainModel) { | ||
List<DomainModel> declarations = model.declares(); | ||
for(DomainModel decl : declarations) { | ||
System.out.println(decl); | ||
} | ||
} | ||
``` | ||
|
||
## Navigating and mutating the Domain Model | ||
|
||
The Domain Model includes Java Bean classes for all elements in the AMF Domain Model. | ||
This getters and setters can be used to navigate and mutate the model. Please, refer to the [documentation](https://raml-org.github.io/api-modeling-framework/doc/java/apidocs/index.html) for more details. | ||
|
||
``` java | ||
APIDocumentation api = (APIDocumentation) model.encodes(); | ||
|
||
for (EndPoint endpoint : api.getEndpoints()) { | ||
endpoint.setName("Modified " + endpoint.getName()); | ||
} | ||
``` | ||
|
||
## Serialisation | ||
|
||
AMF includes generators capable of serialising the AMF model back into one of the supported syntaxes. The method `generateString` can be used to generate a String representation and the method `generateFile` can be used to dump the serialised model directly into a file. | ||
Factory methods for each generator can be found in the `org.raml.amf.AMF` class. | ||
|
||
|
||
``` java | ||
// Generating RAML | ||
// Generate can accept just the model | ||
String generated = AMF.RAMLGenerator().generateString(targetModel); | ||
System.out.println(generated); | ||
|
||
// Generating OpenAPI | ||
// It can also accept a destination File/URL for the model | ||
generated = AMF.OpenAPIGenerator().generateString( | ||
new File("world_music.json"), | ||
targetModel | ||
); | ||
System.out.println(generated); | ||
|
||
// Generating JSON-LD | ||
// Finally it can also accept a set of generation options | ||
generated = AMF.JSONLDGenerator().generateString( | ||
new File("world_music.jsonld"), | ||
targetModel, | ||
new GenerationOptions() | ||
.setFullgraph(true) | ||
.setSourceMapGeneration(true)); | ||
System.out.println(generated); | ||
``` | ||
|
||
Two options are available when generating JSON-LD documents. | ||
`setFullGraph` will nest the JSON-LD graphs for the referenced documents in the model to be serialised, otherwise only URIs will be generated. | ||
`setSourceMapGeneration` enables or disables the generation of source maps JSON-LD information in the output. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package org.raml.amf; | ||
|
||
import org.raml.amf.generators.AMFJSONLDGenerator; | ||
import org.raml.amf.generators.OpenAPIGenerator; | ||
import org.raml.amf.generators.RAMLGenerator; | ||
import org.raml.amf.parsers.AMFJSONLDParser; | ||
import org.raml.amf.parsers.OpenAPIParser; | ||
import org.raml.amf.parsers.RAMLParser; | ||
|
||
/** | ||
* Created by antoniogarrote on 04/05/2017. | ||
*/ | ||
|
||
/** | ||
* Facade class providing access to the main IO facilities in the library | ||
*/ | ||
public class AMF { | ||
|
||
/** | ||
* Builds a RAML to AMF parser | ||
* @return | ||
*/ | ||
public static RAMLParser RAMLParser() { | ||
return new RAMLParser(); | ||
} | ||
|
||
/** | ||
* Builds an OpenAPI to AMF parser | ||
* @return | ||
*/ | ||
public static OpenAPIParser OpenAPIParser() { | ||
return new OpenAPIParser(); | ||
} | ||
|
||
/** | ||
* Builds a AMF encoded JSON-LD to AMF parser | ||
* @return | ||
*/ | ||
public static AMFJSONLDParser JSONLDParser() { | ||
return new AMFJSONLDParser(); | ||
} | ||
|
||
/** | ||
* Builds a AMF to RAML generator | ||
* @return | ||
*/ | ||
public static RAMLGenerator RAMLGenerator() { | ||
return new RAMLGenerator(); | ||
} | ||
|
||
/** | ||
* Builds a AMF to OpenAPI generator | ||
* @return | ||
*/ | ||
public static OpenAPIGenerator OpenAPIGenerator() { | ||
return new OpenAPIGenerator(); | ||
} | ||
|
||
/** | ||
* Builds a AMF to JSON-LD generator | ||
* @return | ||
*/ | ||
public static AMFJSONLDGenerator JSONLDGenerator() { | ||
return new AMFJSONLDGenerator(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package org.raml.amf.core; | ||
|
||
/** | ||
* Created by antoniogarrote on 04/05/2017. | ||
*/ | ||
|
||
import org.raml.amf.core.exceptions.InvalidModelException; | ||
import org.raml.amf.utils.Clojure; | ||
|
||
/** | ||
* Base class for all AMF parsed models, provides methods to inspect and manipulate the model | ||
*/ | ||
public abstract class Model { | ||
|
||
static { | ||
Clojure.require(Clojure.API_MODELING_FRAMEWORK_CORE); | ||
} | ||
|
||
protected Object rawModel; | ||
|
||
protected Model(Object rawModel) { | ||
if (rawModel instanceof Exception) { | ||
throw new InvalidModelException((Exception) rawModel); | ||
} | ||
this.rawModel = rawModel; | ||
} | ||
|
||
/** | ||
* Returns the raw Clojure data structure for this instance data | ||
* @return | ||
*/ | ||
public abstract Object clojureModel(); | ||
} |
16 changes: 16 additions & 0 deletions
16
java/src/org/raml/amf/core/document/DeclaresDomainModel.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package org.raml.amf.core.document; | ||
|
||
import org.raml.amf.core.domain.DomainModel; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* Created by antoniogarrote on 04/05/2017. | ||
*/ | ||
public interface DeclaresDomainModel { | ||
/** | ||
* Declared DomainElements that can be re-used from other documents. | ||
* @return List of domain elements. | ||
*/ | ||
public List<DomainModel> declares(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package org.raml.amf.core.document; | ||
|
||
import clojure.lang.IFn; | ||
import org.raml.amf.core.domain.DomainModel; | ||
import org.raml.amf.core.exceptions.InvalidModelException; | ||
import org.raml.amf.utils.Clojure; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** | ||
* Created by antoniogarrote on 04/05/2017. | ||
*/ | ||
|
||
/** | ||
* AMF Documents encode the main element of a description in a particular Domain Model | ||
* For example, in RAML/HTTP, the main domain element is an APIDescription. | ||
* | ||
* Since AMF Documents encode Domain elements they behave like Fragments | ||
* AMF Documents can also contains declarations of domain elements to be used in the description of the domain. | ||
* From this point of view Documents also behave like Modules. | ||
*/ | ||
public class Document extends DocumentModel implements EncodesDomainModel, DeclaresDomainModel { | ||
public Document(Object rawModel) { | ||
super(rawModel); | ||
} | ||
|
||
/** | ||
* Encoded domain element. It's considered to be the root element of a stand-alone description, not a domain element | ||
* to be re-used and reference | ||
* @return DomainElement encoded in the document. | ||
* @throws InvalidModelException | ||
*/ | ||
public DomainModel encodes() throws InvalidModelException { | ||
IFn getFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_MODEL_DOCUMENT, "encodes"); | ||
return DomainModel.fromRawModel(getFn.invoke(this.clojureModel())); | ||
} | ||
|
||
/** | ||
* List of domain elements declared in the document to be referenced in the encoded element. | ||
* They are supposed to be private to the description and not meant to be re-used as in Modules. | ||
* @return | ||
*/ | ||
public List<DomainModel> declares() { | ||
IFn getFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_MODEL_DOCUMENT, "declares"); | ||
List parsedElements = Clojure.toJavaList((List) getFn.invoke(this.clojureModel())); | ||
ArrayList<DomainModel> declared = new ArrayList<>(); | ||
for(Object parsed : parsedElements) { | ||
declared.add(DomainModel.fromRawModel(parsed)); | ||
} | ||
|
||
return declared; | ||
} | ||
} |
Oops, something went wrong.