|
| 1 | +# AMF Java Programming Guide |
| 2 | + |
| 3 | +Java wrapping code for the AMF library can be found in the `org.raml.amf` namespace. |
| 4 | +This package provides a Java friendly interface on top of the native Clojure code of the library. |
| 5 | + |
| 6 | +## Compiling |
| 7 | + |
| 8 | +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. |
| 9 | +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: |
| 10 | + |
| 11 | +``` bash |
| 12 | +$ lein uberjar |
| 13 | +``` |
| 14 | +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. |
| 15 | + |
| 16 | +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: |
| 17 | + |
| 18 | +``` bash |
| 19 | +mvn package |
| 20 | +``` |
| 21 | + |
| 22 | +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. |
| 23 | + |
| 24 | +## Parsing |
| 25 | + |
| 26 | +Parsers 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` |
| 27 | + |
| 28 | +``` java |
| 29 | +DocumentModel model = AMF.RAMLParser().parseFile(new URL("http://test.com/worldmusic/api.raml")); |
| 30 | +``` |
| 31 | + |
| 32 | +Parsers are include for RAML, OpenAPI and the JSON-LD serialisation of the AMF model. |
| 33 | + |
| 34 | +Parsers can accept options, including a hash-map of URLs to local directories that will be used to resolve references in the parsed documents. |
| 35 | + |
| 36 | +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`. |
| 37 | + |
| 38 | +``` java |
| 39 | +HashMap<String,String> cacheDirs = new HashMap<>(); |
| 40 | +cacheDirs.put("http://test.com/worldmusic","/Users/antoniogarrote/vocabs/world-music-api"); |
| 41 | +ParsingOptions options = new ParsingOptions().setCacheDirs(cacheDirs); |
| 42 | + |
| 43 | +DocumentDocument model = (Document) AMF.RAMLParser().parseFile(new URL("http://test.com/worldmusic/api.raml"), options); |
| 44 | +``` |
| 45 | +The original parsed text can be retrieved using the `rawText` method. |
| 46 | + |
| 47 | +## Navigating the Document Model |
| 48 | +The parsing process will return an instance of one of the subclasses of `DocumentModel`. |
| 49 | +Depending on what is the parsed file, a `Document`, a `Fragment` or a `Module` instance will be returned. |
| 50 | + |
| 51 | +No matter what is the actual Document Model class, the returned model will also include references to all linked documents in the model. |
| 52 | + |
| 53 | +These references can be listed using the `references` method, and new instances of `DocumentModel` can be built for these references using the `modelForReference` method: |
| 54 | + |
| 55 | +``` java |
| 56 | +for (URL ref : model.references()) { |
| 57 | + DocumentModel refModel = model.modelForReference(ref); |
| 58 | + System.out.println("Found a reference model: " + refModel); |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +## Applying resolution |
| 63 | + |
| 64 | +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. |
| 65 | + |
| 66 | +``` java |
| 67 | +DocumentModel resolvedModel = model.resolve(); |
| 68 | +``` |
| 69 | + |
| 70 | +## Accessing the Domain Model |
| 71 | + |
| 72 | +The parsed Domain Model can be retrieved from the Document Model instance using the appropriate accessor. |
| 73 | + |
| 74 | +Fragments return the encoded Domain Model element using the `encodes` method from the `org.raml.amf.core.document.EncodesDomainModel` interface. |
| 75 | +Modules returns the list of declared Domain Model elements using the `declares` method from the `org.raml.amf.core.document.DeclaresDomainModel` interface. |
| 76 | +Documents can use both methods to retrieve the top level encoded element and the list of declared elements in the root element. |
| 77 | + |
| 78 | +``` java |
| 79 | +if (model instanceof EncodesDomainModel) { |
| 80 | + System.out.println(model.encodes()); |
| 81 | +} |
| 82 | + |
| 83 | +if (targetModel instanceof DeclaresDomainModel) { |
| 84 | + List<DomainModel> declarations = model.declares(); |
| 85 | + for(DomainModel decl : declarations) { |
| 86 | + System.out.println(decl); |
| 87 | + } |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +## Navigating and mutating the Domain Model |
| 92 | + |
| 93 | +The Domain Model includes Java bean classes for all elements in the AMF Domain Model. |
| 94 | +These 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. |
| 95 | + |
| 96 | +``` java |
| 97 | +APIDocumentation api = (APIDocumentation) model.encodes(); |
| 98 | + |
| 99 | +for (EndPoint endpoint : api.getEndpoints()) { |
| 100 | + endpoint.setName("Modified " + endpoint.getName()); |
| 101 | +} |
| 102 | +``` |
| 103 | + |
| 104 | +## Serialisation |
| 105 | + |
| 106 | +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. |
| 107 | +Factory methods for each generator can be found in the `org.raml.amf.AMF` class. |
| 108 | + |
| 109 | + |
| 110 | +``` java |
| 111 | +// Generating RAML |
| 112 | +// Generate can accept just the model |
| 113 | +String generated = AMF.RAMLGenerator().generateString(targetModel); |
| 114 | +System.out.println(generated); |
| 115 | + |
| 116 | +// Generating OpenAPI |
| 117 | +// It can also accept a destination File/URL for the model |
| 118 | +generated = AMF.OpenAPIGenerator().generateString( |
| 119 | + new File("world_music.json"), |
| 120 | + targetModel |
| 121 | +); |
| 122 | +System.out.println(generated); |
| 123 | + |
| 124 | +// Generating JSON-LD |
| 125 | +// Finally it can also accept a set of generation options |
| 126 | +generated = AMF.JSONLDGenerator().generateString( |
| 127 | + new File("world_music.jsonld"), |
| 128 | + targetModel, |
| 129 | + new GenerationOptions() |
| 130 | + .setFullgraph(true) |
| 131 | + .setSourceMapGeneration(true)); |
| 132 | +System.out.println(generated); |
| 133 | +``` |
| 134 | + |
| 135 | +Two options are available when generating JSON-LD documents. |
| 136 | +`setFullGraph` will nest the JSON-LD graphs for the referenced documents in the model to be serialised, otherwise only URIs will be generated. |
| 137 | +`setSourceMapGeneration` enables or disables the generation of source maps JSON-LD information in the output. |
0 commit comments