diff --git a/.gitignore b/.gitignore
index c73e0c6..3409ef0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,3 +16,6 @@ pom.xml.asc
package.json
.idea/
output/
+bindings/js/**/*.js
+bindings/js/**/*.js.map
+bindings/js/node_modules
\ No newline at end of file
diff --git a/README.md b/README.md
index 529751a..d19a9ca 100644
--- a/README.md
+++ b/README.md
@@ -124,9 +124,17 @@ $ lein jar
$ lein npm install # this is only required on the first run
$ lein node
```
-
The output NPM package will be generated at `output/node`.
+### Java Bindings
+
+The programming guide for the Java Bindings can be found [here](doc/java.md).
+Javadoc for the bindings can be consulted [here](https://raml-org.github.io/api-modeling-framework/doc/java/apidocs/index.html).
+
+### JS Bindings
+
+The programming guide for the JS Bindings can be found [here](doc/js.md).
+Documentation for the bindings can be consulted [here](https://raml-org.github.io/api-modeling-framework/doc/js/apidocs/index.html).
### API Modeling Framework Clojurescript/Web library
diff --git a/bindings/java/amf-java.iml b/bindings/java/amf-java.iml
new file mode 100644
index 0000000..d73eb00
--- /dev/null
+++ b/bindings/java/amf-java.iml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bindings/java/pom.xml b/bindings/java/pom.xml
new file mode 100644
index 0000000..6a1b60f
--- /dev/null
+++ b/bindings/java/pom.xml
@@ -0,0 +1,57 @@
+
+ 4.0.0
+ org.raml
+ amf-java
+ jar
+ 0.1.2-SNAPSHOT
+ api-modeling-framework java bindings
+ API and domain modeling tools for RAML, OpenAPI (Swagger) and RDF
+ https://github.com/mulesoft-labs/api-modeling-framework
+
+
+ Apache-2.0
+ http://www.eclipse.org/legal/epl-v10.html
+
+
+
+ scm:git:git://github.com/raml-org/api-modelling-framework.git
+ scm:git:ssh://git@github.com/raml-org/api-modelling-framework.git
+ 61a8011ec87cd6a09be6bcdaa7c37de34c5a538c
+
+ https://github.com/raml-org/api-modelling-framework
+
+
+ 1.7
+ 1.7
+
+
+ src
+ ../../target
+ ../../target/classes
+
+
+
+
+
+
+
+ api-modeling-framework
+ api-modeling-framework
+ 0.1.2-SNAPSHOT
+ system
+ ${project.basedir}/../../target/api-modeling-framework-0.1.2-SNAPSHOT-standalone.jar
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 2.10.4
+
+ -Xdoclint:none
+
+
+
+
+
diff --git a/bindings/java/src/org/raml/amf/AMF.java b/bindings/java/src/org/raml/amf/AMF.java
new file mode 100644
index 0000000..d29da76
--- /dev/null
+++ b/bindings/java/src/org/raml/amf/AMF.java
@@ -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();
+ }
+}
diff --git a/bindings/java/src/org/raml/amf/core/Model.java b/bindings/java/src/org/raml/amf/core/Model.java
new file mode 100644
index 0000000..cadfd57
--- /dev/null
+++ b/bindings/java/src/org/raml/amf/core/Model.java
@@ -0,0 +1,37 @@
+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;
+
+ /**
+ * Builds the model from the inner Clojure data structure generated by the AMF library
+ * @param 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();
+}
diff --git a/bindings/java/src/org/raml/amf/core/document/DeclaresDomainModel.java b/bindings/java/src/org/raml/amf/core/document/DeclaresDomainModel.java
new file mode 100644
index 0000000..aa6d38d
--- /dev/null
+++ b/bindings/java/src/org/raml/amf/core/document/DeclaresDomainModel.java
@@ -0,0 +1,17 @@
+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 declares();
+}
diff --git a/bindings/java/src/org/raml/amf/core/document/Document.java b/bindings/java/src/org/raml/amf/core/document/Document.java
new file mode 100644
index 0000000..4a1fef3
--- /dev/null
+++ b/bindings/java/src/org/raml/amf/core/document/Document.java
@@ -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 declares() {
+ IFn getFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_MODEL_DOCUMENT, "declares");
+ List parsedElements = Clojure.toJavaList((List) getFn.invoke(this.clojureModel()));
+ ArrayList declared = new ArrayList<>();
+ for(Object parsed : parsedElements) {
+ declared.add(DomainModel.fromRawModel(parsed));
+ }
+
+ return declared;
+ }
+}
diff --git a/bindings/java/src/org/raml/amf/core/document/DocumentModel.java b/bindings/java/src/org/raml/amf/core/document/DocumentModel.java
new file mode 100644
index 0000000..f4f0d22
--- /dev/null
+++ b/bindings/java/src/org/raml/amf/core/document/DocumentModel.java
@@ -0,0 +1,187 @@
+package org.raml.amf.core.document;
+
+/**
+ * Created by antoniogarrote on 04/05/2017.
+ */
+
+import api_modeling_framework.model.document.ParsedDocument;
+import api_modeling_framework.model.document.ParsedFragment;
+import api_modeling_framework.model.document.ParsedModule;
+import clojure.lang.IFn;
+import org.raml.amf.core.domain.DomainModel;
+import org.raml.amf.core.exceptions.InvalidModelException;
+import org.raml.amf.core.Model;
+import org.raml.amf.core.exceptions.ResolutionException;
+import org.raml.amf.core.exceptions.UnknownModelReferenceException;
+import org.raml.amf.utils.Clojure;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * AMF Document model that can be used to work with the graph of linked documents generated by the parser.
+ */
+public abstract class DocumentModel extends Model {
+
+ static {
+ Clojure.require(Clojure.API_MODELING_FRAMEWORK_CORE);
+ Clojure.require(Clojure.API_MODELING_FRAMEWORK_MODEL_DOCUMENT);
+ Clojure.require(Clojure.API_MODELING_FRAMEWORK_MODEL_DOMAIN);
+ }
+
+ DocumentModel(Object rawModel) throws InvalidModelException {
+ super(rawModel);
+ }
+
+ private boolean resolved = false;
+
+ /**
+ * Builds a new Model object for the referenced Document
+ * @param reference
+ * @return
+ * @throws MalformedURLException
+ * @throws InvalidModelException
+ * @throws UnknownModelReferenceException
+ */
+ public DocumentModel modelForReference(URL reference) throws MalformedURLException, InvalidModelException, UnknownModelReferenceException {
+ IFn referenceModelFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_CORE, "reference-model");
+ URL[] refs = this.references();
+ for(URL ref : refs) {
+ if (ref.sameFile(reference)) {
+ return DocumentModel.fromRawModel(referenceModelFn.invoke(this.rawModel, ref.toString().replace("file:","")));
+ }
+ }
+
+ throw new UnknownModelReferenceException(reference);
+ }
+
+
+ /**
+ * Returns the list document URIs referenced from the document that has been parsed to generate this model
+ * @return An array of URI locations for the remote documents
+ */
+ public URL[] references() throws MalformedURLException {
+ IFn referencesFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_CORE, "references");
+ List references = (List) referencesFn.invoke(this.rawModel);
+ URL[] acc = new URL[references.size()];
+ for (int i=0; i rawText() {
+ IFn rawFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_CORE, "raw");
+ String text = (String) rawFn.invoke(this.rawModel);
+ if (text != null) {
+ return Optional.of(text);
+ } else {
+ return Optional.empty();
+ }
+ }
+
+
+ protected URL stringToURL(String location) throws MalformedURLException {
+ if (!location.contains("://")) {
+ return new URL("file://"+location);
+ } else {
+ return new URL(location);
+ }
+ }
+
+
+ /**
+ * Returns the native Clojure data structure for the model
+ * @return Clojure data structure encoding the model
+ */
+ @Override
+ public Object clojureModel() {
+ IFn documentModelFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_CORE, "document-model");
+ return documentModelFn.invoke(this.rawModel);
+ }
+
+ /**
+ * Factory method building the right wrapper Java DocumentModel subclass for the provided Clojure model data structure
+ * @param rawModel native Clojure encoded model
+ * @return The right DocumentModel
+ * @throws InvalidModelException
+ */
+ public static DocumentModel fromRawModel(Object rawModel) throws InvalidModelException {
+ IFn unitKindFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_CORE, "unit-kind");
+ String unitKind = (String) unitKindFn.invoke(rawModel);
+ if (Objects.equals(unitKind, "module")) {
+ return new Module(rawModel);
+ } else if (Objects.equals(unitKind, "fragment")) {
+ return new Fragment(rawModel);
+ } else if (Objects.equals(unitKind, "document")) {
+ return new Document(rawModel);
+ } else {
+ throw new InvalidModelException(new Exception("Unknown type of document unit " + unitKind));
+ }
+ }
+
+ public DomainModel findDomainElement(String id) {
+ IFn findFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_CORE, "find-element");
+ Object res = findFn.invoke(this.rawModel, (isResolved() ? "domain": "document"), id);
+ if (res != null){
+ Document doc = (Document) DocumentModel.fromRawModel(res);
+ return doc.encodes();
+ } else {
+ return null;
+ }
+ }
+
+ public boolean isResolved() {
+ return resolved;
+ }
+
+ protected void setResolved(boolean resolved) {
+ this.resolved = resolved;
+ }
+}
diff --git a/bindings/java/src/org/raml/amf/core/document/EncodesDomainModel.java b/bindings/java/src/org/raml/amf/core/document/EncodesDomainModel.java
new file mode 100644
index 0000000..f2e03d1
--- /dev/null
+++ b/bindings/java/src/org/raml/amf/core/document/EncodesDomainModel.java
@@ -0,0 +1,18 @@
+package org.raml.amf.core.document;
+
+import org.raml.amf.core.domain.DomainModel;
+import org.raml.amf.core.exceptions.InvalidModelException;
+
+/**
+ * Created by antoniogarrote on 04/05/2017.
+ */
+public interface EncodesDomainModel {
+
+ /**
+ * Encoded domain element described in the document element.
+ * @return DomainElement encoded in the document.
+ * @throws InvalidModelException
+ */
+ public DomainModel encodes() throws InvalidModelException;
+
+}
diff --git a/bindings/java/src/org/raml/amf/core/document/Fragment.java b/bindings/java/src/org/raml/amf/core/document/Fragment.java
new file mode 100644
index 0000000..dea3431
--- /dev/null
+++ b/bindings/java/src/org/raml/amf/core/document/Fragment.java
@@ -0,0 +1,35 @@
+package org.raml.amf.core.document;
+
+import clojure.lang.IFn;
+import clojure.lang.Keyword;
+import org.raml.amf.core.domain.DomainModel;
+import org.raml.amf.core.exceptions.InvalidModelException;
+import org.raml.amf.utils.Clojure;
+
+/**
+ * Created by antoniogarrote on 04/05/2017.
+ */
+
+/**
+ * AMF Fragments encode a single DomainElement that can be referenced and re-used in other documents.
+ */
+public class Fragment extends DocumentModel implements EncodesDomainModel {
+ static {
+ Clojure.require(Clojure.API_MODELING_FRAMEWORK_CORE);
+ Clojure.require(Clojure.API_MODELING_FRAMEWORK_MODEL_DOCUMENT);
+ }
+
+ public Fragment(Object rawModel) {
+ super(rawModel);
+ }
+
+ /**
+ * Encoded Domain element that can referenced from other documents in the DocumentModel
+ * @return
+ * @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()));
+ }
+}
diff --git a/bindings/java/src/org/raml/amf/core/document/Module.java b/bindings/java/src/org/raml/amf/core/document/Module.java
new file mode 100644
index 0000000..135c00a
--- /dev/null
+++ b/bindings/java/src/org/raml/amf/core/document/Module.java
@@ -0,0 +1,37 @@
+package org.raml.amf.core.document;
+
+import clojure.lang.IFn;
+import org.raml.amf.core.domain.DomainModel;
+import org.raml.amf.utils.Clojure;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by antoniogarrote on 04/05/2017.
+ */
+
+/**
+ * AMF Modules contains collections of DomainElements that can be re-used and referenced from other documents in the
+ * Documentmodel.
+ */
+public class Module extends DocumentModel implements DeclaresDomainModel {
+ public Module(Object rawModel) {
+ super(rawModel);
+ }
+
+ /**
+ * Declared DomainElements that can be re-used from other documents.
+ * @return List of domain elements.
+ */
+ public List declares() {
+ IFn getFn = Clojure.var(Clojure.API_MODELING_FRAMEWORK_MODEL_DOCUMENT, "declares");
+ List parsedElements = Clojure.toJavaList((List) getFn.invoke(this.clojureModel()));
+ ArrayList declared = new ArrayList<>();
+ for(Object parsed : parsedElements) {
+ declared.add(DomainModel.fromRawModel(parsed));
+ }
+
+ return declared;
+ }
+}
diff --git a/bindings/java/src/org/raml/amf/core/domain/APIDocumentation.java b/bindings/java/src/org/raml/amf/core/domain/APIDocumentation.java
new file mode 100644
index 0000000..6a34b71
--- /dev/null
+++ b/bindings/java/src/org/raml/amf/core/domain/APIDocumentation.java
@@ -0,0 +1,194 @@
+package org.raml.amf.core.domain;
+
+import api_modeling_framework.model.domain.ParsedAPIDocumentation;
+import clojure.lang.IFn;
+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.
+ */
+
+
+/**
+ * Main EntryPoint of the description of HTTP RPC API
+ */
+public class APIDocumentation extends DomainModel {
+
+ static {
+ Clojure.require(Clojure.API_MODELING_FRAMEWORK_MODEL_DOMAIN);
+ }
+
+ public APIDocumentation(ParsedAPIDocumentation rawModel) {
+ super(rawModel);
+ }
+
+ /**
+ * Build a new empty API Documentation for the provided URI
+ * @param id
+ */
+ public APIDocumentation(String id) {
+ super(Clojure.var(
+ Clojure.API_MODELING_FRAMEWORK_MODEL_DOMAIN,
+ "api-modeling-framework.model.domain/map->ParsedAPIDocumentation"
+ ).invoke(Clojure.map())
+ );
+ this.setId(id);
+ }
+
+ public String getTermsOfService() {
+ return (String) this.wrapped().terms_of_service();
+ }
+
+ public void setTermsOfService(String termsOfService) {
+ this.rawModel = Clojure.setKw(this.rawModel, "terms-of-service", termsOfService);
+ }
+
+ public String getBasePath() {
+ Object res = this.wrapped().base_path();
+ if (res != null)
+ return (String) res;
+ else
+ return null;
+ }
+
+ public void setBasePath(String basePath) {
+ this.rawModel = Clojure.setKw(this.rawModel, "base-path", basePath);
+ }
+
+ public String getHost() {
+ Object res = this.wrapped().host();
+ if (res != null)
+ return (String) res;
+ else
+ return null;
+ }
+
+ public void setHost(String host) {
+ this.rawModel = Clojure.setKw(this.rawModel, "host", host);
+ }
+
+ public String getVersion() {
+ Object res = this.wrapped().version();
+ if (res != null)
+ return (String) res;
+ else
+ return null;
+ }
+
+ public void setVersion(String host) {
+ this.rawModel = Clojure.setKw(this.rawModel, "version", host);
+ }
+
+ /**
+ * URI Scheme for the paths in the API
+ * @return
+ */
+ public String getScheme() {
+ Object res = this.wrapped().scheme();
+ if (res != null)
+ return (String) res;
+ else
+ return null;
+ }
+
+ public void setScheme(String scheme) {
+ this.rawModel = Clojure.setKw(this.rawModel, "scheme", scheme);
+ }
+
+ public List getAccepts() {
+ return (List) this.wrapped().accepts();
+ }
+
+ public void setAccepts(List accepts) {
+ this.rawModel = Clojure.setKw(this.wrapped(), "accepts", Clojure.list(accepts));
+ }
+
+ public List getContentTypes() {
+ return (List) this.wrapped().content_type();
+ }
+
+ public void setContentTypes(List contentTypes) {
+ this.rawModel = Clojure.setKw(this.wrapped(), "content-type", Clojure.list(contentTypes));
+ }
+
+ /**
+ * List of HTTP headers in this unit
+ * @return
+ */
+ public List getHeaders() {
+ List headers = (List) this.wrapped().headers();
+ List tmp = Clojure.toJavaList(headers);
+ ArrayList eps = new ArrayList<>();
+ for(api_modeling_framework.model.domain.ParsedParameter x : tmp) {
+ Header parsed = new Header(x);
+ eps.add(parsed);
+ }
+
+ return eps;
+ }
+
+ public void setHeaders(List headers) {
+ ArrayList