summaryrefslogtreecommitdiffstats
path: root/appc-client/code-generator
diff options
context:
space:
mode:
Diffstat (limited to 'appc-client/code-generator')
-rw-r--r--appc-client/code-generator/.gitignore1
-rw-r--r--appc-client/code-generator/pom.xml122
-rw-r--r--appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/CLI.java66
-rw-r--r--appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/ContextBuilder.java34
-rw-r--r--appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/MavenPlugin.java85
-rw-r--r--appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/extensions/JsonContextBuilderImpl.java67
-rw-r--r--appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/extensions/YangContextBuilderImpl.java98
-rw-r--r--appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/impl/CodeGenWriter.java107
-rw-r--r--appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/impl/ModelGenerator.java71
-rw-r--r--appc-client/code-generator/src/main/resources/configuration/client-kit.properties34
-rw-r--r--appc-client/code-generator/src/main/resources/templates/client-kit/common.ftl49
-rw-r--r--appc-client/code-generator/src/main/resources/templates/client-kit/enum.ftl65
-rw-r--r--appc-client/code-generator/src/main/resources/templates/client-kit/open-api-to-java.ftl41
-rw-r--r--appc-client/code-generator/src/main/resources/templates/client-kit/pojo.ftl109
-rw-r--r--appc-client/code-generator/src/main/resources/templates/client-kit/primitive-wrapper-pojo.ftl59
-rw-r--r--appc-client/code-generator/src/main/resources/templates/client-kit/service.ftl72
-rw-r--r--appc-client/code-generator/src/main/resources/templates/open-api/yang-to-open-api.ftl314
17 files changed, 1394 insertions, 0 deletions
diff --git a/appc-client/code-generator/.gitignore b/appc-client/code-generator/.gitignore
new file mode 100644
index 000000000..b83d22266
--- /dev/null
+++ b/appc-client/code-generator/.gitignore
@@ -0,0 +1 @@
+/target/
diff --git a/appc-client/code-generator/pom.xml b/appc-client/code-generator/pom.xml
new file mode 100644
index 000000000..92bc109ec
--- /dev/null
+++ b/appc-client/code-generator/pom.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ============LICENSE_START=======================================================
+ ONAP : APPC
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Copyright (C) 2017 Amdocs
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ============LICENSE_END=========================================================
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>appc-java-client</artifactId>
+ <groupId>org.openecomp.appc.client</groupId>
+ <version>1.1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>code-generator</artifactId>
+ <name>code-generator</name>
+ <description>APPC client code generator</description>
+ <packaging>maven-plugin</packaging>
+
+ <properties>
+ <licenseDir>${project.parent.parent.basedir}</licenseDir>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>${java.version}</source>
+ <target>${java.version}</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>${maven.plugin.plugin.version}</version>
+ <configuration>
+ <goalPrefix>code-generator</goalPrefix>
+ <encoding>UTF-8</encoding>
+ </configuration>
+ <executions>
+ <execution>
+ <id>default-descriptor</id>
+ <goals>
+ <goal>descriptor</goal>
+ </goals>
+ <phase>process-classes</phase>
+ </execution>
+ <execution>
+ <id>help-descriptor</id>
+ <goals>
+ <goal>helpmojo</goal>
+ </goals>
+ <phase>process-classes</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-parser-impl</artifactId>
+ <version>${yang.parser.impl.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-core-api</artifactId>
+ <version>${sal.core.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-model-api</artifactId>
+ <version>${yang.parser.impl.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
+ <artifactId>jackson-databind</artifactId>
+ <version>${jackson.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.freemarker</groupId>
+ <artifactId>freemarker</artifactId>
+ <version>${freemarker.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <version>${maven.plugin.annotations.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${maven.plugin.api.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${maven.core.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/CLI.java b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/CLI.java
new file mode 100644
index 000000000..61516a72d
--- /dev/null
+++ b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/CLI.java
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.tools.generator.api;
+
+import org.openecomp.appc.tools.generator.impl.ModelGenerator;
+
+public class CLI {
+ public static void main(String... args) throws Exception {
+ String sourceFile = args[0];
+ if(sourceFile == null)
+ throw new IllegalArgumentException("Source file is missing. Please add argument 'client <source file> <destination file> <model template>'");
+
+ String destinationFile = args[1];
+ if(destinationFile == null)
+ throw new IllegalArgumentException("Destination file name is missing. Please add argument 'client "
+ + sourceFile
+ + "<destination> <model template> <builder> <conf file>'");
+
+ String templateFile = args[2];
+ if(templateFile == null)
+ throw new IllegalArgumentException("template file name is missing. Please add argument 'client "
+ + sourceFile
+ + destinationFile
+ + " <model template> <builder> <conf file>'");
+
+ String builderName = args[3];
+ if(builderName == null)
+ throw new IllegalArgumentException("builder FQDN is missing. Please add argument 'client "
+ + sourceFile
+ + destinationFile
+ + templateFile
+ + " <builder> <conf file>'");
+ String contextConfName = args[4];
+ if(contextConfName == null)
+ throw new IllegalArgumentException("context conf file is missing. Please add argument 'client "
+ + sourceFile
+ + destinationFile
+ + templateFile
+ + builderName
+ + " <conf file>'");
+ ModelGenerator generator = new ModelGenerator();
+ generator.execute(sourceFile, destinationFile, templateFile, builderName, contextConfName);
+ }
+}
diff --git a/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/ContextBuilder.java b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/ContextBuilder.java
new file mode 100644
index 000000000..7e0bbe15a
--- /dev/null
+++ b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/ContextBuilder.java
@@ -0,0 +1,34 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.tools.generator.api;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Map;
+
+public interface ContextBuilder {
+
+ Map<String, Object> buildContext(String sourceFile, String contextConf) throws IOException;
+}
diff --git a/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/MavenPlugin.java b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/MavenPlugin.java
new file mode 100644
index 000000000..f031dd666
--- /dev/null
+++ b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/api/MavenPlugin.java
@@ -0,0 +1,85 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.tools.generator.api;
+
+import org.openecomp.appc.tools.generator.impl.ModelGenerator;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+
+@Mojo(
+ name = "generate",
+ defaultPhase = LifecyclePhase.GENERATE_SOURCES
+)
+public class MavenPlugin extends AbstractMojo {
+
+ @Parameter(property = "templateName", required = true)
+ private String templateName;
+
+ @Parameter(property = "sourceFileName")
+ private String sourceFileName;
+
+ @Parameter(property = "outputFileName")
+ private String outputFileName;
+
+ @Parameter(property = "contextBuilderClassName", required = true)
+ private String contextBuilderClassName;
+
+ @Parameter(property = "contextConfigFileName")
+ private String contextConfigFileName;
+
+ @Parameter (property = "project")
+ private MavenProject project;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException {
+ ModelGenerator generator = new ModelGenerator();
+ try {
+ trace("\t === Called MavenPlugin on builder <" + contextBuilderClassName +">\n");
+ generator.execute(sourceFileName,outputFileName,templateName,contextBuilderClassName,contextConfigFileName);
+ String workDirectory = getWorkDirectory(outputFileName);
+ project.addCompileSourceRoot(workDirectory);
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new MojoExecutionException(e.getMessage());
+ }
+ }
+
+ private String getWorkDirectory(String outputFileName) throws IOException {
+ String workDirPath = Paths.get(outputFileName.toString()).getParent().toString();
+ return workDirPath;
+ }
+
+ private void trace(String message) {
+ getLog().info(message);
+ }
+}
diff --git a/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/extensions/JsonContextBuilderImpl.java b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/extensions/JsonContextBuilderImpl.java
new file mode 100644
index 000000000..6a3d13bf5
--- /dev/null
+++ b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/extensions/JsonContextBuilderImpl.java
@@ -0,0 +1,67 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.tools.generator.extensions;
+
+import org.openecomp.appc.tools.generator.api.ContextBuilder;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+public class JsonContextBuilderImpl implements ContextBuilder {
+
+ @Override
+ public Map<String, Object> buildContext(String sourceFile, String contextConf) throws IOException {
+ //read json file
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode model = mapper.readTree(new File(sourceFile));
+
+ //get context config file
+ Properties properties = new Properties();
+ ClassLoader classloader = Thread.currentThread().getContextClassLoader();
+ InputStream inputStream = classloader.getResourceAsStream(contextConf);
+ properties.load(inputStream);
+
+ //get context related properties
+ ObjectNode metadata = mapper.createObjectNode();
+ for (String key : properties.stringPropertyNames()) {
+ if (key.startsWith("ctx")) {
+ metadata.put(key.replaceFirst("ctx.", ""), properties.getProperty(key));
+ }
+ }
+
+ //create context and populate it
+ Map<String, Object> map = new HashMap<>();
+ map.put("model", model);
+ map.put("metadata", metadata);
+ return map;
+ }
+}
diff --git a/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/extensions/YangContextBuilderImpl.java b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/extensions/YangContextBuilderImpl.java
new file mode 100644
index 000000000..32846166e
--- /dev/null
+++ b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/extensions/YangContextBuilderImpl.java
@@ -0,0 +1,98 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.tools.generator.extensions;
+
+import org.openecomp.appc.tools.generator.api.ContextBuilder;
+import com.google.common.base.Optional;
+
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
+import org.opendaylight.yangtools.yang.parser.repo.YangTextSchemaContextResolver;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.ModuleEffectiveStatementImpl;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.*;
+
+public class YangContextBuilderImpl implements ContextBuilder {
+
+ @Override
+ public Map<String, Object> buildContext(String sourceFile, String contextConf) throws FileNotFoundException {
+ InputStream source = new FileInputStream(sourceFile);
+ if (source == null) {
+ throw new FileNotFoundException("YANG file <" + sourceFile + ">not found");
+ }
+
+ YangTextSchemaContextResolver yangContextResolver = YangTextSchemaContextResolver
+ .create("yang-context-resolver");
+ try {
+ yangContextResolver.registerSource(new URL("file:///" + sourceFile));
+ } catch (SchemaSourceException | IOException | YangSyntaxErrorException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ Optional<SchemaContext> sc = yangContextResolver.getSchemaContext();
+
+ Map<String, Object> map = new HashMap<>();
+ if (sc.isPresent()) {
+
+ Set<Module> modules = sc.get().getModules();
+ for (Module module : modules) {
+ ModuleEffectiveStatementImpl impl = (ModuleEffectiveStatementImpl) module;
+ map.put("module", module);
+ }
+
+ }
+
+ return map;
+ }
+
+ // @Override
+ // public Map<String, Object> buildContext(String sourceFile, String
+ // contextConf) throws FileNotFoundException {
+ // InputStream source = new FileInputStream(sourceFile);
+ // if (source == null) {
+ // throw new FileNotFoundException("YANG file <" + sourceFile + ">not found");
+ // }
+ //
+ // SchemaContext mSchema = parse(Collections.singletonList(source));
+ //
+ // Map<String, Object> map = new HashMap<>();
+ // map.put("module", mSchema.getModules().iterator().next());
+ // return map;
+ // }
+ //
+ // private SchemaContext parse(List<InputStream> sources) {
+ // YangParserImpl parser = new YangParserImpl();
+ // Set<Module> modules = parser.parseYangModelsFromStreams(sources);
+ // return parser.resolveSchemaContext(modules);
+ // }
+
+}
diff --git a/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/impl/CodeGenWriter.java b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/impl/CodeGenWriter.java
new file mode 100644
index 000000000..15498c83d
--- /dev/null
+++ b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/impl/CodeGenWriter.java
@@ -0,0 +1,107 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.tools.generator.impl;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+class CodeGenWriter extends Writer {
+
+ private FileWriter fileWriter;
+ private boolean delimiterBeginFound;
+ private Path basePath;
+ private String outPath;
+ private boolean deleteFile;
+ private static final String DELIMITER = "__";
+ private Pattern pattern;
+
+
+ CodeGenWriter(String destination) throws IOException {
+ super(destination);
+ fileWriter = new FileWriter(destination);
+ basePath = Paths.get(destination);
+ delimiterBeginFound = false;
+ outPath = "";
+ deleteFile = false;
+ pattern = Pattern.compile(DELIMITER);
+ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ String bufferStr = new String(cbuf).substring(off, off + len);
+ Matcher matcher = pattern.matcher(bufferStr);
+
+ boolean isMatch = matcher.find();
+ if (!isMatch) {
+ if (!delimiterBeginFound) {
+ fileWriter.write(cbuf, off, len);
+ }
+ else {
+ outPath += bufferStr;
+ }
+ }
+ else {
+ if (!delimiterBeginFound) {
+ delimiterBeginFound = true;
+ }
+ else {
+ deleteFile = true;
+ Path fileName = getNewFileName();
+ Files.createDirectories(fileName.getParent());
+ openNewFileWriter(fileName.toString());
+ delimiterBeginFound = false;
+ outPath = "";
+ }
+ }
+ }
+
+ @Override
+ public void flush() throws IOException {
+ fileWriter.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ fileWriter.close();
+ if (deleteFile) {
+ Files.deleteIfExists(basePath);
+ }
+ }
+
+ private Path getNewFileName() {
+ String newRelativePath = this.outPath.replace(".", File.separator);
+ return Paths.get(basePath.getParent().toString(), newRelativePath + ".java");
+ }
+
+ private void openNewFileWriter(String fileName) throws IOException {
+ flush();
+ close();
+ fileWriter = new FileWriter(fileName);
+ }
+}
diff --git a/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/impl/ModelGenerator.java b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/impl/ModelGenerator.java
new file mode 100644
index 000000000..bdaa3a29d
--- /dev/null
+++ b/appc-client/code-generator/src/main/java/org/openecomp/appc/tools/generator/impl/ModelGenerator.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP : APPC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Copyright (C) 2017 Amdocs
+ * =============================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.appc.tools.generator.impl;
+
+import org.openecomp.appc.tools.generator.api.ContextBuilder;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Map;
+
+public class ModelGenerator {
+
+ public void execute(String sourceFile, String destinationFile, String templateFile, String builderName, String contextConfName) throws IOException, ReflectiveOperationException {
+
+ ContextBuilder contextBuilder = (ContextBuilder) Class.forName(builderName).newInstance();
+ Map<String, Object> context = contextBuilder.buildContext(sourceFile, contextConfName);
+
+ Path destinationPath = Paths.get(destinationFile);
+ if (!Files.isDirectory(destinationPath))
+ Files.createDirectories(destinationPath.getParent());
+ else {
+ Files.createDirectories(destinationPath);
+ }
+
+ this.generate(context, templateFile, destinationFile);
+ System.out.println("\tFile <" + destinationFile + "> prepared successfully");
+ }
+
+ private void generate(Map<String, Object> context, String templateFile, String destinationFile) throws ReflectiveOperationException {
+ try {
+ Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
+ cfg.setClassForTemplateLoading(ModelGenerator.class, "/");
+ Template template = cfg.getTemplate(templateFile);
+
+ Writer out = new CodeGenWriter(destinationFile);
+ template.process(context, out);
+ out.close();
+ } catch (IOException | TemplateException e) {
+ throw new RuntimeException("Failed to generate file from template <" + templateFile + ">", e);
+ }
+ }
+
+}
diff --git a/appc-client/code-generator/src/main/resources/configuration/client-kit.properties b/appc-client/code-generator/src/main/resources/configuration/client-kit.properties
new file mode 100644
index 000000000..047915e44
--- /dev/null
+++ b/appc-client/code-generator/src/main/resources/configuration/client-kit.properties
@@ -0,0 +1,34 @@
+###
+# ============LICENSE_START=======================================================
+# ONAP : APPC
+# ================================================================================
+# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# Copyright (C) 2017 Amdocs
+# =============================================================================
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ECOMP is a trademark and service mark of AT&T Intellectual Property.
+# ============LICENSE_END=========================================================
+###
+
+#
+# Default Properties - Configured for code generator
+#
+#--------------------------------------------------------------------------------------------
+ctx.model.package=org.openecomp.appc.client.lcm.model
+ctx.api.package=org.openecomp.appc.client.lcm.api
+ctx.utils.package=org.openecomp.appc.client.lcm.utils
+ctx.exceptions.package=org.openecomp.appc.client.lcm.exceptions
+ctx.interface.classname=LifeCycleManagerStateful
+
diff --git a/appc-client/code-generator/src/main/resources/templates/client-kit/common.ftl b/appc-client/code-generator/src/main/resources/templates/client-kit/common.ftl
new file mode 100644
index 000000000..ca72829d1
--- /dev/null
+++ b/appc-client/code-generator/src/main/resources/templates/client-kit/common.ftl
@@ -0,0 +1,49 @@
+<#--
+ ============LICENSE_START=======================================================
+ ONAP : APPC
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Copyright (C) 2017 Amdocs
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ============LICENSE_END=========================================================
+-->
+
+<#global template = .main_template_name>
+<#function toJavaName text>
+ <#assign names = text?split("-")>
+ <#assign returnValue = "">
+ <#list names as name>
+ <#assign returnValue = returnValue + name?cap_first>
+ </#list>
+ <#return returnValue?uncap_first>
+</#function>
+<#function toJavaType type>
+ <#switch type>
+ <#case "string">
+ <#return "String">
+ <#case "integer">
+ <#return "int">
+ <#default>
+ <#return type>
+ </#switch>
+</#function>
+<#macro generated>
+@javax.annotation.Generated(
+ value = {"${template}"},
+ date = "${.now?string.iso}",
+ comments = "Auto-generated from Open API specification")
+</#macro>
diff --git a/appc-client/code-generator/src/main/resources/templates/client-kit/enum.ftl b/appc-client/code-generator/src/main/resources/templates/client-kit/enum.ftl
new file mode 100644
index 000000000..2ca633b3f
--- /dev/null
+++ b/appc-client/code-generator/src/main/resources/templates/client-kit/enum.ftl
@@ -0,0 +1,65 @@
+<#--
+ ============LICENSE_START=======================================================
+ ONAP : APPC
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Copyright (C) 2017 Amdocs
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ============LICENSE_END=========================================================
+-->
+
+/**
+ * NOTE: This file is auto-generated and should not be changed manually.
+ */
+package ${meta.model\.package};
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+<#if pojo.description??>
+/**
+* ${pojo.description}
+*
+*/
+</#if>
+public enum ${objectName} {
+
+<#list pojo.enum as enum>
+ ${enum}("${enum}")<#if enum?has_next>,<#else>;</#if>
+</#list>
+
+ private String value;
+
+ ${objectName}(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(value);
+ }
+
+ @JsonCreator
+ public static ${objectName} fromValue(String text) {
+ for (${objectName} var : ${objectName}.values()) {
+ if (String.valueOf(var.value).equals(text)) {
+ return var;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/appc-client/code-generator/src/main/resources/templates/client-kit/open-api-to-java.ftl b/appc-client/code-generator/src/main/resources/templates/client-kit/open-api-to-java.ftl
new file mode 100644
index 000000000..b9a222132
--- /dev/null
+++ b/appc-client/code-generator/src/main/resources/templates/client-kit/open-api-to-java.ftl
@@ -0,0 +1,41 @@
+<#--
+ ============LICENSE_START=======================================================
+ ONAP : APPC
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Copyright (C) 2017 Amdocs
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ============LICENSE_END=========================================================
+-->
+
+<#include "common.ftl">
+<#assign model = model?eval>
+<#assign meta = metadata?eval>
+<#list model.definitions?keys as objectName>
+ <#assign pojo = model.definitions[objectName]>
+__${meta.model\.package}.${objectName}__
+ <#if model.definitions[objectName].enum??>
+ <#include "enum.ftl">
+ <#elseif model.definitions[objectName].properties??>
+ <#include "pojo.ftl">
+ <#else>
+ <#include "primitive-wrapper-pojo.ftl">
+ </#if>
+</#list>
+<#assign service = model.paths>
+__${meta.api\.package}.${meta.interface\.classname}__
+<#include "service.ftl">
diff --git a/appc-client/code-generator/src/main/resources/templates/client-kit/pojo.ftl b/appc-client/code-generator/src/main/resources/templates/client-kit/pojo.ftl
new file mode 100644
index 000000000..1be2d1173
--- /dev/null
+++ b/appc-client/code-generator/src/main/resources/templates/client-kit/pojo.ftl
@@ -0,0 +1,109 @@
+<#--
+ ============LICENSE_START=======================================================
+ ONAP : APPC
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Copyright (C) 2017 Amdocs
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ============LICENSE_END=========================================================
+-->
+
+/**
+ * NOTE: This file is auto-generated and should not be changed manually.
+ */
+package ${meta.model\.package};
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+<#if pojo.description??>
+/**
+ * ${pojo.description}
+ */
+</#if>
+<@generated/>
+public class ${objectName} {
+
+<#assign properties = pojo.properties>
+<#list properties?keys as member>
+ <#if properties[member]?is_hash>
+ <#assign varName = toJavaName(member)>
+ <#if properties[member].type??>
+ <#assign property = properties[member]>
+ <#else>
+ <#assign ref = properties[member].$ref?keep_after_last("/")>
+ <#assign property = model.definitions[ref]>
+ </#if>
+ <#if properties[member].enum??>
+ <#assign varType = property.type?cap_first>
+ public enum ${varName?cap_first} {
+ <#list property.enum as enum>
+ ${enum}<#if enum?has_next>,<#else>;</#if>
+ </#list>
+ }
+
+ @JsonProperty("${member}")
+ private ${varName?cap_first} ${varName};
+ <#else>
+ <#if properties[member].$ref??>
+ <#assign varType = toJavaType(ref)>
+ <#else>
+ <#assign varType = toJavaType(property.type)>
+ </#if>
+ @JsonProperty("${member}")
+ private ${varType} ${varName};
+ </#if>
+ </#if>
+
+</#list>
+<#list properties?keys as member>
+ <#if properties[member]?is_hash>
+ <#if properties[member].type??>
+ <#assign property = properties[member]>
+ <#elseif properties[member].$ref??>
+ <#assign ref = properties[member].$ref?keep_after_last("/")>
+ <#assign property = model.definitions[ref]>
+ </#if>
+ <#if properties[member].$ref??>
+ <#assign varType = ref>
+ <#else>
+ <#assign varType = toJavaType(property.type)>
+ </#if>
+ <#if property.enum??>
+ <#assign varType = toJavaName(member)?cap_first>
+ </#if>
+ <#assign varName = toJavaName(member)>
+ <#if property.description??>
+ /**
+ * ${property.description}
+ */
+ </#if>
+ public ${varType} get${varName?cap_first}() {
+ return ${varName};
+ }
+
+ <#if property.description??>
+ /**
+ * ${property.description}
+ */
+ </#if>
+ public void set${toJavaName(member)?cap_first}(${varType} ${varName}) {
+ this.${varName} = ${varName};
+ }
+
+ </#if>
+</#list>
+}
diff --git a/appc-client/code-generator/src/main/resources/templates/client-kit/primitive-wrapper-pojo.ftl b/appc-client/code-generator/src/main/resources/templates/client-kit/primitive-wrapper-pojo.ftl
new file mode 100644
index 000000000..fd2b2c995
--- /dev/null
+++ b/appc-client/code-generator/src/main/resources/templates/client-kit/primitive-wrapper-pojo.ftl
@@ -0,0 +1,59 @@
+<#--
+ ============LICENSE_START=======================================================
+ ONAP : APPC
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Copyright (C) 2017 Amdocs
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ============LICENSE_END=========================================================
+-->
+
+/**
+ * NOTE: This file is auto-generated and should not be changed manually.
+ */
+package ${meta.model\.package};
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonValue;
+
+<#if pojo.description??>
+/**
+ * ${pojo.description}
+ */
+</#if>
+<@generated/>
+public class ${objectName} {
+<#assign varType = toJavaType(pojo.type)>
+
+ private ${varType} value;
+
+ public ${objectName}() {}
+
+ @JsonCreator
+ public ${objectName}(${varType} value) {
+ this.value = value;
+ }
+
+ @JsonValue
+ public ${varType} getValue() {
+ return value;
+ }
+
+ public void setValue(${varType} value) {
+ this.value = value;
+ }
+}
diff --git a/appc-client/code-generator/src/main/resources/templates/client-kit/service.ftl b/appc-client/code-generator/src/main/resources/templates/client-kit/service.ftl
new file mode 100644
index 000000000..a3a87bdf6
--- /dev/null
+++ b/appc-client/code-generator/src/main/resources/templates/client-kit/service.ftl
@@ -0,0 +1,72 @@
+<#--
+ ============LICENSE_START=======================================================
+ ONAP : APPC
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Copyright (C) 2017 Amdocs
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ============LICENSE_END=========================================================
+-->
+
+/*
+ * NOTE: This file is auto-generated and should not be changed manually.
+ */
+package ${meta.api\.package};
+
+<#list service?keys as action>
+ <#assign outputType = service[action].post.responses["200"].schema.properties.output.$ref?keep_after_last("/")>
+ <#assign inputType = service[action].post.parameters[0].schema.properties.input.$ref?keep_after_last("/")>
+import ${meta.model\.package}.${outputType};
+import ${meta.model\.package}.${inputType};
+</#list>
+import ${meta.exceptions\.package}.AppcClientException;
+import ${meta.utils\.package}.RPC;
+
+<#if model.info.description??>
+/**
+* ${model.info.description}
+*/
+</#if>
+<@generated/>
+public interface ${meta.interface\.classname} {
+
+<#list service?keys as action>
+ <#assign returnType = service[action].post.responses["200"].schema.properties.output.$ref?keep_after_last("/")>
+ <#assign rpcName = service[action].post.operationId>
+ <#assign methodName = toJavaName(rpcName)>
+ <#assign methodInputType = service[action].post.parameters[0].schema.properties.input.$ref?keep_after_last("/")>
+ <#assign methodInputName = methodInputType?uncap_first>
+ <#assign description = service[action].post.description>
+ /**
+ * ${description}
+ *
+ * @param ${methodInputName} - RPC input object
+ */
+ @RPC(name="${rpcName}", outputType=${returnType}.class)
+ ${returnType} ${methodName}(${methodInputType} ${methodInputName}) throws AppcClientException;
+
+ /**
+ * ${description}
+ *
+ * @param ${methodInputName} - RPC input object
+ * @return listener - callback implementation
+ */
+ @RPC(name="${rpcName}", outputType=${returnType}.class)
+ void ${methodName}(${methodInputType} ${methodInputName}, ResponseHandler<${returnType}> listener) throws AppcClientException;
+
+</#list>
+}
diff --git a/appc-client/code-generator/src/main/resources/templates/open-api/yang-to-open-api.ftl b/appc-client/code-generator/src/main/resources/templates/open-api/yang-to-open-api.ftl
new file mode 100644
index 000000000..685efcb02
--- /dev/null
+++ b/appc-client/code-generator/src/main/resources/templates/open-api/yang-to-open-api.ftl
@@ -0,0 +1,314 @@
+<#--
+ ============LICENSE_START=======================================================
+ ONAP : APPC
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Copyright (C) 2017 Amdocs
+ =============================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ ============LICENSE_END=========================================================
+-->
+
+<#global _ = " ">
+<#global __ = _ + _>
+<#global ___ = __ + _>
+<#global ____ = ___ + _>
+<#global _____ = ____ + _>
+<#global ______ = _____ + _>
+<#global _______ = ______ + _>
+<#global ________ = _______ + _>
+<#global _________ = ________ + _>
+<#global __________ = _________ + _>
+<#--
+=================================================================
+ Function definitions
+=================================================================
+-->
+<#function toCamelNotation text>
+ <#local temp = text?upper_case>
+ <#-- Preserve abbreviations (e.g. UUID) - only replace hyphens with underscores, if any -->
+ <#if text == temp>
+ <#return temp?replace("-", "_ ")>
+ <#else>
+ <#return text?replace("-", " ")?capitalize?replace(" ", "")>
+ </#if>
+</#function>
+<#function toRpcInput rpcName>
+ <#return toCamelNotation(rpcName) + "Input">
+</#function>
+<#function toRpcOutput rpcName>
+ <#return toCamelNotation(rpcName) + "Output">
+</#function>
+<#function toJsonType type>
+ <#if type == "string" || type == "enumeration">
+ <#return "string">
+ <#elseif type == "uint16" || type == "uint32">
+ <#return "integer">
+ <#elseif type == "boolean">
+ <#return "boolean">
+ <#else>
+ <#stop "UNSUPPORTED TYPE - ${type}">
+ </#if>
+</#function>
+<#function encode text>
+ <#local temp = text?replace('(\r|\n)+', '', 'r')?replace('( )+', ' ', 'rm')>
+ <#return temp>
+</#function>
+<#--
+ Similar to Java's Class.isAssignableFrom(Class)
+-->
+<#function isAssignableFrom class typeName>
+ <#list class.interfaces as interfaceClass>
+ <#if interfaceClass.name == typeName || isAssignableFrom(interfaceClass, typeName)>
+ <#return true>
+ </#if>
+ </#list>
+ <#return false>
+</#function>
+<#function isContainerNode node>
+ <#return isAssignableFrom(node.class, "org.opendaylight.yangtools.yang.model.api.DataNodeContainer")>
+</#function>
+<#function isLeafNode node>
+ <#return isAssignableFrom(node.class, "org.opendaylight.yangtools.yang.model.api.LeafSchemaNode")>
+</#function>
+<#function isEnumType type>
+ <#return isAssignableFrom(type.class, "org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition")>
+</#function>
+<#function isStringType type>
+ <#return isAssignableFrom(type.class, "org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition")>
+</#function>
+<#function isExtendedType type>
+ <#if type.baseType??>
+ <#return true>
+ </#if>
+ <#return false>
+</#function>
+<#function isGlobalTypeDef obj>
+ <#list module.typeDefinitions as typeDef>
+ <#if typeDef.QName.localName == obj.type.QName.localName>
+ <#return true>
+ </#if>
+ </#list>
+ <#return false>
+</#function>
+<#function getMandatoryProperties obj>
+ <#local result = {}>
+ <#list obj.childNodes as property>
+ <#if property.constraints.mandatory>
+ <#local result = result + {property.QName.localName : ""}>
+ </#if>
+ </#list>
+ <#return result>
+</#function>
+<#function gatherModuleTypes module>
+ <#local result = {}>
+ <#list module.rpcs as rpc>
+ <#local result = gatherNestedTypes(rpc.input, result)>
+ <#local result = gatherNestedTypes(rpc.output, result)>
+ </#list>
+ <#return result>
+</#function>
+<#function gatherNestedTypes container result>
+ <#list container.childNodes as property>
+ <#if isContainerNode(property)>
+ <#local name = property.QName.localName>
+ <#if !result[name]??>
+ <#local result = result + {name : property}>
+ <#local result = gatherNestedTypes(property, result)>
+ </#if>
+ </#if>
+ </#list>
+ <#return result>
+</#function>
+<#--
+=================================================================
+ Macro definitions
+=================================================================
+-->
+<#--
+ Macro to generate description property, if any.
+-->
+<#macro description obj indent = "">
+<#if obj.description??>
+${indent},
+${indent}"description" : "${encode(obj.description)}"<#else>${indent}</#if>
+</#macro>
+<#--
+ Macro to generate enum of valid values
+-->
+<#macro enum yangType indent = "">
+<#if isEnumType(yangType)>
+${indent},
+${indent}"enum" : [
+${indent}${_}<#list yangType.values as enum>"${enum.name}"<#if enum?has_next>, </#if></#list>
+${indent}]
+</#if>
+</#macro>
+<#--
+ Macro to print out schema constraints (min/max/pattern/etc.) if any. Used for custom types defined either globaly via 'typedef'
+ statement or locally (in-line withing a leaf node definition).
+ -->
+<#macro constraints yangType indent = "">
+<#if yangType.patternConstraints?size != 0>
+${indent},
+${indent}"pattern" : "${yangType.patternConstraints?first.regularExpression?replace('\\\\', '\\\\\\\\', 'r')}"
+</#if>
+<#if yangType.lengthConstraints?size != 0>
+${indent},
+${indent}"minLength" : ${yangType.lengthConstraints?first.min},
+${indent}"maxLength" : ${yangType.lengthConstraints?first.max}
+</#if>
+<@enum yangType = yangType.baseType indent = indent />
+</#macro>
+<#--
+ Macro to generate a property within an outer object
+ -->
+<#macro property name prop indent = "">
+${indent}"${name}": {
+<#if isContainerNode(prop)>
+${indent}${_}"$ref" : "#/definitions/${toCamelNotation(prop.QName.localName)}"
+<#elseif isExtendedType(prop.type) && isGlobalTypeDef(prop)>
+${indent}${_}"$ref" : "#/definitions/${toCamelNotation(prop.type.QName.localName)}"
+<#elseif isExtendedType(prop.type)>
+${indent}${_}"type" : "${toJsonType(prop.type.QName.localName)}"
+<@description obj = prop indent = indent + _ />
+<@constraints yangType = prop.type indent = indent + _ />
+<#else><#-- leaf node -->
+${indent}${_}"type" : "${toJsonType(prop.type.QName.localName)}"
+<@description obj = prop indent = indent + _ />
+<@enum yangType = prop.type indent = indent + _ />
+</#if>
+${indent}}</#macro>
+<#--
+ Macro generates declaration of a container node modeled in YANG schema
+-->
+<#macro container name node indent = "">
+${indent}"${name}" : {
+${indent}${_}"type" : "object"
+<@description obj = node indent = indent + _ />
+${indent}${_},
+${indent}${_}"properties" : {
+<#list node.childNodes as child>
+<@property name = child.QName.localName prop = child indent = indent + __ /><#if child?has_next>,</#if>
+</#list>
+${indent}${_}}<#-- end of properties -->
+<#local mandatoryProperties = getMandatoryProperties(node)>
+<#if mandatoryProperties?size != 0>
+,
+${indent}${_}"required" : [<#list mandatoryProperties?keys as p>"${p}"<#if p?has_next> ,</#if></#list>]
+</#if>
+${indent}}<#-- end of container -->
+</#macro>
+<#--
+ Macro generates declaration of JSON object for a custom type defined in YANG schema via 'typedef' statement.
+-->
+<#macro typedef name yangType indent = "">
+${indent}"${name}" : {
+<#local jsonType = toJsonType(yangType.baseType.QName.localName)>
+${indent}${_}"type" : "${jsonType}"
+<@description obj = yangType indent = indent + _ />
+<@constraints yangType = yangType indent = indent + _ />
+${indent}}<#-- end of container -->
+</#macro>
+<#--
+=================================================================
+ Content body
+=================================================================
+-->
+<#assign moduleName = module.name>
+{
+${_}"swagger": "2.0",
+${_}"info": {
+${__}"version": "${module.QNameModule.formattedRevision}"
+<@description obj = module indent = __ />,
+${__}"contact": {
+${_____}"name" : "${module.contact}"
+${__}},
+${__}"title": "${moduleName}"
+${_}},
+${_}"basePath": "/restconf",
+${_}"tags": [{"name": "${moduleName}"}],
+${_}"schemes": [ "https", "http" ],
+${_}"paths": {
+<#list module.rpcs as rpc>
+<#assign rpcName = rpc.QName.localName>
+${__}"/operations/${moduleName}:${rpcName}": {
+${___}"post": {
+${____}"tags": ["${moduleName}"],
+${____}"summary": ""
+<@description obj = rpc indent = ____ />,
+${____}"operationId": "${rpcName}",
+${____}"consumes": ["application/json"],
+${____}"produces": ["application/json"],
+${____}"parameters": [{
+${_____}"in": "body",
+${_____}"name": "input",
+${_____}"required": true,
+${_____}"schema": {
+${______}"type" : "object",
+${______}"properties" : {
+${_______}"input" : {
+${________}"$ref": "#/definitions/${toRpcInput(rpcName)}"
+${_______}}
+${______}}
+${_____}}
+${____}}],
+${____}"responses": {
+${_____}"200": {
+${______}"description": "Successful operation",
+${______}"schema": {
+${_______}"type" : "object",
+${_______}"properties" : {
+${________}"output" : {
+${_________}"$ref": "#/definitions/${toRpcOutput(rpcName)}"
+${________}}
+${_______}}
+${______}}
+${_____}},
+${_____}"401": {"description" : "Unauthorized"},
+${_____}"500": {"description" : "Internal server error"}
+${____}}
+${___}}
+${__}}<#if rpc?has_next>,</#if>
+</#list>
+${_}},
+${_}"definitions": {
+<#--
+ Definition per custom type defined via 'typedef'
+-->
+<#list module.typeDefinitions as typeDef>
+<@typedef name = toCamelNotation(typeDef.QName.localName) yangType = typeDef indent = __ />
+<#if typeDef?has_next>${__},</#if>
+</#list>
+<#--
+ Definition per container explicitly defined in YANG schema
+-->
+<#assign definitions = gatherModuleTypes(module)>
+<#if module.typeDefinitions?size != 0 && definitions?size != 0>${__},</#if>
+<#list definitions?keys as definition>
+<@container name = toCamelNotation(definition) node = definitions[definition] indent = __ /><#if definition?has_next>${__},</#if>
+</#list>
+<#if definitions?size != 0 && module.rpcs?size != 0>${__},</#if>
+<#--
+ Definition per PRC input/output parameter block implicitly defined in YANG schema
+-->
+<#list module.rpcs as rpc>
+<#assign rpcName = rpc.QName.localName>
+<@container name = toRpcInput(rpcName) node = rpc.input indent = __ />${__},
+<@container name = toRpcOutput(rpcName) node = rpc.output indent = __ /><#if rpc?has_next>${__},</#if>
+</#list>
+${_}}<#-- end of "definitions" -->
+} <#-- end of file -->