From 47ef15fef5cdd02f99ce1546c557fe8c74591d46 Mon Sep 17 00:00:00 2001 From: frank feng Date: Wed, 6 Sep 2023 14:24:11 +0800 Subject: fix bug for yang comparator and refactor yang compiler Issue-ID: MODELING-680 Change-Id: I3a04b24d6b02aff2a376c95d6f7508294b65aa57 Signed-off-by: frank feng --- .../comparator/CommonYangStatementComparator.java | 6 + yang-compiler/README.md | 314 ++++++++++ yang-compiler/build.json | 56 ++ yang-compiler/pom.xml | 13 +- .../onap/modeling/yangkit/catalog/ModuleInfo.java | 50 +- .../modeling/yangkit/compiler/BuildOption.java | 174 ++++++ .../onap/modeling/yangkit/compiler/Builder.java | 112 ---- .../modeling/yangkit/compiler/DirectorySource.java | 84 +++ .../onap/modeling/yangkit/compiler/FileSource.java | 84 +++ .../modeling/yangkit/compiler/ModuleSource.java | 153 +++++ .../onap/modeling/yangkit/compiler/Parameter.java | 71 +++ .../yangkit/compiler/ParameterBuilder.java | 69 --- .../org/onap/modeling/yangkit/compiler/Plugin.java | 85 +++ .../modeling/yangkit/compiler/PluginBuilder.java | 86 --- .../onap/modeling/yangkit/compiler/PluginInfo.java | 2 +- .../org/onap/modeling/yangkit/compiler/Source.java | 26 + .../modeling/yangkit/compiler/YangCompiler.java | 604 +++---------------- .../yangkit/compiler/app/YangCompilerRunner.java | 116 +++- .../compiler/plugin/YangCompilerPlugin.java | 65 ++ .../plugin/YangCompilerPluginParameter.java | 35 ++ .../modeling/yangkit/compiler/plugin/stat/Tag.java | 45 ++ .../compiler/plugin/stat/YangNodeDescription.java | 130 ++++ .../compiler/plugin/stat/YangStatistics.java | 408 +++++++++++++ .../compiler/plugin/validator/YangValidator.java | 47 ++ .../compiler/plugin/yangpackage/ModuleInfo.java | 117 ++++ .../compiler/plugin/yangpackage/PackageInfo.java | 45 ++ .../plugin/yangpackage/SubComponentInfo.java | 171 ++++++ .../compiler/plugin/yangpackage/SubModuleInfo.java | 125 ++++ .../compiler/plugin/yangpackage/YangPackage.java | 395 +++++++++++++ .../plugin/yangpackage/YangPackageGenerator.java | 154 +++++ .../plugin/yangpackage/YangPackageMeta.java | 187 ++++++ .../yangtree/GroupingSchemaNodeContainer.java | 151 +++++ .../plugin/yangtree/YangTreeGenerator.java | 655 +++++++++++++++++++++ .../yangkit/compiler/util/YangCompilerUtil.java | 441 ++++++++++++++ .../yangkit/plugin/YangCompilerPlugin.java | 74 --- .../plugin/YangCompilerPluginParameter.java | 35 -- .../yangkit/plugin/stat/YangNodeDescription.java | 96 --- .../yangkit/plugin/stat/YangStatistics.java | 278 --------- .../yangkit/plugin/validator/YangValidator.java | 46 -- .../yangkit/plugin/yangpackage/ModuleInfo.java | 117 ---- .../yangkit/plugin/yangpackage/PackageInfo.java | 45 -- .../plugin/yangpackage/SubComponentInfo.java | 171 ------ .../yangkit/plugin/yangpackage/SubModuleInfo.java | 125 ---- .../yangkit/plugin/yangpackage/YangPackage.java | 395 ------------- .../plugin/yangpackage/YangPackageGenerator.java | 154 ----- .../plugin/yangpackage/YangPackageMeta.java | 187 ------ .../yangtree/GroupingSchemaNodeContainer.java | 141 ----- .../yangkit/plugin/yangtree/YangTreeGenerator.java | 654 -------------------- yang-compiler/src/main/resources/log4j.properties | 25 + yang-compiler/src/main/resources/plugins.json | 60 ++ yang-compiler/src/main/resources/yang-compiler.png | Bin 0 -> 146547 bytes yang-compiler/src/main/resources/yc-build.yang | 54 ++ .../main/resources/yc-yang-compiler-settings.yang | 20 + 53 files changed, 4616 insertions(+), 3337 deletions(-) create mode 100644 yang-compiler/README.md create mode 100644 yang-compiler/build.json create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/BuildOption.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Builder.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/DirectorySource.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/FileSource.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/ModuleSource.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Parameter.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/ParameterBuilder.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Plugin.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/PluginBuilder.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Source.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/YangCompilerPlugin.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/YangCompilerPluginParameter.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/Tag.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/YangNodeDescription.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/YangStatistics.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/validator/YangValidator.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/ModuleInfo.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/PackageInfo.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/SubComponentInfo.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/SubModuleInfo.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackage.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackageGenerator.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackageMeta.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangtree/GroupingSchemaNodeContainer.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangtree/YangTreeGenerator.java create mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/util/YangCompilerUtil.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/YangCompilerPlugin.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/YangCompilerPluginParameter.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/stat/YangNodeDescription.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/stat/YangStatistics.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/validator/YangValidator.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/ModuleInfo.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/PackageInfo.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/SubComponentInfo.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/SubModuleInfo.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackage.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackageGenerator.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackageMeta.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangtree/GroupingSchemaNodeContainer.java delete mode 100644 yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangtree/YangTreeGenerator.java create mode 100644 yang-compiler/src/main/resources/log4j.properties create mode 100644 yang-compiler/src/main/resources/plugins.json create mode 100644 yang-compiler/src/main/resources/yang-compiler.png create mode 100644 yang-compiler/src/main/resources/yc-build.yang create mode 100644 yang-compiler/src/main/resources/yc-yang-compiler-settings.yang diff --git a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java index 8b03304..8be269e 100644 --- a/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java +++ b/yang-comparator/src/main/java/org/onap/modeling/yangkit/comparator/CommonYangStatementComparator.java @@ -370,6 +370,12 @@ public class CommonYangStatementComparator extends Abst * @return true or false */ public static boolean yangStatementIsEqual(YangStatement left, YangStatement right) { + if ((null == left) || (null == right)) { + if ((null == left) && (null == right)) { + return true; + } + return false; + } if ((left instanceof SchemaNode) && (right instanceof SchemaNode)) { SchemaNode leftSchemaNode = (SchemaNode) left; SchemaNode rightSchemaNode = (SchemaNode) right; diff --git a/yang-compiler/README.md b/yang-compiler/README.md new file mode 100644 index 0000000..40d94c4 --- /dev/null +++ b/yang-compiler/README.md @@ -0,0 +1,314 @@ +# **YANG Compiler** +## Overview +Yang compiler is a tool based on [YangKit](https://github.com/yang-central/yangkit), it's designed to solve the problem of YANG files compilation dependencies. +For example, after a YANG module is written, if you want to validate it, you need to add all missing YANG module dependencies to your path. This could be troublesome because dependencies are chained, and the chain of dependencies for a YANG module may be very long. In addition, +where these dependented YANG files are archived and how to obtain these YANG files are also difficult problems. This brings great inconvenience to users and +affects their enthusiasm for using YANG. + +Yang compiler provide a mechanism to get the dependencies automatically when compiling YANG modules. Firstly, it will search the dependencies from yang sources to be complied, if not found, it will search these YANG files from local repository(it's defined in settings.json or default directory), and if it's not found also, it will search the dependencies from module information defined in settings.json(if available), and according to the information to download the YANG files. if it's still not found, it will search the dependencies for remote repository(defined in settings.json or +[yangcatalog](https://yangcatalog.org/api/) by default). If the dependencies are fetched, it will be saved into local repository. + +Using Yang compiler, you can compile any YANG file regardless where it's dependencies are. Yang compiler allow developer to develop +plugin to extend customized functions. +## Architecture +![yang-compiler](src/main/resources/yang-compiler.png) +## Specification +* search and download dependencies automatically. +* allow user to customize settings for compilation. + * customize local repository,{user.home}/.yang is default. + * customize remote repository, [yangcatalog](https://yangcatalog.org/api/) is default. + * support proxy. + * define module information directly if some modules are not in [yangcatalog](https://yangcatalog.org/api/). +* allow user to install yang files which are compiled OK. +* allow developer to develop customized plugin. + + +## Installation +###  Prerequisites +* JDK or JRE 1.8 or above + +###  Obtain code +``` +# git clone https://github.com/yang-central/yang-compiler.git +``` +###  Build code +``` +# cd yang-compiler +# mvn clean install +``` + it will generate yang-compiler-1.0-SNAPSHOT.jar and libs directory under the directory target. + +###  Make application package for YANG compiler +1. create a directory in anywhere (of your computer), we may call it application directory. The name of directory should be yang-compiler-x.y.z(e.g., yang-compiler-1.0.0) +2. copy yang-compiler-1.0-SNAPSHOT.jar and libs to the application directory you created in previous step. +3. (optional)place settings.json into application directory if needed. +4. (optional)create a sub-directory named 'plugins' under application directory if external plugins are need, then place plugins.json into this directory. +####   Example of application package +``` +|--yang-compiler-1.0.0 + |--libs + |--plugins + |----plugins.json + |--settings.json + |--yang-compiler-1.0.0.jar +``` + +## Specification of settings +1. local-repository: local repo directory to find the missing yang module dependencies, the default directory is {user.home}/.yang +2. remote-repository: remote url, it will fetch the yang module dependencies to local repo if yang compiler request, [yangcatalog](https://yangcatalog.org/api/) is default. +3. proxy: the proxy information, if you are in local network and can't access internet directly, the proxy information must be provided. + 1. url: the url of proxy including port number. + 2. authentication: the authentication information, username and password should be provided if needed by proxy. +4. token: the token information, if the remote repo needed. +5. module-info: the information of yang schema. if some dependencies are not in local and remote repos, you can specify the schema information by hand. + 1. name: module name,mandatory. + 2. revision: revision date,mandatory. + 3. schema: the url where the yang schema stores. +###  Example: +```json + { + + "settings": { + + "local-repository": "/Users/llly/yang", + + "remote-repository": "https://yangcatalog.org/api/", + + "proxy": { + + "url":"http:proxy.mydomain.com:8080", + + "authentication": { + + "username":"foo", + + "password":"bar" + + } + + }, + + "module-info": [ + { + + "name": "openconfig-acl", + + "revision": "2022-01-14", + + "schema": "https://raw.githubusercontent.com/openconfig/public/master/release/models/acl/openconfig-acl.yang" + + }, + + { + "name": "openconfig-packet-match-types", + + "revision": "2021-07-14", + + "schema": "https://raw.githubusercontent.com/openconfig/public/master/release/models/acl/openconfig-packet-match-types.yang" + + } + + ] + + } + +} +``` +## Develop plugin +The plugin system of Yang compiler support built-in plugin and external plugin. Built-in plugin is in yang-compiler project, and external plugin can be in anywhere. +###  Specification of plugin information +1. name: the name of plugin, it MUST be unique. +2. class-path: the class path of plugin class, it MUST be provided when the plugin is an external plugin. It can be relative path or absolute path, + if it's a relative path, the base path is plugins directory of application directory. + +3. class: class name which implements org.yangcentral.yangkit.compiler.plugin.YangCompilerPlugin. +4. description: some description information about this plugin. +5. parameter: parameter information, it's json array. name and description of a parameter MUST be provided. + +###  How to develop a built-in plugin +1. specified a unique plugin name. e.g. yang-tree-generator. +2. write a java class implements YangCompilerPlugin. + @see [YangValidator](src/main/java/org/yangcentral/yangkit/plugin/yangtree/YangTreeGenerator.java) +3. add plugin information in plugins.json(in src/main/resource) +####   Example + ```json + { + + "plugins": { + + "plugin": [ + + { + + "name": "validator_plugin", + + "class": "org.yangcentral.yangkit.compiler.plugin.validator.YangValidator", + + "description": "a plugin for validating yang files", + + "parameter": [ + + { + + "name": "output", + + "description": "the output directory." + + } + + ] + + } + + ] + + } + + } + ``` +###  How to develop an external plugin +1. specified a unique plugin name. e.g. yang-tree-generator. +2. create a java project, and write a java class implements YangCompilerPlugin. +3. build the java project, and get the corresponding jar. +4. add plugin information to plugins.json ({application directory}/plugins/plugins.json), class-path MUST point to the jar generated at previous step. +####   Example +```json +{ + "plugins": { + "plugin": [ + { + "name": "yang_comparator", + "class-path": "yang-comparator/yang-comparator-1.0-SNAPSHOT.jar", + "class": "com.huawei.yang.comparator.YangComparatorPlugin", + "description": "a plugin for comparing two yang schema.", + "parameter": [ + { + "name": "old-yang", + "description": "mandatory,the old version yang directory." + }, + { + "name": "settings", + "description": "optional,the settings file path." + }, + { + "name": "compare-type", + "description": "mandatory, specify compare-type, one of stmt,tree,or compatible-check" + }, + { + "name": "rule", + "description": "optional, specify the path of compatible-rule file." + }, + { + "name": "result", + "description": "mandatory, specify the compare result file path, the result file is a xml format." + } + ] + } + ] + } +} +``` +## Compile YANG modules: +1. make a yang compiler project. You can create a directory in anywhere of your computer. +2. make a directory under project directory as target directory where YANG modules what you want to compile store. 'yang' is recommended as the name of the directory. +3. place build.json into project directory. The build.json specify the options of this compilation. +4. execute the commandline to compile YANG modules. +###  Example of yang compiler project +``` +|--yang-test(project name) + |--yang(yang modules to be compiled) + |--build.json +``` +###  Specification of compilation options +1. yang: source yang information, support directory, file list, module information, or hybrid. +2. settings: specify the path of settings.json, optional, if it's not present, the {user.home}/.yang/settings.json will be used. +3. plugin: a json array,specify the parameters of plugins which will be called. + 1. name: the plugin name. + 2. parameter: the parameters of a plugin. name and value should be specified. +####   Examples: +```json +{ + "yang": { + + "module": [ + { + "name": "ietf-interfaces", + "revision": "" + }, + { + "name": "huawei-ifm", + "revision": "2022-08-06" + }, + { + "name": "huawei-bgp", + "revision": "" + }, + { + "name": "huawei-network-instance", + "revision": "" + } + ], + "dir" : [ + "yang/ietf", + "yang/huawei" + ], + "file" : [ + "yang/ietf/ietf-interfaces.yang", + "yang/huawei/huawei-bgp.yang" + ] + }, + "settings" : "settings.json", + "plugin": [ + { + "name": "validator_plugin", + "parameter": [ + { + "name": "output", + "value": "yang/validator.txt" + } + ] + }, + { + "name": "yangtree_generator", + "parameter": [ + { + "name": "output", + "value": "tree" + }, + { + "name": "expand-grouping", + "value": "true" + } + ] + }, + { + "name": "yang_statistics", + "parameter" : [ + { + "name": "output", + "value": "statistics/node_description.xlsx" + }, + { + "name" : "tag", + "value": [ + { + "name": "operation-exclude", + "keyword": "huawei-extension:operation-exclude" + } + ] + } + ] + } + + ] + + + } + ``` +###  Commandline +``` +# java -jar yang-compiler-1.0-SNAPSHOT.jar [option=<_build.json_>] [install] +``` +####   Parameters +1. option: optional, specify the build option. It's the path of build.json, if not present, the build.json in current directory will be used. +2. install: optional, if it's not present, the yang files to be complied will not be copied into local repo directory, if it's present, all yang files which is successfully compiled will be copied into local repository. diff --git a/yang-compiler/build.json b/yang-compiler/build.json new file mode 100644 index 0000000..43d258e --- /dev/null +++ b/yang-compiler/build.json @@ -0,0 +1,56 @@ +{ + "yang": { + "module": [ + { + "name": "ietf-interfaces", + "revision": "" + }, + { + "name": "huawei-ifm", + "revision": "2022-08-06" + }, + { + "name": "huawei-bgp", + "revision": "" + }, + { + "name": "huawei-network-instance", + "revision": "" + } + ] + }, + "plugin": [ + { + "name": "yangtree_generator", + "parameter": [ + { + "name": "output", + "value": "tree" + }, + { + "name": "expand-grouping", + "value": "true" + } + ] + }, + { + "name": "yang_statistics", + "parameter" : [ + { + "name": "output", + "value": "statistics/node_description.xlsx" + }, + { + "name" : "tag", + "value": [ + { + "name": "operation-exclude", + "keyword": "huawei-extension:operation-exclude" + } + ] + } + ] + } + ] + +} \ No newline at end of file diff --git a/yang-compiler/pom.xml b/yang-compiler/pom.xml index cdd6626..f739e39 100644 --- a/yang-compiler/pom.xml +++ b/yang-compiler/pom.xml @@ -64,7 +64,7 @@ io.github.yang-central.yangkit yangkit-parser - 1.3.3 + 1.3.6 @@ -77,11 +77,6 @@ commons-lang3 3.12.0 - - org.antlr - antlr4-runtime - 4.11.1 - org.dom4j dom4j @@ -103,6 +98,12 @@ poi-ooxml 5.2.3 + + io.github.yang-central.yangkit + yang-compiler + 1.3.1 + compile + yang compiler yang compiler: compile yang modules regardless where the dependencies are (by resolve and download diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/catalog/ModuleInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/catalog/ModuleInfo.java index 31bb51e..5e128a3 100644 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/catalog/ModuleInfo.java +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/catalog/ModuleInfo.java @@ -27,14 +27,15 @@ import java.net.URI; public class ModuleInfo { private final String name; private final String revision; - private final String organization; + private String organization; private URI schema; /** * The constructor of ModuleInfo. - * @param name module name - * @param revision module revision - * @param organization the organization who publish this module + * + * @param name module name + * @param revision module revision + * @param organization the organization who publish this module */ public ModuleInfo(String name, String revision, String organization) { this.name = name; @@ -42,16 +43,18 @@ public class ModuleInfo { this.organization = organization; } - /** - * set schema. - * @param schema the URI of schema - */ + public ModuleInfo(String name, String revision) { + this.name = name; + this.revision = revision; + } + public void setSchema(URI schema) { this.schema = schema; } /** * get module name. + * * @return module name */ public String getName() { @@ -60,6 +63,7 @@ public class ModuleInfo { /** * get module's revision. + * * @return revision */ public String getRevision() { @@ -68,6 +72,7 @@ public class ModuleInfo { /** * get organization. + * * @return organization */ public String getOrganization() { @@ -76,14 +81,38 @@ public class ModuleInfo { /** * get schema. + * * @return URI */ public URI getSchema() { return schema; } + /** + * whether this module info with revision. + * @return true or false + */ + public boolean withRevision() { + if (revision != null && !revision.isEmpty()) { + return true; + } + return false; + } + + /** + * get the module information string. + * @return module information + */ + public String getModuleInfo() { + if (withRevision()) { + return name + "@" + revision; + } + return name; + } + /** * parse module info from json. + * * @param element json element * @return ModuleInfo */ @@ -101,16 +130,17 @@ public class ModuleInfo { return null; } URI schema = URI.create(schemaElement.getAsString()); - if (name == null || revision == null) { + if (name == null || revision == null || schema == null) { return null; } - ModuleInfo moduleInfo = new ModuleInfo(name,revision,organization); + ModuleInfo moduleInfo = new ModuleInfo(name, revision, organization); moduleInfo.setSchema(schema); return moduleInfo; } /** * parse module information from json string. + * * @param str json string * @return Module information */ diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/BuildOption.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/BuildOption.java new file mode 100644 index 0000000..328d2a4 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/BuildOption.java @@ -0,0 +1,174 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.onap.modeling.yangkit.catalog.ModuleInfo; + + + + +public class BuildOption { + private List sources = new ArrayList<>(); + private List plugins = new ArrayList<>(); + + private String settings; + + /** + * the constructor. + */ + public BuildOption() { + } + + /** + * get all sources. + * @return list of sources + */ + public List getSources() { + return sources; + } + + /** + * add a source to build option. + * @param source candidate source + */ + public void addSource(Source source) { + if (sources.contains(source)) { + return; + } + sources.add(source); + } + + /** + * get plugins of build option. + * @return list of plugins + */ + public List getPlugins() { + return plugins; + } + + /** + * set the list of plugins. + * + * @param plugins the list of plugins + */ + public void setPlugins(List plugins) { + this.plugins = plugins; + } + + /** + * add a plugin. + * + * @param plugin plugin to be added. + */ + public void addPlugin(Plugin plugin) { + this.plugins.add(plugin); + } + + public String getSettings() { + return settings; + } + + public void setSettings(String settings) { + this.settings = settings; + } + + /** + * parse the build.json. + * + * @param jsonElement json element + * @return builder structure + */ + public static BuildOption parse(JsonElement jsonElement) { + BuildOption buildOption = new BuildOption(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + JsonElement yangElement = jsonObject.get("yang"); + if (yangElement != null) { + JsonObject yang = yangElement.getAsJsonObject(); + JsonElement dirElement = yang.get("dir"); + if (dirElement != null) { + JsonArray dirArray = dirElement.getAsJsonArray(); + List dirElementList = dirArray.asList(); + List dirs = new ArrayList<>(); + for (JsonElement dirElementItem : dirElementList) { + String yangDir = dirElementItem.getAsString(); + dirs.add(yangDir); + } + DirectorySource directorySource = new DirectorySource(dirs); + buildOption.addSource(directorySource); + } + JsonElement filesElement = yang.get("file"); + if (filesElement != null) { + JsonArray fileArray = filesElement.getAsJsonArray(); + List fileElementList = fileArray.asList(); + List files = new ArrayList<>(); + for (JsonElement fileElementItem : fileElementList) { + String yangFile = fileElementItem.getAsString(); + files.add(yangFile); + } + FileSource fileSource = new FileSource(files); + buildOption.addSource(fileSource); + } + JsonElement modulesElement = yang.get("module"); + if (modulesElement != null) { + JsonArray moduleArray = modulesElement.getAsJsonArray(); + List moduleList = moduleArray.asList(); + List moduleInfos = new ArrayList<>(); + for (JsonElement moduleElement : moduleList) { + JsonObject moduleObject = moduleElement.getAsJsonObject(); + String name = moduleObject.get("name").getAsString(); + String revision = moduleObject.get("revision").getAsString(); + String organization = null; + if (moduleObject.get("organization") != null) { + organization = moduleObject.get("organization").getAsString(); + } + URI schema = null; + if (moduleObject.get("schema") != null) { + schema = URI.create(moduleObject.get("schema").getAsString()); + } + ModuleInfo moduleInfo = new ModuleInfo(name, revision, organization); + moduleInfo.setSchema(schema); + moduleInfos.add(moduleInfo); + } + ModuleSource moduleSource = new ModuleSource(moduleInfos); + buildOption.addSource(moduleSource); + } + } + JsonElement settingsElement = jsonObject.get("settings"); + if (settingsElement != null) { + buildOption.setSettings(settingsElement.getAsString()); + } + JsonElement pluginsElement = jsonObject.get("plugin"); + if (pluginsElement != null) { + JsonArray plugins = pluginsElement.getAsJsonArray(); + for (int i = 0; i < plugins.size(); i++) { + JsonElement pluginElement = plugins.get(i); + Plugin plugin = Plugin.parse(pluginElement); + buildOption.addPlugin(plugin); + } + } + return buildOption; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Builder.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Builder.java deleted file mode 100644 index 7436447..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Builder.java +++ /dev/null @@ -1,112 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.compiler; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.util.ArrayList; -import java.util.List; - - -public class Builder { - private String yangDir; - private List plugins = new ArrayList<>(); - - /** - * the constructor. - */ - public Builder() { - } - - /** - * get yang directory where the yang files to be compiled exist. - * - * @return the directory path - */ - public String getYangDir() { - return yangDir; - } - - /** - * set the yang directory. - * - * @param yangDir the path of yang directory - */ - public void setYangDir(String yangDir) { - this.yangDir = yangDir; - } - - /** - * get the plugins. - * - * @return the list of plugins - */ - public List getPlugins() { - return plugins; - } - - /** - * set the list of plugins. - * - * @param plugins the list of plugins - */ - public void setPlugins(List plugins) { - this.plugins = plugins; - } - - /** - * add a plugin. - * - * @param pluginBuilder plugin to be added. - */ - public void addPlugin(PluginBuilder pluginBuilder) { - this.plugins.add(pluginBuilder); - } - - /** - * parse the build.json. - * - * @param jsonElement json element - * @return builder structure - */ - public static Builder parse(JsonElement jsonElement) { - JsonObject jsonObject = jsonElement.getAsJsonObject(); - JsonElement buildElement = jsonObject.get("build"); - Builder builder = new Builder(); - if (buildElement == null) { - return builder; - } - JsonObject buildObj = buildElement.getAsJsonObject(); - JsonElement yangElement = buildObj.get("yang"); - if (yangElement != null) { - String yang = yangElement.getAsString(); - builder.setYangDir(yang); - } - JsonElement pluginsElement = buildObj.get("plugin"); - if (pluginsElement != null) { - JsonArray plugins = pluginsElement.getAsJsonArray(); - for (int i = 0; i < plugins.size(); i++) { - JsonElement pluginElement = plugins.get(i); - PluginBuilder pluginBuilder = PluginBuilder.parse(pluginElement); - builder.addPlugin(pluginBuilder); - } - } - return builder; - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/DirectorySource.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/DirectorySource.java new file mode 100644 index 0000000..e1c5019 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/DirectorySource.java @@ -0,0 +1,84 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler; + +import java.util.ArrayList; +import java.util.List; + +import org.onap.modeling.yangkit.catalog.ModuleInfo; +import org.onap.modeling.yangkit.compiler.util.YangCompilerUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; +import org.yangcentral.yangkit.model.api.stmt.Module; +import org.yangcentral.yangkit.parser.YangYinParser; + + + +public class DirectorySource implements Source { + private List dirs = new ArrayList<>(); + private static final Logger logger = LoggerFactory.getLogger(DirectorySource.class); + + public DirectorySource(List dirs) { + this.dirs = dirs; + } + + + @Override + public YangSchemaContext buildSource(Settings settings, YangSchemaContext yangSchemaContext) + throws YangCompilerException { + return buildSource(settings, yangSchemaContext, false); + } + + @Override + public YangSchemaContext buildSource(Settings settings, YangSchemaContext schemaContext, boolean withDependencies) + throws YangCompilerException { + for (String dir : dirs) { + try { + logger.info("start to build schema context for dir:" + dir); + schemaContext = YangYinParser.parse(dir, schemaContext); + if (withDependencies) { + logger.info("start to build dependencies for dir:" + dir); + for (Module module : schemaContext.getModules()) { + if (!module.getElementPosition().getSource().contains(dir)) { + continue; + } + List dependencies = YangCompilerUtil.getDependencies(module); + if (!dependencies.isEmpty()) { + List extraDependencies = new ArrayList<>(); + for (ModuleInfo dependency : dependencies) { + if (schemaContext.getModule(dependency.getName(), dependency.getRevision()) + .isPresent()) { + continue; + } + extraDependencies.add(dependency); + } + ModuleSource extraDependenciesSource = new ModuleSource(extraDependencies, true); + schemaContext = extraDependenciesSource.buildSource(settings, schemaContext, true); + } + } + logger.info("end to build dependencies for dir:" + dir); + } + logger.info("end to build schema context for dir:" + dir); + } catch (Exception e) { + throw new YangCompilerException(e.getMessage()); + } + } + return schemaContext; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/FileSource.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/FileSource.java new file mode 100644 index 0000000..a6f26bc --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/FileSource.java @@ -0,0 +1,84 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.onap.modeling.yangkit.catalog.ModuleInfo; +import org.onap.modeling.yangkit.compiler.util.YangCompilerUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; +import org.yangcentral.yangkit.model.api.stmt.Module; +import org.yangcentral.yangkit.parser.YangYinParser; + + +public class FileSource implements Source { + private List files; + private static final Logger logger = LoggerFactory.getLogger(FileSource.class); + + public FileSource(List files) { + this.files = files; + } + + @Override + public YangSchemaContext buildSource(Settings settings, YangSchemaContext yangSchemaContext) + throws YangCompilerException { + return buildSource(settings, yangSchemaContext, false); + } + + @Override + public YangSchemaContext buildSource(Settings settings, YangSchemaContext schemaContext, boolean withDependencies) + throws YangCompilerException { + List fileList = new ArrayList<>(); + for (String file : files) { + fileList.add(new File(file)); + } + try { + logger.info("start to build schema context for files:" + files); + schemaContext = YangYinParser.parse(fileList, schemaContext); + if (withDependencies) { + logger.info("start to build dependencies for files:" + files); + for (Module module : schemaContext.getModules()) { + String source = module.getElementPosition().getSource(); + if (!files.contains(source)) { + continue; + } + List dependencies = YangCompilerUtil.getDependencies(module); + if (!dependencies.isEmpty()) { + List extraDependencies = new ArrayList<>(); + for (ModuleInfo dependency : dependencies) { + if (schemaContext.getModule(dependency.getName(), dependency.getRevision()).isPresent()) { + continue; + } + extraDependencies.add(dependency); + } + ModuleSource extraDependenciesSource = new ModuleSource(extraDependencies, true); + schemaContext = extraDependenciesSource.buildSource(settings, schemaContext, true); + } + } + logger.info("end to build dependencies for files:" + files); + } + logger.info("end to build schema context for files:" + files); + return schemaContext; + } catch (Exception e) { + throw new YangCompilerException(e.getMessage()); + } + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/ModuleSource.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/ModuleSource.java new file mode 100644 index 0000000..96977da --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/ModuleSource.java @@ -0,0 +1,153 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.onap.modeling.yangkit.catalog.ModuleInfo; +import org.onap.modeling.yangkit.compiler.util.YangCompilerUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.yangcentral.yangkit.model.api.schema.ModuleId; +import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; +import org.yangcentral.yangkit.model.api.stmt.Module; +import org.yangcentral.yangkit.parser.YangYinParser; +import org.yangcentral.yangkit.utils.file.FileUtil; + + +public class ModuleSource implements Source { + private List modules; + + private boolean importOnly; + private static final Logger logger = LoggerFactory.getLogger(ModuleSource.class); + + public ModuleSource(List modules) { + this.modules = modules; + } + + public ModuleSource(List modules, boolean importOnly) { + this.modules = modules; + this.importOnly = importOnly; + } + + public boolean isImportOnly() { + return importOnly; + } + + public void setImportOnly(boolean importOnly) { + this.importOnly = importOnly; + } + + public List getModules() { + return modules; + } + + @Override + public YangSchemaContext buildSource(Settings settings, YangSchemaContext yangSchemaContext) + throws YangCompilerException { + return buildSource(settings, yangSchemaContext, false); + } + + @Override + public YangSchemaContext buildSource(Settings settings, YangSchemaContext schemaContext, boolean withDependencies) + throws YangCompilerException { + ModuleInfo targetModuleInfo = null; + for (ModuleInfo moduleInfo : modules) { + if (schemaContext != null) { + Optional oldModule = schemaContext.getModule( + new ModuleId(moduleInfo.getName(), moduleInfo.getRevision())); + if (oldModule.isPresent()) { + if (!importOnly && schemaContext.isImportOnly(oldModule.get())) { + schemaContext.removeModule(oldModule.get().getModuleId()); + schemaContext.addModule(oldModule.get()); + } + continue; + } + } + URI schema = moduleInfo.getSchema(); + if (schema == null) { + try { + targetModuleInfo = YangCompilerUtil.getSchema(moduleInfo, settings); + } catch (IOException e) { + throw new YangCompilerException(e.getMessage()); + } + if (targetModuleInfo == null) { + throw new YangCompilerException("module=" + + moduleInfo.getModuleInfo() + + " is not found."); + } + schema = targetModuleInfo.getSchema(); + } + if (targetModuleInfo == null) { + targetModuleInfo = moduleInfo; + } + + + try { + logger.info("download yang from " + schema.toURL()); + String yangString = YangCompilerUtil.urlInvoke2String(schema.toURL().toString(), settings); + + InputStream inputStream = new ByteArrayInputStream(yangString.getBytes()); + String parseModuleInfo = schema.toURL().toString(); + schemaContext = YangYinParser.parse(inputStream, + parseModuleInfo, true, importOnly, schemaContext); + //judge whether this module exists in local repository + if (YangCompilerUtil.getSchemaFromLocal(targetModuleInfo, settings) == null) { + // if not found, install to local repository + String fileName = settings.getLocalRepository() + File.separator + targetModuleInfo.getModuleInfo() + + ".yang"; + FileUtil.writeUtf8File(fileName, yangString); + logger.info("install " + targetModuleInfo.getModuleInfo() + ".yang to " + + settings.getLocalRepository()); + } + if (withDependencies) { + logger.info("get dependencies for " + targetModuleInfo.getModuleInfo()); + Module sourceModule = + schemaContext.getModule(targetModuleInfo.getName(), targetModuleInfo.getRevision()) + .get(); + + List dependencies = YangCompilerUtil.getDependencies(sourceModule); + if (!dependencies.isEmpty()) { + List extraDependencies = new ArrayList<>(); + for (ModuleInfo dependency : dependencies) { + if (schemaContext.getModule(dependency.getName(), dependency.getRevision()).isPresent()) { + continue; + } + extraDependencies.add(dependency); + } + ModuleSource extraDependenciesSource = new ModuleSource(extraDependencies, true); + logger.info("start to build dependencies for " + targetModuleInfo.getModuleInfo()); + schemaContext = extraDependenciesSource.buildSource(settings, schemaContext, true); + logger.info("end to build dependencies for " + targetModuleInfo.getModuleInfo()); + } + } + + } catch (Exception e) { + throw new YangCompilerException(e.getMessage()); + } + } + return schemaContext; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Parameter.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Parameter.java new file mode 100644 index 0000000..54f9236 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Parameter.java @@ -0,0 +1,71 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public class Parameter { + private String name; + private JsonElement value; + + /** + * the constructor. + * + * @param name the name of parameter + * @param value the value of parameter + */ + public Parameter(String name, JsonElement value) { + this.name = name; + this.value = value; + } + + /** + * get the parameter name. + * + * @return name + */ + public String getName() { + return name; + } + + /** + * get the parameter value. + * + * @return value + */ + public JsonElement getValue() { + return value; + } + + /** + * parse parameter from json. + * + * @param jsonElement json element + * @return parameter + */ + public static Parameter parse(JsonElement jsonElement) { + JsonObject jsonObject = jsonElement.getAsJsonObject(); + String name = jsonObject.get("name").getAsString(); + JsonElement value = null; + if (jsonObject.get("value") != null) { + value = jsonObject.get("value"); + } + Parameter parameter = new Parameter(name, value); + return parameter; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/ParameterBuilder.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/ParameterBuilder.java deleted file mode 100644 index ea8ad7a..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/ParameterBuilder.java +++ /dev/null @@ -1,69 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.compiler; - -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - - -public class ParameterBuilder { - private final String name; - private final String value; - - /** - * the constructor. - * - * @param name the name of parameter - * @param value the value of parameter - */ - public ParameterBuilder(String name, String value) { - this.name = name; - this.value = value; - } - - /** - * get the parameter name. - * - * @return name - */ - public String getName() { - return name; - } - - /** - * get the parameter value. - * - * @return value - */ - public String getValue() { - return value; - } - - /** - * parse parameter from json. - * - * @param jsonElement json element - * @return parameter - */ - public static ParameterBuilder parse(JsonElement jsonElement) { - JsonObject jsonObject = jsonElement.getAsJsonObject(); - String name = jsonObject.get("name").getAsString(); - String value = jsonObject.get("value").getAsString(); - ParameterBuilder parameterBuilder = new ParameterBuilder(name, value); - return parameterBuilder; - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Plugin.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Plugin.java new file mode 100644 index 0000000..91939a4 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Plugin.java @@ -0,0 +1,85 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; + +import java.util.ArrayList; +import java.util.List; + +public class Plugin { + private String name; + private List parameters = new ArrayList<>(); + + /** + * the constructor. + * + * @param name the plugin name + */ + public Plugin(String name) { + this.name = name; + } + + /** + * get the plugin name. + * + * @return name + */ + public String getName() { + return name; + } + + /** + * get all parameters of plugin. + * + * @return the list of parameters + */ + public List getParameters() { + return parameters; + } + + /** + * add parameter into plugin. + * + * @param para parameter + */ + public void addParameter(Parameter para) { + parameters.add(para); + } + + /** + * parse plugin from json. + * + * @param jsonElement json element + * @return plugin builder + */ + public static Plugin parse(JsonElement jsonElement) { + String name = jsonElement.getAsJsonObject().get("name").getAsString(); + Plugin plugin = new Plugin(name); + JsonElement parasElement = jsonElement.getAsJsonObject().get("parameter"); + if (parasElement != null) { + JsonArray paras = parasElement.getAsJsonArray(); + for (int i = 0; i < paras.size(); i++) { + JsonElement paraElement = paras.get(i); + Parameter parameter = Parameter.parse(paraElement); + plugin.addParameter(parameter); + } + } + return plugin; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/PluginBuilder.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/PluginBuilder.java deleted file mode 100644 index 489d1f7..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/PluginBuilder.java +++ /dev/null @@ -1,86 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.compiler; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; - -import java.util.ArrayList; -import java.util.List; - - -public class PluginBuilder { - private final String name; - private final List parameters = new ArrayList<>(); - - /** - * the constructor. - * - * @param name the plugin name - */ - public PluginBuilder(String name) { - this.name = name; - } - - /** - * get the plugin name. - * - * @return name - */ - public String getName() { - return name; - } - - /** - * get all parameters of plugin. - * - * @return the list of parameters - */ - public List getParameters() { - return parameters; - } - - /** - * add parameter into plugin. - * - * @param para parameter - */ - public void addParameter(ParameterBuilder para) { - parameters.add(para); - } - - /** - * parse plugin from json. - * - * @param jsonElement json element - * @return plugin builder - */ - public static PluginBuilder parse(JsonElement jsonElement) { - String name = jsonElement.getAsJsonObject().get("name").getAsString(); - PluginBuilder pluginBuilder = new PluginBuilder(name); - JsonElement parasElement = jsonElement.getAsJsonObject().get("parameter"); - if (parasElement != null) { - JsonArray paras = parasElement.getAsJsonArray(); - for (int i = 0; i < paras.size(); i++) { - JsonElement paraElement = paras.get(i); - ParameterBuilder parameterBuilder = ParameterBuilder.parse(paraElement); - pluginBuilder.addParameter(parameterBuilder); - } - } - return pluginBuilder; - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/PluginInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/PluginInfo.java index a042dd0..63b82ef 100644 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/PluginInfo.java +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/PluginInfo.java @@ -32,7 +32,7 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import org.onap.modeling.yangkit.plugin.YangCompilerPlugin; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPlugin; @SuppressWarnings("ALL") diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Source.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Source.java new file mode 100644 index 0000000..f3443ed --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/Source.java @@ -0,0 +1,26 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler; + +import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; + +public interface Source { + YangSchemaContext buildSource(Settings settings, YangSchemaContext yangSchemaContext) throws YangCompilerException; + + YangSchemaContext buildSource(Settings settings, YangSchemaContext yangSchemaContext, boolean withDependencies) + throws YangCompilerException; +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/YangCompiler.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/YangCompiler.java index 7d4975d..87a1c5e 100644 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/YangCompiler.java +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/YangCompiler.java @@ -16,52 +16,28 @@ limitations under the License. package org.onap.modeling.yangkit.compiler; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; + import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.net.Authenticator; -import java.net.InetSocketAddress; -import java.net.PasswordAuthentication; -import java.net.Proxy; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Properties; -import java.util.Scanner; import java.util.concurrent.ConcurrentHashMap; -import javax.annotation.Nullable; - -import org.dom4j.DocumentException; import org.onap.modeling.yangkit.catalog.ModuleInfo; -import org.onap.modeling.yangkit.catalog.YangCatalog; -import org.onap.modeling.yangkit.plugin.YangCompilerPlugin; -import org.onap.modeling.yangkit.plugin.YangCompilerPluginParameter; -import org.yangcentral.yangkit.base.YangBuiltinKeyword; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPlugin; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPluginParameter; +import org.onap.modeling.yangkit.compiler.util.YangCompilerUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.yangcentral.yangkit.base.YangElement; import org.yangcentral.yangkit.common.api.validate.ValidatorRecord; import org.yangcentral.yangkit.common.api.validate.ValidatorResult; import org.yangcentral.yangkit.common.api.validate.ValidatorResultBuilder; -import org.yangcentral.yangkit.model.api.schema.ModuleId; import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; import org.yangcentral.yangkit.model.api.stmt.Module; -import org.yangcentral.yangkit.model.api.stmt.SubModule; import org.yangcentral.yangkit.model.api.stmt.YangStatement; -import org.yangcentral.yangkit.parser.YangParser; -import org.yangcentral.yangkit.parser.YangParserEnv; -import org.yangcentral.yangkit.parser.YangParserException; -import org.yangcentral.yangkit.parser.YangYinParser; import org.yangcentral.yangkit.utils.file.FileUtil; -import org.yangcentral.yangkit.utils.url.URLUtil; import org.yangcentral.yangkit.writter.YangFormatter; import org.yangcentral.yangkit.writter.YangWriter; @@ -69,34 +45,24 @@ import org.yangcentral.yangkit.writter.YangWriter; public class YangCompiler { private Settings settings; - private File yang; private final Map pluginInfos = new ConcurrentHashMap(); - private Builder builder; + private BuildOption buildOption; + + private boolean install; + + private static final Logger logger = LoggerFactory.getLogger(YangCompiler.class); - /** - * constructor. - */ public YangCompiler() { } - /** - * get the builder. - * - * @return builder class - */ - public Builder getBuilder() { - return builder; + public BuildOption getBuildOption() { + return buildOption; } - /** - * set builder. - * - * @param builder builder - */ - public void setBuilder(Builder builder) { - this.builder = builder; + public void setBuildOption(BuildOption buildOption) { + this.buildOption = buildOption; } /** @@ -145,445 +111,103 @@ public class YangCompiler { this.settings = settings; } - /** - * get yang directory file handler. - * - * @return yang directory file handler. - */ - public File getYang() { - return yang; + public boolean isInstall() { + return install; } - /** - * set yang directory file handler. - * - * @param yang file handler - */ - public void setYang(File yang) { - this.yang = yang; + public void setInstall(boolean install) { + this.install = install; } /** - * get all dependencies of a specified module. - * - * @param module module - * @return dependencies + * build schema context from build option. + * @return yang schema context */ - private List getDependencies(Module module) { - List dependencies = new ArrayList<>(); - if (module == null) { - return dependencies; - } - List importStatements = module.getSubStatement(YangBuiltinKeyword.IMPORT.getQName()); - for (YangStatement importStatement : importStatements) { - String moduleName = importStatement.getArgStr(); - String revision = null; - List revisions = importStatement.getSubStatement(YangBuiltinKeyword.REVISIONDATE.getQName()); - if (revisions.isEmpty()) { - revision = ""; - } else { - revision = revisions.get(0).getArgStr(); - } - ModuleId moduleId = new ModuleId(moduleName, revision); - dependencies.add(moduleId); - } - List includeStatements = module.getSubStatement(YangBuiltinKeyword.INCLUDE.getQName()); - for (YangStatement includeStatement : includeStatements) { - String moduleName = includeStatement.getArgStr(); - String revision = null; - List revisions = - includeStatement.getSubStatement(YangBuiltinKeyword.REVISIONDATE.getQName()); - if (revisions.isEmpty()) { - revision = ""; - } else { - revision = revisions.get(0).getArgStr(); - } - ModuleId moduleId = new ModuleId(moduleName, revision); - dependencies.add(moduleId); - } - if (module instanceof SubModule) { - List belongsToStatements = module.getSubStatement(YangBuiltinKeyword.BELONGSTO.getQName()); - String moduleName = belongsToStatements.get(0).getArgStr(); - ModuleId moduleId = new ModuleId(moduleName, ""); - dependencies.add(moduleId); - } - return dependencies; - } - - private String urlInvoke(String url) throws IOException { - URL catalogUrl = URI.create(url).toURL(); - Proxy proxy = null; - Authenticator authenticator = null; - if (settings.getProxy() != null) { - String protocol = catalogUrl.getProtocol(); - Proxy.Type proxyType = null; - if (protocol.equalsIgnoreCase("http") || protocol.equalsIgnoreCase("https")) { - proxyType = Proxy.Type.HTTP; - } else { - proxyType = Proxy.Type.SOCKS; - } - proxy = new Proxy(proxyType, - new InetSocketAddress(settings.getProxy().getHostName(), settings.getProxy().getPort())); - if (settings.getProxy().getAuthentication() != null) { - authenticator = new Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(settings.getProxy().getAuthentication().getName(), - settings.getProxy().getAuthentication().getPassword().toCharArray() - ); - } - }; - Authenticator.setDefault(authenticator); + public YangSchemaContext buildSchemaContext() { + YangSchemaContext schemaContext = null; + try { + List sources = buildOption.getSources(); + for (Source source : sources) { + schemaContext = source.buildSource(settings, schemaContext, true); } + return schemaContext; + } catch (YangCompilerException e) { + throw new RuntimeException(e); } - return URLUtil.URLGet(catalogUrl, proxy, authenticator, settings.getToken()); } - private File getFromLocal(ModuleId moduleId) { - File localRepository = new File(settings.getLocalRepository()); - if (!localRepository.exists()) { - localRepository.mkdirs(); - } - String prefix = - moduleId.getModuleName() + (moduleId.getRevision().equals("") ? "" : "@" + moduleId.getRevision()); - String suffix = ".yang"; - FilenameFilter filenameFilter = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - if (dir != localRepository) { - return false; - } - if (name.startsWith(prefix) && name.endsWith(suffix)) { - String moduleDesc = name.substring(0, name.indexOf(suffix)); - String[] moduleInfo = moduleDesc.split("@"); - String moduleName = moduleInfo[0]; - String revision = moduleInfo[1]; - if (!moduleName.equals(moduleId.getModuleName())) { - return false; - } - if (moduleId.getRevision() != null && moduleId.getRevision().length() > 0) { - if (!revision.equals(moduleId.getRevision())) { - return false; - } - } - return true; - } - return false; - } - }; - System.out.print("[INFO]finding module:" + moduleId.getModuleName() - + (moduleId.getRevision().isEmpty() ? "" : moduleId.getRevision()) - + " from " + localRepository.getAbsolutePath() - + " ..."); - File[] matched = localRepository.listFiles(filenameFilter); - if (matched == null || matched.length == 0) { - System.out.println("not found."); - return null; - } - if (matched.length == 1) { - System.out.println("get " + matched[0].getName()); - return matched[0]; - } - File latest = null; - if (matched.length > 1) { - for (File file : matched) { - if (latest == null) { - latest = file; - } else { - if (file.getName().compareTo(latest.getName()) > 0) { - latest = file; - } - } - } + private void saveModule(String fileName, List elements) { + StringBuilder sb = new StringBuilder(); + for (YangElement element : elements) { + String yangStr = YangWriter.toYangString(element, YangFormatter.getPrettyYangFormatter(), null); + sb.append(yangStr); + sb.append("\n"); } - System.out.println("get " + latest.getName()); - return latest; - } - - private File getFromRemote(ModuleId moduleId) throws IOException { - ModuleInfo moduleInfo = null; - if (moduleId.getRevision() == null || moduleId.getRevision().equals("")) { - String url = settings.getRemoteRepository() + "search/name/" + moduleId.getModuleName(); - System.out.print("[INFO]downloading module info:" + moduleId.getModuleName() + " from " + url + " ..."); - YangCatalog yangCatalog = YangCatalog.parse(urlInvoke(url)); - moduleInfo = yangCatalog.getLatestModule(moduleId.getModuleName()); - System.out.println(moduleInfo == null ? " not found." : "revision=" + moduleInfo.getRevision()); - - } else { - String organization = moduleId.getModuleName().substring(0, moduleId.getModuleName().indexOf("-")); - if (organization.equals("junos")) { - organization = "juniper"; - } - String url = settings.getRemoteRepository() - + "search/modules/" - + moduleId.getModuleName() - + "," - + moduleId.getRevision() - + "," - + organization; - System.out.print("[INFO]downloading module info:" - + moduleId.getModuleName() - + " from " - + url - + " ..."); - moduleInfo = ModuleInfo.parse(urlInvoke(url)); - System.out.println(moduleInfo == null ? " not found." : "finished"); - } - if (moduleInfo == null) { - return null; - } - System.out.print("[INFO]downloading content of module:" + moduleInfo.getName() + "@" + moduleInfo.getRevision() - + " from " + moduleInfo.getSchema().toString() + " ..."); - String yangString = urlInvoke(moduleInfo.getSchema().toString()); - System.out.println("finished."); - File localRepositoryFile = new File(settings.getLocalRepository()); - if (!localRepositoryFile.exists()) { - localRepositoryFile.mkdirs(); - } - String yangfileName = moduleInfo.getName() + "@" + moduleInfo.getRevision() + ".yang"; - File localYangFile = new File(localRepositoryFile, yangfileName); - FileUtil.writeUtf8File(yangString, localYangFile); - System.out.println("[INFO]save module:" - + moduleInfo.getName() - + "@" - + moduleInfo.getRevision() - + " to " - + localYangFile.getAbsolutePath()); - return localYangFile; + fileName = settings.getLocalRepository() + File.separator + fileName; + FileUtil.writeUtf8File(fileName, sb.toString()); } - private File getFromSettings(ModuleId moduleId) throws IOException { - ModuleInfo moduleInfo = null; - if (moduleId.getRevision() == null || moduleId.getRevision().equals("")) { - moduleInfo = settings.getLatestModuleInfo(moduleId.getModuleName()); - System.out.print("[INFO]getting module info:" - + moduleId.getModuleName() - + " from settings"); - System.out.println(moduleInfo == null ? " not found." : "revision=" - + moduleInfo.getRevision()); - - } else { - System.out.print("[INFO]getting module info:" - + moduleId.getModuleName() - + " from settings."); - moduleInfo = settings.getModuleInfo(moduleId.getModuleName(), moduleId.getRevision()); - System.out.println(moduleInfo == null ? " not found." : "finished"); - - } - if (moduleInfo == null) { - return null; - } - System.out.print("[INFO]downloading content of module:" - + moduleInfo.getName() - + "@" - + moduleInfo.getRevision() - + " from " - + moduleInfo.getSchema().toString() - + " ..."); - String yangString = urlInvoke(moduleInfo.getSchema().toString()); - System.out.println("finished."); - File localRepositoryFile = new File(settings.getLocalRepository()); - if (!localRepositoryFile.exists()) { - localRepositoryFile.mkdirs(); - } - String yangfileName = moduleInfo.getName() - + "@" - + moduleInfo.getRevision() - + ".yang"; - File localYangFile = new File(localRepositoryFile, yangfileName); - FileUtil.writeUtf8File(yangString, localYangFile); - System.out.println("[INFO]save module:" - + moduleInfo.getName() - + "@" - + moduleInfo.getRevision() - + " to " - + localYangFile.getAbsolutePath()); - return localYangFile; - } - - private void buildDependencies(YangSchemaContext schemaContext, List dependencies) - throws IOException, YangParserException, YangCompilerException { - for (ModuleId moduleId : dependencies) { - if (schemaContext.getModule(moduleId).isPresent()) { - continue; - } - //firstly,get yang file from local repository - File file = getFromLocal(moduleId); - if (file == null) { - //secondly,if not found,get yang file from settings - file = getFromSettings(moduleId); - if (file == null) { - //thirdly, if not found, get yang file from remote repository - file = getFromRemote(moduleId); - } + private void installModules(List modules) { + for (Module module : modules) { + String moduleName = module.getArgStr(); + String revision = ""; + if (module.getCurRevisionDate().isPresent()) { + revision = module.getCurRevisionDate().get(); } - if (file == null) { - throw new YangCompilerException("can not find the yang module named:" - + moduleId.getModuleName(), - moduleId); + ModuleInfo moduleInfo = new ModuleInfo(moduleName, revision, null); + ModuleInfo targetModuleInfo = YangCompilerUtil.getSchemaFromLocal(moduleInfo, settings); + if (targetModuleInfo == null) { + //if not found, save this module to local repository + List elements = module.getContext().getSchemaContext().getParseResult() + .get(module.getElementPosition().getSource()); + saveModule(moduleInfo.getModuleInfo() + ".yang", elements); + logger.info("install " + moduleInfo.getModuleInfo() + ".yang" + " to " + settings.getLocalRepository()); } - YangParserEnv env = new YangParserEnv(); - env.setCurPos(0); - env.setYangStr(FileUtil.readFile2String(file)); - env.setFilename(file.getAbsolutePath()); - YangParser yangParser = new YangParser(); - List yangElements = yangParser.parseYang(env.getYangStr(), env); - schemaContext.getParseResult().put(env.getFilename(), yangElements); - Module module = null; - for (YangElement yangElement : yangElements) { - if (yangElement instanceof Module) { - module = (Module) yangElement; - schemaContext.addImportOnlyModule(module); - break; - } - } - if (module != null) { - List subDependencies = getDependencies(module); - if (!subDependencies.isEmpty()) { - buildDependencies(schemaContext, subDependencies); - } - - } - } - } - - /** - * build yang schema context. - * - * @return yang schema context - */ - public YangSchemaContext buildSchemaContext() { - if (!yang.exists()) { - return null; - } - try { - YangSchemaContext schemaContext = YangYinParser.parse(yang); - for (Module module : schemaContext.getModules()) { - List dependencies = getDependencies(module); - buildDependencies(schemaContext, dependencies); - } - return schemaContext; - } catch (IOException e) { - throw new RuntimeException(e); - } catch (YangParserException e) { - throw new RuntimeException(e); - } catch (DocumentException e) { - throw new RuntimeException(e); - } catch (YangCompilerException e) { - throw new RuntimeException(e); } } /** - * compile yang files. - * - * @param yangdir yang directory - * @param settingsfile the path of settings.json - * @param install whether install to local repository - * @throws IOException io exception - * @throws URISyntaxException uri syntax exception + * compile yang modules and invoke plugins. */ - public void compile(@Nullable String yangdir, @Nullable String settingsfile, boolean install) - throws IOException, URISyntaxException { - String defaultSettingsfile = - System.getProperty("user.home") - + File.separator - + ".yang" - + File.separator - + "settings.json"; - Settings settings = null; - if (settingsfile != null) { - settings = Settings.parse(FileUtil.readFile2String(settingsfile)); - } else { - File defaultSettingsFile = new File(defaultSettingsfile); - if (defaultSettingsFile.exists()) { - settings = Settings.parse(FileUtil.readFile2String(defaultSettingsfile)); - } else { - File programDir = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation() - .toURI()); - File programSettings = new File(programDir.getParentFile(), "settings.json"); - if (programSettings.exists()) { - settings = Settings.parse(FileUtil.readFile2String(programSettings)); - } else { - settings = new Settings(); - } - - } - } - - setSettings(settings); - File builderFile = new File("build.json"); - if (builderFile.exists()) { - Builder builder = prepareBuilder(FileUtil.readFile2String(builderFile)); - setBuilder(builder); - if (yangdir == null) { - yangdir = builder.getYangDir(); - } - } - if (yangdir == null) { - yangdir = "yang"; - //System.out.println("no yang directory!"); - //System.out.println("Usage: yang-compiler yang={yang directory} [settings={settings.json}] [install]"); - //return; - } - File yangDirFile = new File(yangdir); - if (!yangDirFile.exists()) { - System.out.println("yang directory:" - + yangdir - + " is not exist!"); + public void compile() { + if (buildOption == null) { + logger.warn("build.json is not found."); return; } - setYang(new File(yangdir)); - Properties compilerProps = new Properties(); - compilerProps.setProperty("yang", yangdir); - if (settings.getLocalRepository() != null) { - compilerProps.setProperty("local-repository", settings.getLocalRepository()); - } - - if (settings.getRemoteRepository() != null) { - compilerProps.setProperty("remote-repository", settings.getRemoteRepository().toString()); - } - - preparePlugins(this); - + logger.info("build yang schema context."); YangSchemaContext schemaContext = buildSchemaContext(); ValidatorResult validatorResult = schemaContext.validate(); if (!validatorResult.isOk()) { + logger.error("there are some errors when validating yang schema context."); System.out.println(validatorResult); return; } - if (getBuilder() != null) { - for (PluginBuilder pluginBuilder : getBuilder().getPlugins()) { - PluginInfo pluginInfo = getPluginInfo(pluginBuilder.getName()); - if (null == pluginInfo) { - System.out.println("can not find a plugin named:" - + pluginBuilder.getName()); - continue; - } - YangCompilerPlugin plugin = pluginInfo.getPlugin(); - try { - List parameters = new ArrayList<>(); - if (!pluginBuilder.getParameters().isEmpty()) { - for (ParameterBuilder parameterBuilder : pluginBuilder.getParameters()) { - YangCompilerPluginParameter parameter = plugin.getParameter(compilerProps, - parameterBuilder.getName(), parameterBuilder.getValue()); - if (parameter != null) { - parameters.add(parameter); - } + for (Plugin pluginBuilder : getBuildOption().getPlugins()) { + PluginInfo pluginInfo = getPluginInfo(pluginBuilder.getName()); + if (null == pluginInfo) { + logger.warn("can not find a plugin named:" + pluginBuilder.getName()); + continue; + } + YangCompilerPlugin plugin = pluginInfo.getPlugin(); + try { + List parameters = new ArrayList<>(); + if (!pluginBuilder.getParameters().isEmpty()) { + for (Parameter parameterBuilder : pluginBuilder.getParameters()) { + YangCompilerPluginParameter parameter = plugin.getParameter( + parameterBuilder.getName(), parameterBuilder.getValue()); + if (parameter != null) { + parameters.add(parameter); } } - System.out.println("[INFO]call plugin:" - + pluginInfo.getPluginName() - + " ..."); - plugin.run(schemaContext, this, parameters); - System.out.println("ok."); - } catch (YangCompilerException e) { - System.out.println("[ERROR]" - + e.getMessage()); } + logger.info("call plugin:" + pluginInfo.getPluginName() + " ..."); + plugin.run(schemaContext, this, parameters); + logger.info("ok."); + } catch (YangCompilerException e) { + logger.error(e.getMessage()); } } ValidatorResultBuilder validatorResultBuilder = new ValidatorResultBuilder(); @@ -598,78 +222,10 @@ public class YangCompiler { } validatorResult = validatorResultBuilder.build(); if (install && validatorResult.isOk()) { - for (Module module : schemaContext.getModules()) { - List elements = - schemaContext.getParseResult().get(module.getElementPosition().getSource()); - StringBuilder sb = new StringBuilder(); - for (YangElement element : elements) { - String yangStr = YangWriter.toYangString(element, YangFormatter.getPrettyYangFormatter(), null); - sb.append(yangStr); - sb.append("\n"); - } - String moduleDesc = module.getArgStr() - + (module.getCurRevisionDate().isPresent() ? "@" + module.getCurRevisionDate().get() : ""); - String fileName = settings.getLocalRepository() - + File.separator + moduleDesc; - FileUtil.writeUtf8File(fileName, sb.toString()); - System.out.println("[INFO]install " - + moduleDesc - + " to " - + settings.getLocalRepository()); - - } + installModules(schemaContext.getModules()); } - System.out.println(validatorResult); + logger.info(validatorResult.toString()); } - private static void preparePlugins(YangCompiler yangCompiler) throws IOException, URISyntaxException { - InputStream inputStream = yangCompiler.getClass().getResourceAsStream("/plugins.json"); - Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"); - String result = scanner.hasNext() ? scanner.next() : ""; - if (!result.isEmpty()) { - List pluginInfos = parsePlugins(null, result); - for (PluginInfo pluginInfo : pluginInfos) { - yangCompiler.addPluginInfo(pluginInfo); - } - } - File programDir = new File(yangCompiler.getClass().getProtectionDomain().getCodeSource().getLocation() - .toURI()); - File pluginsDir = new File(programDir.getParentFile(), "plugins"); - if (!pluginsDir.exists()) { - System.out.println("[WARNING]plugins dir:" - + pluginsDir.getAbsolutePath() - + " is not exists"); - return; - } - File pluginsFile = new File(pluginsDir, "plugins.json"); - if (pluginsFile.exists()) { - System.out.println("[INFO]reading the information of plugins from:" - + pluginsFile.getAbsolutePath()); - List pluginInfos = parsePlugins(pluginsFile, FileUtil.readFile2String(pluginsFile)); - for (PluginInfo pluginInfo : pluginInfos) { - yangCompiler.addPluginInfo(pluginInfo); - } - } - - } - - private static List parsePlugins(File pluginsFile, String str) { - List pluginInfos = new ArrayList<>(); - JsonElement pluginsElement = JsonParser.parseString(str); - JsonObject jsonObject = pluginsElement.getAsJsonObject(); - JsonObject pluginsObject = jsonObject.get("plugins").getAsJsonObject(); - JsonArray pluginList = pluginsObject.getAsJsonArray("plugin"); - for (int i = 0; i < pluginList.size(); i++) { - JsonElement pluginElement = pluginList.get(i); - PluginInfo pluginInfo = PluginInfo.parse(pluginsFile, pluginElement); - pluginInfos.add(pluginInfo); - } - return pluginInfos; - } - - private static Builder prepareBuilder(String str) { - JsonElement jsonElement = JsonParser.parseString(str); - return Builder.parse(jsonElement); - } } diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/app/YangCompilerRunner.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/app/YangCompilerRunner.java index 650e444..217ffad 100644 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/app/YangCompilerRunner.java +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/app/YangCompilerRunner.java @@ -16,31 +16,86 @@ limitations under the License. package org.onap.modeling.yangkit.compiler.app; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.URISyntaxException; -import org.onap.modeling.yangkit.compiler.YangCompiler; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import org.onap.modeling.yangkit.compiler.BuildOption; +import org.onap.modeling.yangkit.compiler.PluginInfo; +import org.onap.modeling.yangkit.compiler.Settings; +import org.onap.modeling.yangkit.compiler.YangCompiler; +import org.yangcentral.yangkit.utils.file.FileUtil; public class YangCompilerRunner { + private static List parsePlugins(File pluginsFile, String str) { + List pluginInfos = new ArrayList<>(); + JsonElement pluginsElement = JsonParser.parseString(str); + JsonObject jsonObject = pluginsElement.getAsJsonObject(); + JsonObject pluginsObject = jsonObject.get("plugins").getAsJsonObject(); + JsonArray pluginList = pluginsObject.getAsJsonArray("plugin"); + for (int i = 0; i < pluginList.size(); i++) { + JsonElement pluginElement = pluginList.get(i); + PluginInfo pluginInfo = PluginInfo.parse(pluginsFile, pluginElement); + pluginInfos.add(pluginInfo); + } + return pluginInfos; + } + + private static void preparePlugins(YangCompiler yangCompiler) throws IOException, URISyntaxException { + InputStream inputStream = yangCompiler.getClass().getResourceAsStream("/plugins.json"); + Scanner scanner = new Scanner(inputStream).useDelimiter("\\A"); + String result = scanner.hasNext() ? scanner.next() : ""; + if (!result.isEmpty()) { + List pluginInfos = parsePlugins(null, result); + for (PluginInfo pluginInfo : pluginInfos) { + yangCompiler.addPluginInfo(pluginInfo); + } + } + File programDir = new File(yangCompiler.getClass().getProtectionDomain().getCodeSource().getLocation() + .toURI()); + File pluginsDir = new File(programDir.getParentFile(), "plugins"); + if (!pluginsDir.exists()) { + System.out.println("[WARNING]plugins dir:" + pluginsDir.getAbsolutePath() + " is not exists"); + return; + } + File pluginsFile = new File(pluginsDir, "plugins.json"); + if (pluginsFile.exists()) { + System.out.println("[INFO]reading the information of plugins from:" + pluginsFile.getAbsolutePath()); + List pluginInfos = parsePlugins(pluginsFile, FileUtil.readFile2String(pluginsFile)); + for (PluginInfo pluginInfo : pluginInfos) { + yangCompiler.addPluginInfo(pluginInfo); + } + } + + + } + /** - * the main method of yang compiler runner. + * main function of yang compiler. + * * @param args arguments - * @throws IOException io exception - * @throws URISyntaxException uri syntax exception + * @throws IOException io exception + * @throws URISyntaxException URI syntax exception */ public static void main(String[] args) throws IOException, URISyntaxException { - String yangdir = null; - String settingsfile = null; + String option = null; boolean install = false; for (String arg : args) { String[] paras = arg.split("="); if (paras.length == 2) { String para = paras[0]; String value = paras[1]; - if (para.equals("yang")) { - yangdir = value; - } else if (para.equals("settings")) { - settingsfile = value; + if (para.equals("option")) { + option = value; } } else { if (arg.equals("install")) { @@ -48,7 +103,46 @@ public class YangCompilerRunner { } } } + if (option == null) { + option = "build.json"; + } + // get build option + File optionFile = new File(option); + if (!optionFile.exists()) { + System.out.println("The option file:" + option + " is not found."); + return; + } + JsonElement jsonElement = JsonParser.parseString(FileUtil.readFile2String(optionFile)); + BuildOption buildOption = BuildOption.parse(jsonElement); + // get settings + String settingsPath = buildOption.getSettings(); + if (settingsPath == null) { + //if no settings is specified by user, get the settings.json from program directory + File programDir = new File(YangCompilerRunner.class.getProtectionDomain().getCodeSource().getLocation() + .toURI()); + File programSettings = new File(programDir.getParentFile(), "settings.json"); + if (programSettings.exists()) { + settingsPath = programSettings.getAbsolutePath(); + } + } + if (settingsPath == null) { + //if settings.json is not found in program directory, try to find it from user.home + settingsPath = System.getProperty("user.home") + + File.separator + + ".yang" + + File.separator + + "settings.json"; + } + Settings settings = new Settings(); + File settingsfile = new File(settingsPath); + if (settingsfile.exists()) { + settings = Settings.parse(FileUtil.readFile2String(settingsfile)); + } YangCompiler compiler = new YangCompiler(); - compiler.compile(yangdir, settingsfile, install); + compiler.setBuildOption(buildOption); + compiler.setSettings(settings); + compiler.setInstall(install); + preparePlugins(compiler); + compiler.compile(); } } diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/YangCompilerPlugin.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/YangCompilerPlugin.java new file mode 100644 index 0000000..c4d2366 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/YangCompilerPlugin.java @@ -0,0 +1,65 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin; + +import com.google.gson.JsonElement; + +import java.util.List; + +import org.onap.modeling.yangkit.compiler.YangCompiler; +import org.onap.modeling.yangkit.compiler.YangCompilerException; +import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; + + +public interface YangCompilerPlugin { + /** + * get parameter from build option. + * @param name parameter name + * @param value parameter value + * @return return yang compiler plugin parameter + * @throws YangCompilerException yang compiler exception + */ + default YangCompilerPluginParameter getParameter(String name, JsonElement value) + throws YangCompilerException { + YangCompilerPluginParameter yangCompilerPluginParameter = new YangCompilerPluginParameter() { + @Override + public String getName() { + return name; + } + + @Override + public Object getValue() { + String formatStr = value.getAsString(); + return formatStr; + + } + + }; + return yangCompilerPluginParameter; + } + + /** + * the definition of run method. + * @param schemaContext yang schema context + * @param yangCompiler yang compiler instance + * @param parameters parameters + * @throws YangCompilerException if error occurs, the exception will be thrown. + */ + void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, List parameters) + throws YangCompilerException; + +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/YangCompilerPluginParameter.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/YangCompilerPluginParameter.java new file mode 100644 index 0000000..d76c9fa --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/YangCompilerPluginParameter.java @@ -0,0 +1,35 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin; + +import org.onap.modeling.yangkit.compiler.YangCompilerException; + + +public interface YangCompilerPluginParameter { + /** + * get parameter name. + * @return name + */ + String getName(); + + /** + * get parameter value. + * @return value + * @throws YangCompilerException yang compiler exception + */ + Object getValue() throws YangCompilerException; +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/Tag.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/Tag.java new file mode 100644 index 0000000..59a7996 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/Tag.java @@ -0,0 +1,45 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.stat; + + +public class Tag { + private String name; + private String field; + private String value; + + public Tag(String name, String field) { + this.name = name; + this.field = field; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getName() { + return name; + } + + public String getField() { + return field; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/YangNodeDescription.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/YangNodeDescription.java new file mode 100644 index 0000000..a9c24bd --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/YangNodeDescription.java @@ -0,0 +1,130 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.stat; + +import java.util.ArrayList; +import java.util.List; + +public class YangNodeDescription { + private String path; + private String description; + private String config; + private String schemaType; + private String nodeType; + private String module; + private boolean isActive; + private boolean isDeviated; + + private List tags = new ArrayList<>(); + + public YangNodeDescription() { + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getConfig() { + return config; + } + + public void setConfig(String config) { + this.config = config; + } + + public String getSchemaType() { + return schemaType; + } + + public void setSchemaType(String schemaType) { + this.schemaType = schemaType; + } + + public String getNodeType() { + return nodeType; + } + + public void setNodeType(String nodeType) { + this.nodeType = nodeType; + } + + public String getModule() { + return module; + } + + public void setModule(String module) { + this.module = module; + } + + public boolean isActive() { + return isActive; + } + + public void setActive(boolean active) { + isActive = active; + } + + public boolean isDeviated() { + return isDeviated; + } + + public void setDeviated(boolean deviated) { + isDeviated = deviated; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + /** + * add a tag. + * @param tag customized tag + */ + public void addTag(Tag tag) { + tags.add(tag); + } + + /** + * get tag information according to name. + * @param name tag name + * @return tag + */ + public Tag getTag(String name) { + for (Tag tag : tags) { + if (tag.getName().equals(name)) { + return tag; + } + } + return null; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/YangStatistics.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/YangStatistics.java new file mode 100644 index 0000000..6e38a99 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/stat/YangStatistics.java @@ -0,0 +1,408 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.stat; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.xssf.streaming.SXSSFCell; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; + +import org.onap.modeling.yangkit.compiler.YangCompiler; +import org.onap.modeling.yangkit.compiler.YangCompilerException; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPlugin; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPluginParameter; +import org.yangcentral.yangkit.base.Yang; +import org.yangcentral.yangkit.common.api.FName; +import org.yangcentral.yangkit.common.api.QName; +import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; +import org.yangcentral.yangkit.model.api.stmt.Module; +import org.yangcentral.yangkit.model.api.stmt.SchemaNode; +import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer; +import org.yangcentral.yangkit.model.api.stmt.SubModule; +import org.yangcentral.yangkit.model.api.stmt.TypedDataNode; +import org.yangcentral.yangkit.model.api.stmt.VirtualSchemaNode; +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + + +public class YangStatistics implements YangCompilerPlugin { + private List tags = new ArrayList<>(); + private String output; + + /** + * get node description. + * + * @param schemaNode schema node + * @return node description + */ + public YangNodeDescription getNodeDescription(SchemaNode schemaNode) { + if (schemaNode == null) { + return null; + } + if (schemaNode instanceof VirtualSchemaNode) { + return null; + } + if (schemaNode.getSchemaPath() == null) { + return null; + } + YangNodeDescription nodeDescription = new YangNodeDescription(); + nodeDescription.setPath(schemaNode.getSchemaPath().toString()); + nodeDescription.setDescription( + schemaNode.getDescription() == null ? "" : schemaNode.getDescription().getArgStr()); + nodeDescription.setConfig(schemaNode.isConfig() ? "true" : "false"); + nodeDescription.setSchemaType(schemaNode.getYangKeyword().getLocalName()); + if (schemaNode instanceof TypedDataNode) { + TypedDataNode typedDataNode = (TypedDataNode) schemaNode; + nodeDescription.setNodeType(typedDataNode.getType().getArgStr()); + } + nodeDescription.setModule(schemaNode.getContext().getCurModule().getArgStr()); + nodeDescription.setActive(schemaNode.isActive()); + nodeDescription.setDeviated(schemaNode.isDeviated()); + for (Tag tag : tags) { + String field = tag.getField(); + FName prefixedName = new FName(field); + QName keyword = null; + if (prefixedName.getPrefix() == null) { + keyword = new QName(Yang.NAMESPACE, prefixedName.getLocalName()); + } else { + YangSchemaContext schemaContext = schemaNode.getContext().getSchemaContext(); + List matched = schemaContext.getModule(prefixedName.getPrefix()); + if (matched == null || matched.isEmpty()) { + continue; + } + URI namespace = matched.get(0).getMainModule().getNamespace().getUri(); + keyword = new QName(namespace, prefixedName.getLocalName()); + } + if (tag.getValue() == null || tag.getValue().isEmpty()) { + List statements = schemaNode.getSubStatement(keyword); + if (!statements.isEmpty()) { + String arg = statements.get(0).getArgStr(); + if (arg == null || arg.isEmpty()) { + arg = "true"; + } + Tag nodeTag = new Tag(tag.getName(), tag.getField()); + nodeTag.setValue(arg); + nodeDescription.addTag(nodeTag); + } + } else { + YangStatement statement = schemaNode.getSubStatement(keyword, tag.getValue()); + if (statement != null) { + Tag nodeTag = new Tag(tag.getName(), tag.getField()); + nodeTag.setValue(tag.getValue()); + nodeDescription.addTag(nodeTag); + } + } + } + return nodeDescription; + } + + /** + * get node description for schema node container. + * + * @param schemaNodeContainer schema node container + * @return list of node description. + */ + public List getNodeDescriptions(SchemaNodeContainer schemaNodeContainer) { + if (schemaNodeContainer == null) { + return new ArrayList<>(); + } + List nodeDescriptions = new ArrayList<>(); + if (schemaNodeContainer instanceof SchemaNode) { + SchemaNode schemaNode = (SchemaNode) schemaNodeContainer; + YangNodeDescription nodeDescription = getNodeDescription(schemaNode); + if (nodeDescription != null) { + nodeDescriptions.add(nodeDescription); + } + } + + for (SchemaNode schemaNode : schemaNodeContainer.getSchemaNodeChildren()) { + List modules = schemaNode.getContext().getSchemaContext().getModules(); + Module curModule = schemaNode.getContext().getCurModule().getMainModule(); + if (!modules.contains(curModule)) { + //only include the schema node belongs to modules of schema context + continue; + } + + if (schemaNode instanceof SchemaNodeContainer) { + nodeDescriptions.addAll(getNodeDescriptions((SchemaNodeContainer) schemaNode)); + } else { + YangNodeDescription nodeDescription = getNodeDescription(schemaNode); + if (nodeDescription != null) { + nodeDescriptions.add(nodeDescription); + } + } + } + return nodeDescriptions; + } + + /** + * get yang statistics for yang schema context. + * + * @param schemaContext yang schema context. + * @return list of node description. + */ + public List getYangStatistics(YangSchemaContext schemaContext) { + List nodeDescriptions = new ArrayList<>(); + if (schemaContext == null) { + return nodeDescriptions; + } + for (Module module : schemaContext.getModules()) { + if (module instanceof SubModule) { + continue; + } + nodeDescriptions.addAll(getNodeDescriptions(module)); + } + return nodeDescriptions; + } + + /** + * serialize the yang statistics of schema context to xlsx format. + * + * @param schemaContext yang schema context. + * @return xlsx document + */ + public SXSSFWorkbook serializeXlsx(YangSchemaContext schemaContext) { + SXSSFWorkbook workbook = new SXSSFWorkbook(); + SXSSFSheet summary = workbook.createSheet("summary"); + summary.setDisplayGridlines(true); + summary.setAutobreaks(true); + summary.setColumnWidth(0, 5000); + summary.setColumnWidth(1, 5000); + SXSSFRow sumFirstRow = summary.createRow(0); + SXSSFCell totalModules = sumFirstRow.createCell(0); + totalModules.setCellValue("Total modules:"); + SXSSFCell totalModulesVal = sumFirstRow.createCell(1); + totalModulesVal.setCellValue(schemaContext.getModules().size()); + + SXSSFSheet detail = workbook.createSheet("detail"); + detail.setDisplayGridlines(true); + detail.setAutobreaks(true); + detail.setColumnWidth(0, 20000); + detail.setColumnWidth(1, 5000); + detail.setColumnWidth(2, 20000); + detail.setColumnWidth(3, 5000); + detail.setColumnWidth(4, 5000); + detail.setColumnWidth(5, 5000); + detail.setColumnWidth(6, 5000); + detail.setColumnWidth(7, 5000); + int size = tags.size(); + for (int i = 0; i < size; i++) { + detail.setColumnWidth(8 + i, 5000); + } + + CellStyle style = workbook.createCellStyle(); + style.setBorderBottom(BorderStyle.THIN); + style.setBorderLeft(BorderStyle.THIN); + style.setBorderRight(BorderStyle.THIN); + style.setBorderTop(BorderStyle.THIN); + + CellStyle desStyle = workbook.createCellStyle(); + desStyle.cloneStyleFrom(style); + desStyle.setAlignment(HorizontalAlignment.JUSTIFY); + + detail.setDefaultColumnStyle(0, style); + detail.setDefaultColumnStyle(1, desStyle); + detail.setDefaultColumnStyle(2, style); + detail.setDefaultColumnStyle(3, style); + detail.setDefaultColumnStyle(4, style); + detail.setDefaultColumnStyle(5, style); + detail.setDefaultColumnStyle(6, style); + detail.setDefaultColumnStyle(7, style); + for (int i = 0; i < size; i++) { + detail.setDefaultColumnStyle(8 + i, style); + } + //generate header + SXSSFRow firstRow = detail.createRow(0); + SXSSFCell yangpath = firstRow.createCell(0); + yangpath.setCellValue("Path"); + yangpath.setCellStyle(style); + SXSSFCell active = firstRow.createCell(1); + active.setCellValue("Active"); + active.setCellStyle(style); + SXSSFCell description = firstRow.createCell(2); + description.setCellValue("Description"); + description.setCellStyle(style); + SXSSFCell config = firstRow.createCell(3); + config.setCellValue("Config"); + config.setCellStyle(style); + SXSSFCell schema = firstRow.createCell(4); + schema.setCellValue("schema"); + schema.setCellStyle(style); + SXSSFCell type = firstRow.createCell(5); + type.setCellValue("type"); + type.setCellStyle(style); + SXSSFCell moduleHeader = firstRow.createCell(6); + moduleHeader.setCellValue("module"); + moduleHeader.setCellStyle(style); + SXSSFCell deviated = firstRow.createCell(7); + deviated.setCellValue("deviated"); + deviated.setCellStyle(style); + for (int i = 0; i < size; i++) { + SXSSFCell tagCell = firstRow.createCell(8 + i); + tagCell.setCellValue(tags.get(i).getName()); + tagCell.setCellStyle(style); + } + + List totalPaths = getYangStatistics(schemaContext); + + + if (null != totalPaths) { + int pathSize = totalPaths.size(); + SXSSFRow summarySecRow = summary.createRow(1); + SXSSFCell totalNodes = summarySecRow.createCell(0); + totalNodes.setCellValue("Total nodes:"); + SXSSFCell totalNodesVal = summarySecRow.createCell(1); + totalNodesVal.setCellValue(pathSize); + for (int i = 0; i < pathSize; i++) { + YangNodeDescription path = totalPaths.get(i); + SXSSFRow row = detail.createRow(i + 1); + SXSSFCell pathCell = row.createCell(0); + pathCell.setCellValue(path.getPath()); + pathCell.setCellStyle(style); + SXSSFCell activeCell = row.createCell(1); + activeCell.setCellValue(path.isActive()); + activeCell.setCellStyle(style); + SXSSFCell descriptionCell = row.createCell(2); + String str = path.getDescription(); + if (str.length() >= 32767) { + str = str.substring(0, 32767); + } + descriptionCell.setCellValue(str); + descriptionCell.setCellStyle(desStyle); + + SXSSFCell configCell = row.createCell(3); + configCell.setCellValue(path.getConfig()); + configCell.setCellStyle(style); + + SXSSFCell schemaCell = row.createCell(4); + schemaCell.setCellValue(path.getSchemaType()); + schemaCell.setCellStyle(style); + + SXSSFCell typeCell = row.createCell(5); + typeCell.setCellValue(path.getNodeType()); + typeCell.setCellStyle(style); + + SXSSFCell moduleCell = row.createCell(6); + moduleCell.setCellValue(path.getModule()); + moduleCell.setCellStyle(style); + SXSSFCell deviateCell = row.createCell(7); + deviateCell.setCellValue(path.isDeviated()); + deviateCell.setCellStyle(style); + for (int j = 0; j < size; j++) { + SXSSFCell tagValCell = row.createCell(8 + j); + Tag valueTag = path.getTag(tags.get(j).getName()); + if (valueTag == null) { + tagValCell.setCellValue(""); + } else { + tagValCell.setCellValue(valueTag.getValue()); + } + + tagValCell.setCellStyle(style); + } + } + } + return workbook; + } + + /** + * a yang compiler plugin implementation (run method). + * + * @param schemaContext yang schema context + * @param yangCompiler yang compiler instance + * @param parameters parameters for plugin + * @throws YangCompilerException if error occurs, throw the exception + */ + @Override + public void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, + List parameters) throws YangCompilerException { + + for (YangCompilerPluginParameter parameter : parameters) { + if (parameter.getName().equals("output")) { + output = (String) (parameter.getValue()); + } else { + tags = (List) (parameter.getValue()); + } + } + + SXSSFWorkbook workbook = serializeXlsx(schemaContext); + try { + File out = new File(output); + if (!out.exists()) { + File parent = out.getParentFile(); + if (!parent.exists()) { + parent.mkdirs(); + } + } + workbook.write(new FileOutputStream(out)); + workbook.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + + } + + @Override + public YangCompilerPluginParameter getParameter(String name, JsonElement value) throws YangCompilerException { + if (!name.equals("output") && !name.equals("tag")) { + throw new YangCompilerException("unknown parameter:" + name); + } + YangCompilerPluginParameter yangCompilerPluginParameter = new YangCompilerPluginParameter() { + @Override + public String getName() { + return name; + } + + @Override + public Object getValue() { + if (name.equals("output")) { + return value.getAsString(); + } else { + List tags = new ArrayList<>(); + JsonArray tagArray = value.getAsJsonArray(); + int size = tagArray.size(); + for (int i = 0; i < size; i++) { + JsonObject tagElement = tagArray.get(i).getAsJsonObject(); + String name = tagElement.get("name").getAsString(); + String keyword = tagElement.get("keyword").getAsString(); + Tag tag = new Tag(name, keyword); + if (tagElement.get("value") != null) { + tag.setValue(tagElement.get("value").getAsString()); + } + tags.add(tag); + } + return tags; + } + + } + + }; + return yangCompilerPluginParameter; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/validator/YangValidator.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/validator/YangValidator.java new file mode 100644 index 0000000..5523dda --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/validator/YangValidator.java @@ -0,0 +1,47 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.validator; + +import java.util.List; + +import org.onap.modeling.yangkit.compiler.YangCompiler; +import org.onap.modeling.yangkit.compiler.YangCompilerException; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPlugin; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPluginParameter; +import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; +import org.yangcentral.yangkit.utils.file.FileUtil; + + + +public class YangValidator implements YangCompilerPlugin { + /** + * the implementation of run method. + * @param schemaContext yang schema context. + * @param yangCompiler yang compiler instance. + * @param parameters parameters of plugin. + * @throws YangCompilerException if error occurs, the exception will be thrown. + */ + @Override + public void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, + List parameters) throws YangCompilerException { + YangCompilerPluginParameter parameter = parameters.get(0); + if (!parameter.getName().equals("output")) { + throw new YangCompilerException("unknown parameter:" + parameter.getName()); + } + FileUtil.writeUtf8File((String) parameter.getValue(), schemaContext.getValidateResult().toString()); + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/ModuleInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/ModuleInfo.java new file mode 100644 index 0000000..d9871c0 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/ModuleInfo.java @@ -0,0 +1,117 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.yangpackage; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.net.URI; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + +public class ModuleInfo extends SubComponentInfo { + private URI namespace; + private final List subModules = new ArrayList<>(); + + /** + * constructor. + * @param name module name + * @param revision module revision + */ + public ModuleInfo(String name, String revision) { + super(name, revision); + } + + /** + * constructor. + * @param name module name + */ + public ModuleInfo(String name) { + super(name); + } + + /** + * serialize the revision. + * @return serialized revision + */ + @Override + protected Map.Entry serializeRevision() { + if (this.getRevision() == null) { + return null; + } + return new AbstractMap.SimpleEntry<>("revision", this.getRevision()); + } + + /** + * get namespace. + * @return the uri of namespace + */ + public URI getNamespace() { + return namespace; + } + + /** + * set namespace. + * @param namespace the uri of namespace + */ + public void setNamespace(URI namespace) { + this.namespace = namespace; + } + + /** + * get submodules. + * @return list of submodules. + */ + public List getSubModules() { + return subModules; + } + + /** + * add submodule. + * @param subModuleInfo submodule + */ + public void addSubModule(SubModuleInfo subModuleInfo) { + if (subModules.contains(subModuleInfo)) { + return; + } + subModules.add(subModuleInfo); + } + + /** + * serialize the module information. + * @return json element. + */ + @Override + public JsonElement serialize() { + JsonObject jsonObject = super.serialize().getAsJsonObject(); + if (this.getNamespace() != null) { + jsonObject.addProperty("namespace", this.getNamespace().toString()); + } + if (!this.getSubModules().isEmpty()) { + JsonArray subModules = new JsonArray(); + for (SubModuleInfo subModule : this.getSubModules()) { + subModules.add(subModule.serialize()); + } + jsonObject.add("submodule", subModules); + } + return jsonObject; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/PackageInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/PackageInfo.java new file mode 100644 index 0000000..d61560d --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/PackageInfo.java @@ -0,0 +1,45 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.yangpackage; + +import java.util.AbstractMap; +import java.util.Map; + + +public class PackageInfo extends SubComponentInfo { + /** + * constructor. + * @param name package name + * @param revision package revision. + */ + public PackageInfo(String name, String revision) { + super(name, revision); + } + + /** + * serialize the revision. + * @return serialized revision. + */ + @Override + protected Map.Entry serializeRevision() { + if (this.getRevision() == null) { + return null; + } + Map.Entry revisionEntry = new AbstractMap.SimpleEntry<>("version", this.getRevision()); + return revisionEntry; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/SubComponentInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/SubComponentInfo.java new file mode 100644 index 0000000..fffdcce --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/SubComponentInfo.java @@ -0,0 +1,171 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.yangpackage; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + + +public abstract class SubComponentInfo { + private final String name; + private String revision; + private final List replaceRevisions = new ArrayList<>(); + private List locations; + + /** + * constructor. + * @param name the name of subcomponent. + * @param revision the revision of subcomponent. + */ + public SubComponentInfo(String name, String revision) { + this.name = name; + this.revision = revision; + } + + /** + * constructor. + * @param name the name of subcomponent. + */ + public SubComponentInfo(String name) { + this.name = name; + } + + /** + * get the name of subcomponent. + * @return name. + */ + public String getName() { + return name; + } + + /** + * get the revision of subcomponent. + * @return revision + */ + public String getRevision() { + return revision; + } + + /** + * set the revision of subcomponent. + * @param revision revision + */ + public void setRevision(String revision) { + this.revision = revision; + } + + /** + * get the replaced revisions. + * @return the list of revisions. + */ + public List getReplaceRevisions() { + return replaceRevisions; + } + + /** + * add replace revision. + * @param revision the revision to be replaced. + */ + public void addReplaceRevision(String revision) { + if (replaceRevisions.contains(revision)) { + return; + } + replaceRevisions.add(revision); + } + + /** + * get locations of subcomponent. + * @return list of location uri. + */ + public List getLocations() { + return locations; + } + + /** + * add location. + * @param location location uri. + */ + public void addLocation(URI location) { + if (locations.contains(location)) { + return; + } + locations.add(location); + } + + /** + * equals method. + * @param obj other object. + * @return true or false. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof SubComponentInfo)) { + return false; + } + SubComponentInfo that = (SubComponentInfo) obj; + return getName().equals(that.getName()) && getRevision().equals(that.getRevision()); + } + + @Override + public int hashCode() { + return Objects.hash(getName(), getRevision()); + } + + /** + * the abstract method of serialize the revision. + * @return serialized revision. + */ + protected abstract Map.Entry serializeRevision(); + + /** + * serialize the subcomponent to json element. + * @return json element. + */ + public JsonElement serialize() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("name", this.getName()); + if (this.getRevision() != null) { + Map.Entry revisionEntry = serializeRevision(); + jsonObject.addProperty(revisionEntry.getKey(), revisionEntry.getValue()); + } + if (!this.getReplaceRevisions().isEmpty()) { + JsonArray replaceRevisions = new JsonArray(); + for (String replaceRevision : this.getReplaceRevisions()) { + replaceRevisions.add(replaceRevision); + } + jsonObject.add("replaces-version", replaceRevisions); + } + if (!this.getLocations().isEmpty()) { + JsonArray locations = new JsonArray(); + for (URI location : this.getLocations()) { + locations.add(location.toString()); + } + jsonObject.add("location", locations); + } + return jsonObject; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/SubModuleInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/SubModuleInfo.java new file mode 100644 index 0000000..0c5848b --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/SubModuleInfo.java @@ -0,0 +1,125 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.yangpackage; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + + +public class SubModuleInfo { + private final String name; + private final String revision; + private List locations = new ArrayList<>(); + + /** + * constructor. + * @param name submodule name + * @param revision submodule revision + */ + public SubModuleInfo(String name, String revision) { + this.name = name; + this.revision = revision; + } + + /** + * get the submodule name. + * @return name + */ + public String getName() { + return name; + } + + /** + * get the revision of submodule. + * @return revision + */ + public String getRevision() { + return revision; + } + + /** + * get locations of submodule. + * @return list of location. + */ + public List getLocations() { + return locations; + } + + /** + * set the locations. + * @param locations list of location. + */ + public void setLocations(List locations) { + this.locations = locations; + } + + /** + * add a location. + * @param location location uri + */ + public void addLocation(URI location) { + if (locations.contains(location)) { + return; + } + locations.add(location); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof SubModuleInfo)) { + return false; + } + SubModuleInfo that = (SubModuleInfo) obj; + return getName().equals(that.getName()) && getRevision().equals(that.getRevision()); + } + + @Override + public int hashCode() { + return Objects.hash(getName(), getRevision()); + } + + /** + * serialize submodule to json. + * @return json element. + */ + public JsonElement serialize() { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("name", this.getName()); + if (this.getRevision() != null) { + jsonObject.addProperty("revision", this.getRevision()); + } + + if (!this.getLocations().isEmpty()) { + JsonArray locations = new JsonArray(); + for (URI location : this.getLocations()) { + locations.add(location.toString()); + } + jsonObject.add("location", locations); + } + return jsonObject; + + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackage.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackage.java new file mode 100644 index 0000000..a1997de --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackage.java @@ -0,0 +1,395 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.yangpackage; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.util.ArrayList; +import java.util.List; + + +public class YangPackage { + private final String name; + private final String revision; + private String timestamp; + private String organization; + private String contact; + private String description; + private String reference; + private boolean complete = true; + private boolean local; + private List tags = new ArrayList<>(); + private List mandatoryFeatures = new ArrayList<>(); + private List includePackages = new ArrayList<>(); + private List modules = new ArrayList<>(); + private List importOnlyModules = new ArrayList<>(); + + /** + * constructor. + * @param name package name + * @param revision package revision + */ + public YangPackage(String name, String revision) { + this.name = name; + this.revision = revision; + } + + /** + * get the package name. + * @return name + */ + public String getName() { + return name; + } + + /** + * get the package revision. + * @return revision + */ + public String getRevision() { + return revision; + } + + /** + * get the timestamp. + * @return timestamp. + */ + public String getTimestamp() { + return timestamp; + } + + /** + * set the timestamp. + * @param timestamp timestamp + */ + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + /** + * get organization. + * @return organization. + */ + public String getOrganization() { + return organization; + } + + /** + * set organization. + * @param organization organization + */ + public void setOrganization(String organization) { + this.organization = organization; + } + + /** + * get contact information. + * @return contact. + */ + public String getContact() { + return contact; + } + + /** + * set the contact. + * @param contact contact. + */ + public void setContact(String contact) { + this.contact = contact; + } + + /** + * get description. + * @return description. + */ + public String getDescription() { + return description; + } + + /** + * set description. + * @param description description. + */ + public void setDescription(String description) { + this.description = description; + } + + /** + * get reference. + * @return reference. + */ + public String getReference() { + return reference; + } + + /** + * set reference. + * @param reference reference. + */ + public void setReference(String reference) { + this.reference = reference; + } + + /** + * whether the package is complete. + * @return true or false. + */ + public boolean isComplete() { + return complete; + } + + /** + * set whether the package is complete. + * @param complete true or false. + */ + public void setComplete(boolean complete) { + this.complete = complete; + } + + /** + * whether the package is local. + * @return true or false + */ + public boolean isLocal() { + return local; + } + + /** + * set whether the package is local. + * @param local true or false + */ + public void setLocal(boolean local) { + this.local = local; + } + + /** + * get the tags of package. + * @return the list of tags. + */ + public List getTags() { + return tags; + } + + /** + * set the tags of package. + * @param tags the list of tags. + */ + public void setTags(List tags) { + this.tags = tags; + } + + /** + * add a tag to package. + * @param tag tag + */ + public void addTag(String tag) { + if (tags.contains(tag)) { + return; + } + tags.add(tag); + } + + /** + * get mandatory features of package. + * @return list of features. + */ + public List getMandatoryFeatures() { + return mandatoryFeatures; + } + + /** + * set mandatory features. + * @param mandatoryFeatures list of mandatory features. + */ + public void setMandatoryFeatures(List mandatoryFeatures) { + this.mandatoryFeatures = mandatoryFeatures; + } + + /** + * add mandatory feature. + * @param feature feature + */ + public void addMandatoryFeature(String feature) { + if (mandatoryFeatures.contains(feature)) { + return; + } + mandatoryFeatures.add(feature); + } + + /** + * get include packages. + * @return list of included packages. + */ + public List getIncludePackages() { + return includePackages; + } + + /** + * set the include packages. + * @param includePackages the list of include packages. + */ + public void setIncludePackages(List includePackages) { + this.includePackages = includePackages; + } + + /** + * add a include package. + * @param packageInfo package + */ + public void addIncludePackage(PackageInfo packageInfo) { + if (includePackages.contains(packageInfo)) { + return; + } + includePackages.add(packageInfo); + } + + /** + * get the modules of package. + * @return list of modules. + */ + public List getModules() { + return modules; + } + + /** + * set the modules of package. + * @param modules list of modules + */ + public void setModules(List modules) { + this.modules = modules; + } + + /** + * add a module to package. + * @param module module + */ + public void addModule(ModuleInfo module) { + if (this.modules.contains(module)) { + return; + } + modules.add(module); + } + + /** + * get import-only modules. + * @return list of modules. + */ + public List getImportOnlyModules() { + return importOnlyModules; + } + + /** + * add a import-only module. + * @param module module + */ + public void addImportOnlyModule(ModuleInfo module) { + if (importOnlyModules.contains(module)) { + return; + } + importOnlyModules.add(module); + } + + /** + * set import-only modules. + * @param importOnlyModules list of modules + */ + public void setImportOnlyModules(List importOnlyModules) { + this.importOnlyModules = importOnlyModules; + } + + /** + * serialize yang package to json. + * @return json element + */ + public JsonElement serialize() { + JsonObject document = new JsonObject(); + JsonObject instanceDataset = new JsonObject(); + document.add("ietf-yang-instance-data:instance-data-set", instanceDataset); + instanceDataset.addProperty("name", this.getName()); + JsonObject contentSchema = new JsonObject(); + instanceDataset.add("content-schema", contentSchema); + JsonArray moduleArray = new JsonArray(); + moduleArray.add("ietf-yang-package-instance@2020-01-21"); + contentSchema.add("module", moduleArray); + JsonObject contentData = new JsonObject(); + instanceDataset.add("content-data", contentData); + JsonObject yangPackage = new JsonObject(); + contentData.add("ietf-yang-package-instance:yang-package", yangPackage); + yangPackage.addProperty("name", this.getName()); + yangPackage.addProperty("version", this.getRevision()); + // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + // String dateTime = sdf.format(new Date(System.currentTimeMillis())); + if (this.getTimestamp() != null) { + yangPackage.addProperty("timestamp", this.getTimestamp()); + } + + if (this.getOrganization() != null) { + yangPackage.addProperty("organization", this.getOrganization()); + } + if (this.getContact() != null) { + yangPackage.addProperty("contact", this.getContact()); + } + if (this.getDescription() != null) { + yangPackage.addProperty("description", this.getDescription()); + } + if (this.getReference() != null) { + yangPackage.addProperty("reference", this.getReference()); + } + yangPackage.addProperty("complete", this.isComplete()); + yangPackage.addProperty("local", this.isLocal()); + + if (!this.getTags().isEmpty()) { + JsonArray tags = new JsonArray(); + for (String tag : this.getTags()) { + tags.add(tag); + } + yangPackage.add("tag", tags); + } + if (!this.getMandatoryFeatures().isEmpty()) { + JsonArray mandatoryFeatures = new JsonArray(); + for (String mandatoryFeature : this.getMandatoryFeatures()) { + mandatoryFeatures.add(mandatoryFeature); + } + yangPackage.add("mandatory-feature", mandatoryFeatures); + } + if (!this.getIncludePackages().isEmpty()) { + JsonArray includePackages = new JsonArray(); + for (PackageInfo packageInfo : this.getIncludePackages()) { + includePackages.add(packageInfo.serialize()); + } + yangPackage.add("included-package", includePackages); + } + if (!this.getModules().isEmpty()) { + JsonArray modules = new JsonArray(); + for (ModuleInfo moduleInfo : this.getModules()) { + modules.add(moduleInfo.serialize()); + } + yangPackage.add("module", modules); + } + + if (!this.getImportOnlyModules().isEmpty()) { + JsonArray importOnlyModules = new JsonArray(); + for (ModuleInfo importOnlyModule : this.getImportOnlyModules()) { + importOnlyModules.add(importOnlyModule.serialize()); + } + yangPackage.add("import-only-module", importOnlyModules); + } + return yangPackage; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackageGenerator.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackageGenerator.java new file mode 100644 index 0000000..f300d46 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackageGenerator.java @@ -0,0 +1,154 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.yangpackage; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FilenameFilter; +import java.util.List; + + +import org.onap.modeling.yangkit.compiler.YangCompiler; +import org.onap.modeling.yangkit.compiler.YangCompilerException; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPlugin; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPluginParameter; +import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; +import org.yangcentral.yangkit.model.api.stmt.Include; +import org.yangcentral.yangkit.model.api.stmt.MainModule; +import org.yangcentral.yangkit.model.api.stmt.Module; +import org.yangcentral.yangkit.model.api.stmt.SubModule; + + +public class YangPackageGenerator implements YangCompilerPlugin { + @Override + public YangCompilerPluginParameter getParameter(String name, JsonElement value) + throws YangCompilerException { + if (!name.equals("complete") && !name.equals("meta") && !name.equals("output")) { + throw new YangCompilerException("unrecognized parameter:" + name); + } + if (name.equals("complete")) { + YangCompilerPluginParameter pluginParameter = new YangCompilerPluginParameter() { + @Override + public String getName() { + return name; + } + + @Override + public Object getValue() throws YangCompilerException { + return value.getAsBoolean(); + } + }; + return pluginParameter; + } + return YangCompilerPlugin.super.getParameter(name, value); + } + + @Override + public void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, + List parameters) + throws YangCompilerException { + String output = null; + for (YangCompilerPluginParameter parameter : parameters) { + if (parameter.getName().equals("output")) { + output = (String) parameter.getValue(); + } else { + throw new YangCompilerException("unknown parameter:" + parameter.getName()); + } + } + if (output == null) { + throw new YangCompilerException("missing mandatory parameter:output"); + } + + + //search package_meta.json + File packageMetaFile = new File("package_meta.json"); + if (!packageMetaFile.exists()) { + throw new YangCompilerException("missing package_meta.json."); + } + + try { + //parse yang package meta information + JsonElement element = JsonParser.parseReader(new FileReader(packageMetaFile)); + YangPackageMeta yangPackageMeta = new YangPackageMeta(); + yangPackageMeta.deserialize(element); + //set meta information for yang package + YangPackage yangPackage = new YangPackage(yangPackageMeta.getName(), yangPackageMeta.getRevision()); + yangPackage.setOrganization(yangPackageMeta.getOrganization()); + yangPackage.setContact(yangPackageMeta.getContact()); + yangPackage.setDescription(yangPackageMeta.getDescription()); + yangPackage.setReference(yangPackageMeta.getReference()); + yangPackage.setLocal(yangPackageMeta.isLocal()); + yangPackage.setTags(yangPackageMeta.getTags()); + yangPackage.setMandatoryFeatures(yangPackageMeta.getMandatoryFeatures()); + yangPackage.setIncludePackages(yangPackageMeta.getIncludePackages()); + if (schemaContext.getImportOnlyModules().isEmpty()) { + yangPackage.setComplete(true); + } + FilenameFilter packageMetaFilter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + if (name.equals("package_meta.json")) { + return true; + } + return false; + } + }; + + List modules = schemaContext.getModules(); + for (Module module : modules) { + if (module instanceof MainModule) { + ModuleInfo moduleInfo = new ModuleInfo(module.getArgStr(), module.getCurRevisionDate().get()); + moduleInfo.setNamespace(((MainModule) module).getNamespace().getUri()); + if (!module.getIncludes().isEmpty()) { + for (Include include : module.getIncludes()) { + SubModule subModule = include.getInclude().get(); + SubModuleInfo subModuleInfo = + new SubModuleInfo(subModule.getArgStr(), subModule.getCurRevisionDate().get()); + moduleInfo.addSubModule(subModuleInfo); + } + } + yangPackage.addModule(moduleInfo); + } + } + for (Module importOnlyModule : schemaContext.getImportOnlyModules()) { + if (!(importOnlyModule instanceof MainModule)) { + continue; + } + ModuleInfo moduleInfo = + new ModuleInfo(importOnlyModule.getArgStr(), importOnlyModule.getCurRevisionDate().get()); + moduleInfo.setNamespace(((MainModule) importOnlyModule).getNamespace().getUri()); + if (!importOnlyModule.getIncludes().isEmpty()) { + for (Include include : importOnlyModule.getIncludes()) { + SubModule subModule = include.getInclude().get(); + SubModuleInfo subModuleInfo = + new SubModuleInfo(subModule.getArgStr(), subModule.getCurRevisionDate().get()); + moduleInfo.addSubModule(subModuleInfo); + } + } + yangPackage.addImportOnlyModule(moduleInfo); + } + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackageMeta.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackageMeta.java new file mode 100644 index 0000000..92946cf --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangpackage/YangPackageMeta.java @@ -0,0 +1,187 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.yangpackage; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import java.util.ArrayList; +import java.util.List; + + +public class YangPackageMeta { + private String name; + private String revision; + private String organization; + private String contact; + private String description; + private String reference; + private boolean local; + private final List tags = new ArrayList<>(); + private final List mandatoryFeatures = new ArrayList<>(); + private final List includePackages = new ArrayList<>(); + + /** + * get the package name. + * @return name + */ + public String getName() { + return name; + } + + /** + * get revision of package. + * @return revision + */ + public String getRevision() { + return revision; + } + + /** + * get organization. + * @return organization. + */ + public String getOrganization() { + return organization; + } + + /** + * get contact. + * @return contact. + */ + public String getContact() { + return contact; + } + + /** + * get description. + * @return description. + */ + public String getDescription() { + return description; + } + + /** + * get reference. + * @return reference. + */ + public String getReference() { + return reference; + } + + /** + * whether the package is local. + * @return true or false + */ + public boolean isLocal() { + return local; + } + + /** + * get tags of package. + * @return list of tags. + */ + public List getTags() { + return tags; + } + + /** + * get mandatory features. + * @return list of features/ + */ + public List getMandatoryFeatures() { + return mandatoryFeatures; + } + + /** + * get include packages. + * @return list of packages. + */ + public List getIncludePackages() { + return includePackages; + } + + /** + * deserialized package meta from json. + * @param metaDoc json element + */ + public void deserialize(JsonElement metaDoc) { + JsonObject jsonObject = metaDoc.getAsJsonObject(); + JsonElement nameElement = jsonObject.get("name"); + if (nameElement != null) { + this.name = nameElement.getAsString(); + } + JsonElement versionElement = jsonObject.get("version"); + if (versionElement != null) { + this.revision = versionElement.getAsString(); + } + JsonElement organizationElement = jsonObject.get("organization"); + if (organizationElement != null) { + this.organization = organizationElement.getAsString(); + } + JsonElement contactElement = jsonObject.get("contact"); + if (contactElement != null) { + this.contact = contactElement.getAsString(); + } + JsonElement descElement = jsonObject.get("description"); + if (descElement != null) { + this.description = descElement.getAsString(); + } + JsonElement referElement = jsonObject.get("reference"); + if (referElement != null) { + this.reference = referElement.getAsString(); + } + + JsonElement localElement = jsonObject.get("local"); + if (localElement != null) { + this.local = referElement.getAsBoolean(); + } + JsonElement tagElement = jsonObject.get("tag"); + if (tagElement != null) { + JsonArray tagArray = tagElement.getAsJsonArray(); + int size = tagArray.size(); + for (int i = 0; i < size; i++) { + JsonElement tagIns = tagArray.get(i); + this.tags.add(tagIns.getAsString()); + } + } + + JsonElement mandatoryFeaturesElement = jsonObject.get("mandatory-feature"); + if (mandatoryFeaturesElement != null) { + JsonArray mandatoryFeaturesArray = mandatoryFeaturesElement.getAsJsonArray(); + int size = mandatoryFeaturesArray.size(); + for (int i = 0; i < size; i++) { + JsonElement featureIns = mandatoryFeaturesArray.get(i); + this.mandatoryFeatures.add(featureIns.getAsString()); + } + } + JsonElement includePackagesElement = jsonObject.get("include-package"); + if (includePackagesElement != null) { + JsonArray includePackageArray = includePackagesElement.getAsJsonArray(); + int size = includePackageArray.size(); + for (int i = 0; i < size; i++) { + JsonElement includePackageIns = includePackageArray.get(i); + JsonObject includePackageObj = includePackageIns.getAsJsonObject(); + PackageInfo packageInfo = new PackageInfo(includePackageObj.get("name").getAsString(), + includePackageObj.get("version").getAsString()); + this.includePackages.add(packageInfo); + } + } + + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangtree/GroupingSchemaNodeContainer.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangtree/GroupingSchemaNodeContainer.java new file mode 100644 index 0000000..2b8ba23 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangtree/GroupingSchemaNodeContainer.java @@ -0,0 +1,151 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.yangtree; + +import java.util.ArrayList; +import java.util.List; + +import org.yangcentral.yangkit.common.api.QName; +import org.yangcentral.yangkit.common.api.validate.ValidatorResult; +import org.yangcentral.yangkit.model.api.stmt.Action; +import org.yangcentral.yangkit.model.api.stmt.ActionContainer; +import org.yangcentral.yangkit.model.api.stmt.Augment; +import org.yangcentral.yangkit.model.api.stmt.DataDefContainer; +import org.yangcentral.yangkit.model.api.stmt.DataDefinition; +import org.yangcentral.yangkit.model.api.stmt.DataNode; +import org.yangcentral.yangkit.model.api.stmt.Grouping; +import org.yangcentral.yangkit.model.api.stmt.GroupingDefContainer; +import org.yangcentral.yangkit.model.api.stmt.Notification; +import org.yangcentral.yangkit.model.api.stmt.NotificationContainer; +import org.yangcentral.yangkit.model.api.stmt.SchemaNode; +import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer; +import org.yangcentral.yangkit.model.api.stmt.Uses; +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + + +public class GroupingSchemaNodeContainer implements SchemaNodeContainer, GroupingDefContainer { + + private final YangStatement container; + + /** + * constructor. + * @param container schema node container + */ + public GroupingSchemaNodeContainer(YangStatement container) { + this.container = container; + } + + @Override + public List getGroupings() { + List groupings = new ArrayList<>(); + if (container instanceof GroupingDefContainer) { + groupings.addAll(((GroupingDefContainer) container).getGroupings()); + } + return groupings; + } + + @Override + public Grouping getGrouping(String name) { + return null; + } + + @Override + public List getSchemaNodeChildren() { + List schemaNodes = new ArrayList<>(); + if (container instanceof DataDefContainer) { + DataDefContainer dataDefContainer = (DataDefContainer) container; + for (DataDefinition dataDefinition : dataDefContainer.getDataDefChildren()) { + schemaNodes.add(dataDefinition); + } + } + + if (container instanceof ActionContainer) { + ActionContainer actionContainer = (ActionContainer) container; + for (Action action : actionContainer.getActions()) { + schemaNodes.add(action); + } + } + + if (container instanceof NotificationContainer) { + for (Notification notification : ((NotificationContainer) container).getNotifications()) { + schemaNodes.add(notification); + } + } + if (container instanceof Uses) { + for (Augment augment : ((Uses) container).getAugments()) { + schemaNodes.add(augment); + } + } + + return schemaNodes; + } + + @Override + public ValidatorResult addSchemaNodeChild(SchemaNode schemaNode) { + return null; + } + + @Override + public ValidatorResult addSchemaNodeChildren(List schemaNodes) { + return null; + } + + @Override + public SchemaNode getSchemaNodeChild(QName identifier) { + return null; + } + + @Override + public DataNode getDataNodeChild(QName identifier) { + return null; + } + + @Override + public List getDataNodeChildren() { + return null; + } + + @Override + public List getTreeNodeChildren() { + return null; + } + + @Override + public SchemaNode getTreeNodeChild(QName identifier) { + return null; + } + + @Override + public List getEffectiveSchemaNodeChildren(boolean ignoreNamespace) { + return null; + } + + @Override + public void removeSchemaNodeChild(QName identifier) { + + } + + @Override + public void removeSchemaNodeChild(SchemaNode schemaNode) { + + } + + @Override + public SchemaNode getMandatoryDescendant() { + return null; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangtree/YangTreeGenerator.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangtree/YangTreeGenerator.java new file mode 100644 index 0000000..b5b5643 --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/plugin/yangtree/YangTreeGenerator.java @@ -0,0 +1,655 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.plugin.yangtree; + +import com.google.gson.JsonElement; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import org.onap.modeling.yangkit.compiler.YangCompiler; +import org.onap.modeling.yangkit.compiler.YangCompilerException; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPlugin; +import org.onap.modeling.yangkit.compiler.plugin.YangCompilerPluginParameter; +import org.yangcentral.yangkit.common.api.QName; +import org.yangcentral.yangkit.model.api.restriction.LeafRef; +import org.yangcentral.yangkit.model.api.schema.SchemaTreeType; +import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; + +import org.yangcentral.yangkit.model.api.stmt.Action; +import org.yangcentral.yangkit.model.api.stmt.Anydata; +import org.yangcentral.yangkit.model.api.stmt.Anyxml; +import org.yangcentral.yangkit.model.api.stmt.Augment; +import org.yangcentral.yangkit.model.api.stmt.Case; +import org.yangcentral.yangkit.model.api.stmt.Choice; +import org.yangcentral.yangkit.model.api.stmt.Container; +import org.yangcentral.yangkit.model.api.stmt.DataDefinition; +import org.yangcentral.yangkit.model.api.stmt.Entity; +import org.yangcentral.yangkit.model.api.stmt.Grouping; +import org.yangcentral.yangkit.model.api.stmt.GroupingDefContainer; +import org.yangcentral.yangkit.model.api.stmt.IfFeature; +import org.yangcentral.yangkit.model.api.stmt.IfFeatureSupport; +import org.yangcentral.yangkit.model.api.stmt.Leaf; +import org.yangcentral.yangkit.model.api.stmt.MainModule; +import org.yangcentral.yangkit.model.api.stmt.Module; +import org.yangcentral.yangkit.model.api.stmt.MultiInstancesDataNode; +import org.yangcentral.yangkit.model.api.stmt.Notification; +import org.yangcentral.yangkit.model.api.stmt.Rpc; +import org.yangcentral.yangkit.model.api.stmt.SchemaDataNode; +import org.yangcentral.yangkit.model.api.stmt.SchemaNode; +import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer; +import org.yangcentral.yangkit.model.api.stmt.Status; +import org.yangcentral.yangkit.model.api.stmt.TypedDataNode; +import org.yangcentral.yangkit.model.api.stmt.Uses; +import org.yangcentral.yangkit.model.api.stmt.YangList; +import org.yangcentral.yangkit.model.api.stmt.YangStatement; +import org.yangcentral.yangkit.model.api.stmt.YangUnknown; +import org.yangcentral.yangkit.model.api.stmt.ext.AugmentStructure; +import org.yangcentral.yangkit.model.api.stmt.ext.YangData; +import org.yangcentral.yangkit.model.api.stmt.ext.YangDataStructure; +import org.yangcentral.yangkit.utils.file.FileUtil; + + +public class YangTreeGenerator implements YangCompilerPlugin { + private int lineLength = 72; + private boolean expandGrouping = true; + private String output; + private static final String SPACE = " "; + private static final String TWO_SPACES = " "; + private static final String OFFSET = " "; + private static final String VERTICAL_OFFSET = "| "; + + /** + * build yang tree from module. + * @param module module + * @return yang tree string + */ + public String buildYangTree(Module module) { + StringBuilder sb = new StringBuilder(); + if (module instanceof MainModule) { + sb.append("module:"); + } else { + sb.append("submodule:"); + } + sb.append(SPACE); + sb.append(module.getArgStr()); + sb.append("\n"); + //data nodes + List dataDefs = module.getDataDefChildren(); + + //augments + List augments = module.getAugments(); + + + List yangDataList = module.getUnknowns( + new QName("urn:ietf:params:xml:ns:yang:ietf-restconf", "yang-data")); + + // yang structure extension + List yangStructureList = module.getUnknowns(YangDataStructure.YANG_KEYWORD); + + // augment structure extension + List augmentStructureList = module.getUnknowns(AugmentStructure.YANG_KEYWORD); + + if (!module.getGroupings().isEmpty() + && (!expandGrouping + || (module.getDataDefChildren().isEmpty() + && module.getRpcs().isEmpty() + && module.getNotifications().isEmpty() + && module.getAugments().isEmpty() + && yangDataList.isEmpty() + && yangStructureList.isEmpty() + && augmentStructureList.isEmpty()))) { + sb.append(buildGroupingContainer(module, TWO_SPACES)); + } + //data nodes + if (!dataDefs.isEmpty()) { + int size = dataDefs.size(); + boolean last = false; + for (int i = 0; i < size; i++) { + if (i == (size - 1)) { + last = true; + } + DataDefinition dataDefinition = dataDefs.get(i); + sb.append(buildYangTree(dataDefinition, last, TWO_SPACES, !expandGrouping)); + } + } + //augments + if (!augments.isEmpty()) { + for (Augment augment : augments) { + sb.append(buildAugmentRepresentation(augment, TWO_SPACES)); + sb.append(buildChildren(augment, TWO_SPACES + TWO_SPACES, !expandGrouping)); + } + } + //rpcs + List rpcs = module.getRpcs(); + if (!rpcs.isEmpty()) { + sb.append(TWO_SPACES); + sb.append("rpcs:\n"); + int size = rpcs.size(); + boolean last = false; + for (int i = 0; i < size; i++) { + if (i == (size - 1)) { + last = true; + } + Rpc rpc = rpcs.get(i); + sb.append(buildYangTree(rpc, last, TWO_SPACES + TWO_SPACES, !expandGrouping)); + } + } + //notifications + List notifications = module.getNotifications(); + if (!notifications.isEmpty()) { + sb.append(TWO_SPACES); + sb.append("notifications:\n"); + int size = notifications.size(); + boolean last = false; + for (int i = 0; i < size; i++) { + if (i == (size - 1)) { + last = true; + } + Notification notification = notifications.get(i); + sb.append(buildYangTree(notification, last, TWO_SPACES + TWO_SPACES, !expandGrouping)); + } + } + //yang data + if (!yangDataList.isEmpty()) { + for (YangUnknown unknown : yangDataList) { + YangData yangData = (YangData) unknown; + sb.append(TWO_SPACES); + sb.append("yang-data"); + sb.append(" "); + sb.append(yangData.getArgStr()); + sb.append(":\n"); + sb.append(buildChildren(yangData, TWO_SPACES + TWO_SPACES, !expandGrouping)); + } + } + //structures + if (!yangStructureList.isEmpty()) { + for (YangUnknown unknown : yangStructureList) { + YangDataStructure structure = (YangDataStructure) unknown; + sb.append(TWO_SPACES); + sb.append("structure"); + sb.append(" "); + sb.append(structure.getArgStr()); + sb.append(":\n"); + if (!expandGrouping) { + sb.append(buildGroupingContainer(structure, TWO_SPACES + TWO_SPACES)); + } + sb.append(buildChildren(structure, TWO_SPACES + TWO_SPACES, !expandGrouping)); + + } + } + //augment-structures + if (!augmentStructureList.isEmpty()) { + for (YangUnknown unknown : augmentStructureList) { + AugmentStructure augmentStructure = (AugmentStructure) unknown; + sb.append(TWO_SPACES); + sb.append("augment-structure"); + sb.append(" "); + sb.append(augmentStructure.getArgStr()); + sb.append(":\n"); + sb.append(buildChildren(augmentStructure, TWO_SPACES + TWO_SPACES, !expandGrouping)); + } + } + + return sb.toString(); + } + + private String buildYangTree(SchemaNode schemaNode, boolean last, String offSet, boolean grouping) { + StringBuilder sb = new StringBuilder(); + if (!grouping && (schemaNode instanceof Uses)) { + Uses uses = (Uses) schemaNode; + List schemaNodes = uses.getSchemaNodeChildren(); + for (int i = 0; i < schemaNodes.size(); i++) { + SchemaNode exSchemaNode = schemaNodes.get(i); + boolean subLast = last; + if (i != (schemaNodes.size() - 1)) { + subLast = false; + } + sb.append(buildYangTree(exSchemaNode, subLast, offSet, grouping)); + } + return sb.toString(); + } + if (schemaNode instanceof Augment) { + sb.append(buildAugmentRepresentation((Augment) schemaNode, offSet)); + } else { + sb.append(buildNodeRepresentation(schemaNode, offSet)); + } + if ((schemaNode instanceof GroupingDefContainer) && grouping) { + sb.append(buildGroupingContainer((GroupingDefContainer) schemaNode, offSet + TWO_SPACES)); + } + if (schemaNode instanceof SchemaNodeContainer) { + String childOffSet = offSet; + if (schemaNode instanceof Augment) { + childOffSet = childOffSet.concat(TWO_SPACES); + } else { + if (last) { + childOffSet = childOffSet.concat(OFFSET); + } else { + childOffSet = childOffSet.concat(VERTICAL_OFFSET); + } + } + + SchemaNodeContainer schemaNodeContainer; + if (!grouping) { + schemaNodeContainer = (SchemaNodeContainer) schemaNode; + } else { + schemaNodeContainer = new GroupingSchemaNodeContainer(schemaNode); + } + + sb.append(buildChildren(schemaNodeContainer, childOffSet, grouping)); + } + + return sb.toString(); + } + + private String buildGroupingContainer(GroupingDefContainer groupingDefContainer, String offSet) { + StringBuilder sb = new StringBuilder(); + //sb.append(offSet); + List groupings = groupingDefContainer.getGroupings(); + int size = groupings.size(); + for (int i = 0; i < size; i++) { + boolean last = false; + if (i == (size - 1)) { + last = true; + } + Grouping grouping = groupings.get(i); + sb.append(buildGrouping(grouping, last, offSet)); + } + return sb.toString(); + } + + private List getRealSchemaChildren(SchemaNodeContainer schemaNodeContainer, boolean grouping) { + List realSchemaNodeChildren = new ArrayList<>(); + + for (SchemaNode schemaChild : schemaNodeContainer.getSchemaNodeChildren()) { + if (schemaChild instanceof Augment) { + Augment augment = (Augment) schemaChild; + if (schemaNodeContainer instanceof SchemaNode) { + SchemaNode schemaNodeParent = (SchemaNode) schemaNodeContainer; + if (augment.getContext().getNamespace() != null && !augment.getContext().getNamespace() + .equals(schemaNodeParent.getContext().getNamespace())) { + continue; + } + } + if (!grouping) { + realSchemaNodeChildren.addAll(getRealSchemaChildren(augment, grouping)); + continue; + } + } + realSchemaNodeChildren.add(schemaChild); + } + return realSchemaNodeChildren; + } + + private String buildChildren(SchemaNodeContainer schemaNodeContainer, String offSet, boolean grouping) { + StringBuilder sb = new StringBuilder(); + List schemaNodeChildren = schemaNodeContainer.getSchemaNodeChildren(); + List realSchemaNodeChildren = getRealSchemaChildren(schemaNodeContainer, grouping); + + int size = realSchemaNodeChildren.size(); + for (int i = 0; i < size; i++) { + SchemaNode realSchemaNode = realSchemaNodeChildren.get(i); + boolean subLast = false; + if (i == (size - 1)) { + subLast = true; + } + sb.append(buildYangTree(realSchemaNode, subLast, offSet, grouping)); + + } + return sb.toString(); + } + + private String buildGrouping(Grouping grouping, boolean last, String offset) { + StringBuilder sb = new StringBuilder(); + sb.append(offset); + sb.append("grouping "); + sb.append(grouping.getArgStr()); + sb.append(":\n"); + GroupingSchemaNodeContainer groupingSchemaNodeContainer = new GroupingSchemaNodeContainer(grouping); + sb.append(buildGroupingContainer(grouping, offset + TWO_SPACES)); + sb.append(buildChildren(groupingSchemaNodeContainer, offset + TWO_SPACES, true)); + return sb.toString(); + } + + + + private String getStatus(YangStatement yangStatement) { + if (yangStatement instanceof Entity) { + Status status = ((Entity) yangStatement).getEffectiveStatus(); + switch (status) { + case CURRENT: { + return "+"; + } + case DEPRECATED: { + return "x"; + } + case OBSOLETE: { + return "o"; + } + default: + throw new IllegalStateException("Unexpected value: " + status); + } + } + return ""; + } + + private String getFlags(YangStatement yangStatement) { + String flags = ""; + if (yangStatement instanceof SchemaNode) { + SchemaNode schemaNode = (SchemaNode) yangStatement; + if (schemaNode instanceof Uses) { + flags = "-u"; + } else if ((schemaNode instanceof Rpc) || (schemaNode instanceof Action)) { + flags = "-x"; + } else if (schemaNode instanceof Notification) { + flags = "-n"; + } else if (schemaNode instanceof Case) { + flags = ""; + } else if (schemaNode.isConfig()) { + flags = "rw"; + } else { + flags = "ro"; + if (schemaNode.getSchemaTreeType() == SchemaTreeType.INPUTTREE) { + flags = "-w"; + } + } + + if (!schemaNode.getSubStatement(new QName("urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount", + "mount-point")).isEmpty()) { + flags = "mp"; + } + } else if (yangStatement instanceof Grouping) { + flags = "rw"; + } + + return flags; + } + + private String getNodeName(YangStatement yangStatement) { + if (yangStatement instanceof Case) { + return ":(" + yangStatement.getArgStr() + ")"; + } else if (yangStatement instanceof Choice) { + return " (" + yangStatement.getArgStr() + ")"; + } else { + return " " + yangStatement.getArgStr(); + } + } + + private boolean isMandatory(SchemaDataNode dataNode) { + //key nodes + if (dataNode instanceof Leaf) { + SchemaNodeContainer parent = dataNode.getClosestAncestorNode(); + if (parent instanceof YangList) { + YangList list = (YangList) parent; + if (list.getKey().getKeyNode(dataNode.getIdentifier()) != null) { + return true; + } + } + } + return dataNode.isMandatory(); + } + + private String getOpts(YangStatement yangStatement) { + if ((yangStatement instanceof Leaf) + || (yangStatement instanceof Choice) + || (yangStatement instanceof Anydata) + || (yangStatement instanceof Anyxml)) { + if (!isMandatory((SchemaDataNode) yangStatement)) { + return "?"; + } + } else if (yangStatement instanceof Container) { + if (((Container) yangStatement).isPresence()) { + return "!"; + } + } else if (yangStatement instanceof MultiInstancesDataNode) { + StringBuilder sb = new StringBuilder("*"); + if (yangStatement instanceof YangList) { + YangList yangList = (YangList) yangStatement; + if (yangList.getKey() != null) { + sb.append(" ["); + sb.append(yangList.getKey().getArgStr()); + sb.append("]"); + } + } + return sb.toString(); + } + return ""; + } + + private String getType(TypedDataNode typedDataNode) { + if (typedDataNode.getType().getRestriction() instanceof LeafRef) { + LeafRef leafRef = (LeafRef) typedDataNode.getType().getRestriction(); + return "-> " + leafRef.getEffectivePath().getArgStr(); + } else { + return typedDataNode.getType().getArgStr(); + } + } + + private String getFeatures(IfFeatureSupport ifFeatureSupport) { + StringBuilder sb = new StringBuilder(); + List ifFeatures = ifFeatureSupport.getIfFeatures(); + if (!ifFeatures.isEmpty()) { + sb.append(" {"); + int size = ifFeatures.size(); + for (int i = 0; i < size; i++) { + IfFeature ifFeature = ifFeatures.get(i); + sb.append(ifFeature.getArgStr()); + if (i != (size - 1)) { + sb.append(","); + } + } + sb.append("}?"); + } + return sb.toString(); + } + + private String wrapLongPath(String offSet, String longPath) { + if ((offSet.length() + longPath.length()) <= lineLength) { + return offSet + longPath; + } + StringBuilder wrappedLine = new StringBuilder(offSet); + String firstCandidatePath = longPath.substring(0, lineLength - offSet.length()); + int index = firstCandidatePath.lastIndexOf("/"); + firstCandidatePath = firstCandidatePath.substring(0, index); + wrappedLine.append(firstCandidatePath); + wrappedLine.append("\n"); + String nextOffSet = offSet + " "; + String nextLongPath = longPath.substring(index); + wrappedLine.append(wrapLongPath(nextOffSet, nextLongPath)); + return wrappedLine.toString(); + } + + /** + * build augmentation representation string. + * @param augment augment + * @param offSet offset + * @return string + */ + public String buildAugmentRepresentation(Augment augment, String offSet) { + StringBuilder sb = new StringBuilder(offSet); + int beginIndex = sb.length(); + sb.append("augment"); + sb.append(" "); + int nameIndex = sb.length(); + sb.append(augment.getArgStr()); + sb.append(":\n"); + if (sb.length() > lineLength) { + String subString = sb.substring(0, lineLength); + int index = subString.lastIndexOf("/"); + StringBuilder newSb = new StringBuilder(); + String firstLine = sb.substring(0, index); + newSb.append(firstLine); + newSb.append("\n"); + newSb.append(offSet); + for (int i = beginIndex; i < (nameIndex + 2); i++) { + newSb.append(" "); + } + newSb.append(sb.substring(index)); + return newSb.toString(); + } + return sb.toString(); + } + + /** + * build a node representation from yang statement. + * @param yangStatement yang statement. + * @param offSet offset. + * @return string + */ + public String buildNodeRepresentation(YangStatement yangStatement, String offSet) { + StringBuilder sb = new StringBuilder(offSet); + int beginIndex = sb.length(); + //status + sb.append(getStatus(yangStatement)).append("--"); + //flags + sb.append(getFlags(yangStatement)); + //name + String name = getNodeName(yangStatement); + int nameIndex = sb.length(); + if (name.startsWith(" ")) { + nameIndex++; + } + sb.append(name); + sb.append(getOpts(yangStatement)); + + + if (yangStatement instanceof TypedDataNode) { + int typeIndex = sb.length(); + TypedDataNode typedDataNode = (TypedDataNode) yangStatement; + String type = getType(typedDataNode); + if (type.length() + typeIndex + 1 > lineLength) { + //change line + StringBuilder newLine = new StringBuilder(); + + StringBuilder newOffSet = new StringBuilder(offSet); + + for (int i = beginIndex; i < nameIndex + 2; i++) { + newOffSet.append(" "); + } + newLine.append(newOffSet); + newLine.append(type); + + if ((typedDataNode.getType().getRestriction() instanceof LeafRef) + && (newLine.length() > lineLength)) { + sb.append(" "); + sb.append("leafref"); + } else { + sb.append("\n"); + sb.append(newLine); + } + + + } else { + sb.append(" "); + sb.append(type); + } + } + + if (yangStatement instanceof IfFeatureSupport) { + IfFeatureSupport ifFeatureSupport = (IfFeatureSupport) yangStatement; + String features = getFeatures(ifFeatureSupport); + if (features.length() > 0) { + int ifFeatureIndex = sb.length(); + int lastCrIndex = sb.lastIndexOf("\n"); + if (lastCrIndex == -1) { + lastCrIndex = 0; + } + if (((ifFeatureIndex - lastCrIndex) + features.length()) > lineLength) { + //change line + sb.append("\n"); + sb.append(offSet); + for (int i = beginIndex; i < (nameIndex + 2); i++) { + sb.append(" "); + } + sb.append(features); + } else { + sb.append(" "); + sb.append(features); + } + } + + } + sb.append("\n"); + return sb.toString(); + } + + @Override + public YangCompilerPluginParameter getParameter(String name, JsonElement value) + throws YangCompilerException { + if (!name.equals("output") && !name.equals("line-length") + && !name.equals("expand-grouping")) { + throw new YangCompilerException("unrecognized parameter:" + name); + } + if (name.equals("output")) { + return YangCompilerPlugin.super.getParameter(name, value); + } + YangCompilerPluginParameter yangCompilerPluginParameter = new YangCompilerPluginParameter() { + @Override + public String getName() { + return name; + } + + @Override + public Object getValue() { + + if (name.equals("line-length")) { + return value.getAsInt(); + } + + if (name.equals("expand-grouping")) { + return value.getAsBoolean(); + } + return null; + } + + }; + return yangCompilerPluginParameter; + + + } + + @Override + public void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, + List parameters) throws YangCompilerException { + for (YangCompilerPluginParameter parameter : parameters) { + if (parameter.getName().equals("output")) { + output = (String) parameter.getValue(); + } else if (parameter.getName().equals("line-length")) { + lineLength = (int) parameter.getValue(); + } else if (parameter.getName().equals("expand-grouping")) { + expandGrouping = (boolean) parameter.getValue(); + } + } + if (output == null) { + throw new YangCompilerException("missing mandatory parameter:output"); + } + File outputDir = new File(output); + if (!outputDir.exists()) { + outputDir.mkdirs(); + } + + List modules = schemaContext.getModules(); + for (Module module : modules) { + String yangTree = buildYangTree(module); + FileUtil.writeUtf8File(yangTree, new File(outputDir, + module.getArgStr() + + (module.getCurRevisionDate().isPresent() ? "@" + module.getCurRevisionDate().get() : "") + + "_tree.txt")); + } + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/util/YangCompilerUtil.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/util/YangCompilerUtil.java new file mode 100644 index 0000000..19a63bd --- /dev/null +++ b/yang-compiler/src/main/java/org/onap/modeling/yangkit/compiler/util/YangCompilerUtil.java @@ -0,0 +1,441 @@ +/* +Copyright 2023 Huawei Technologies + +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. +*/ + +package org.onap.modeling.yangkit.compiler.util; + + +import java.io.BufferedReader; +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.Authenticator; +import java.net.HttpURLConnection; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.Proxy; +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.List; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManager; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import org.onap.modeling.yangkit.catalog.ModuleInfo; +import org.onap.modeling.yangkit.catalog.YangCatalog; +import org.onap.modeling.yangkit.compiler.Settings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yangcentral.yangkit.base.YangBuiltinKeyword; + + +import org.yangcentral.yangkit.model.api.stmt.Module; +import org.yangcentral.yangkit.model.api.stmt.SubModule; +import org.yangcentral.yangkit.model.api.stmt.YangStatement; + +public class YangCompilerUtil { + private static final Logger logger = LoggerFactory.getLogger(YangCompilerUtil.class); + + private static ModuleInfo buildModuleInfo(File file) { + String fileName = file.getName(); + String moduleDesc = fileName.substring(0, fileName.indexOf(".yang")); + String[] moduleInfos = moduleDesc.split("@"); + String moduleName = moduleInfos[0]; + String revision = moduleInfos[1]; + ModuleInfo targetModuleInfo = new ModuleInfo(moduleName, revision, null); + targetModuleInfo.setSchema(file.toURI()); + return targetModuleInfo; + } + + /** + * get schema information from local repository. + * @param moduleInfo moduleInfo input, as a filter + * @param settings settings of yang compiler + * @return module information + */ + public static ModuleInfo getSchemaFromLocal(ModuleInfo moduleInfo, Settings settings) { + File localRepository = new File(settings.getLocalRepository()); + if (!localRepository.exists()) { + localRepository.mkdirs(); + } + String prefix = moduleInfo.getModuleInfo(); + String suffix = ".yang"; + FilenameFilter filenameFilter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + if (dir != localRepository) { + return false; + } + if (name.startsWith(prefix) && name.endsWith(suffix)) { + String moduleDesc = name.substring(0, name.indexOf(suffix)); + String[] moduleInfos = moduleDesc.split("@"); + String moduleName = moduleInfos[0]; + String revision = moduleInfos[1]; + if (!moduleName.equals(moduleInfo.getName())) { + return false; + } + if (moduleInfo.withRevision()) { + if (!revision.equals(moduleInfo.getRevision())) { + return false; + } + } + return true; + } + return false; + } + }; + + File[] matched = localRepository.listFiles(filenameFilter); + if (matched == null || matched.length == 0) { + return null; + } + if (matched.length == 1) { + return buildModuleInfo(matched[0]); + } + File latest = null; + for (File file : matched) { + if (latest == null) { + latest = file; + } else { + if (file.getName().compareTo(latest.getName()) > 0) { + latest = file; + } + } + } + + return buildModuleInfo(latest); + } + + /** + * get schema information from module information of settings. + * @param moduleInfo moduleInfo input, as a filter + * @param moduleInfoList the list of module information of settings + * @return module information. + */ + public static ModuleInfo getSchemaFromModuleInfos(ModuleInfo moduleInfo, List moduleInfoList) { + if (null != moduleInfoList) { + ModuleInfo targetModuleInfo = null; + // if module info is not null, try to find the matched module info. + // note: if the revision is null, it means match the latest module info + for (ModuleInfo mi : moduleInfoList) { + if (!mi.getName().equals(moduleInfo.getName())) { + continue; + } + if (moduleInfo.withRevision()) { + if (moduleInfo.getRevision().equals(mi.getRevision())) { + targetModuleInfo = mi; + break; + } + } else { + if (targetModuleInfo == null) { + targetModuleInfo = mi; + } else { + if (targetModuleInfo.getRevision().compareTo(mi.getRevision()) < 0) { + targetModuleInfo = mi; + } + } + } + } + //if not found,try to find it from local repository + if (targetModuleInfo != null) { + return targetModuleInfo; + } + } + return null; + } + + /** + * invoke a url. + * @param url url + * @param settings settings + * @return input stream + * @throws IOException io exception + */ + public static InputStream urlInvoke(String url, Settings settings) throws IOException { + URL catalogUrl = URI.create(url).toURL(); + return urlInvoke(catalogUrl, settings); + } + + /** + * invoke a url. + * @param url url + * @param settings settings + * @return input stream + * @throws IOException io exception. + */ + public static InputStream urlInvoke(URL url, Settings settings) throws IOException { + Proxy proxy = null; + Authenticator authenticator = null; + if (settings.getProxy() != null) { + String protocol = url.getProtocol(); + Proxy.Type proxyType = null; + if (protocol.equalsIgnoreCase("http") || protocol.equalsIgnoreCase("https")) { + proxyType = Proxy.Type.HTTP; + } else { + proxyType = Proxy.Type.SOCKS; + } + proxy = new Proxy(proxyType, + new InetSocketAddress(settings.getProxy().getHostName(), settings.getProxy().getPort())); + if (settings.getProxy().getAuthentication() != null) { + authenticator = new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(settings.getProxy().getAuthentication().getName(), + settings.getProxy().getAuthentication().getPassword().toCharArray() + ); + } + }; + Authenticator.setDefault(authenticator); + } + + } + return urlGet(url, proxy, authenticator, settings.getToken(), 120000, 100000); + } + + /** + * invoke a url and return string. + * @param url url + * @param settings settings + * @return string + * @throws IOException io exception + */ + public static String urlInvoke2String(String url, Settings settings) throws IOException { + InputStream inputStream = urlInvoke(url, settings); + StringBuilder sb = new StringBuilder(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + + String output; + while ((output = bufferedReader.readLine()) != null) { + sb.append(output); + sb.append("\n"); + } + bufferedReader.close(); + inputStream.close(); + return sb.toString(); + + } + + /** + * get schema information from remote repository. + * @param moduleInfo module information, as a filter + * @param settings settings + * @return module information + * @throws IOException io exception + */ + public static ModuleInfo getSchemaFromRemote(ModuleInfo moduleInfo, Settings settings) throws IOException { + ModuleInfo targetModuleInfo = null; + if (moduleInfo.getRevision() == null || moduleInfo.getRevision().equals("")) { + String url = settings.getRemoteRepository() + "search/name/" + moduleInfo.getName(); + YangCatalog yangCatalog = YangCatalog.parse(urlInvoke2String(url, settings)); + targetModuleInfo = yangCatalog.getLatestModule(moduleInfo.getName()); + } else { + String organization = moduleInfo.getOrganization(); + if (organization == null) { + organization = moduleInfo.getName().substring(0, moduleInfo.getName().indexOf("-")); + } + + if (organization.equals("junos")) { + organization = "juniper"; + } + String url = settings.getRemoteRepository() + + "search/modules/" + + moduleInfo.getName() + + "," + + moduleInfo.getRevision() + + "," + + organization; + + targetModuleInfo = ModuleInfo.parse(urlInvoke2String(url, settings)); + } + if (targetModuleInfo == null) { + return null; + } + return targetModuleInfo; + } + + /** + * get schema according to module information (as a filter). + * @param moduleInfo module information, as a filter + * @param settings settings + * @return module information + * @throws IOException io exception + */ + public static ModuleInfo getSchema(ModuleInfo moduleInfo, Settings settings) throws IOException { + + ModuleInfo targetModuleInfo = null; + //get schema from module information of settings + logger.info("get schema for module:" + moduleInfo.getModuleInfo()); + List moduleInfoList = settings.getModuleInfos(); + targetModuleInfo = getSchemaFromModuleInfos(moduleInfo, moduleInfoList); + if (targetModuleInfo != null) { + logger.info( + "find schema:" + targetModuleInfo.getSchema() + " for module:" + targetModuleInfo.getModuleInfo()); + return targetModuleInfo; + } + //get schema from local repository + targetModuleInfo = getSchemaFromLocal(moduleInfo, settings); + if (targetModuleInfo != null) { + logger.info( + "find schema:" + targetModuleInfo.getSchema() + " for module:" + targetModuleInfo.getModuleInfo()); + return targetModuleInfo; + } + + //get schema from remote repository + try { + targetModuleInfo = getSchemaFromRemote(moduleInfo, settings); + if (null != targetModuleInfo) { + logger.info("find schema:" + targetModuleInfo.getSchema() + + " for module:" + + targetModuleInfo.getModuleInfo()); + return targetModuleInfo; + } + logger.warn("can not find schema for module:" + moduleInfo.getModuleInfo()); + return null; + + } catch (RuntimeException e) { + logger.error(e.getMessage()); + return null; + } + + } + + /** + * send get operation to a url, and return input stream. + * @param url url + * @param proxy proxy + * @param authenticator authenticator + * @param token token + * @param connectionTimeout time out for connection + * @param readTimeout time out for read + * @return input stream + * @throws IOException io exception + */ + public static InputStream urlGet(URL url, Proxy proxy, Authenticator authenticator, String token, + int connectionTimeout, int readTimeout) throws IOException { + URLConnection urlConnection; + if (proxy != null) { + urlConnection = url.openConnection(proxy); + } else { + urlConnection = url.openConnection(); + } + + if (null != authenticator) { + Authenticator.setDefault(authenticator); + } + + if (token != null) { + urlConnection.setRequestProperty("Authorization", "Token " + token); + } + + urlConnection.setConnectTimeout(connectionTimeout); + urlConnection.setReadTimeout(readTimeout); + if (urlConnection instanceof HttpURLConnection) { + if (urlConnection instanceof HttpsURLConnection) { + TrustManager[] trustManagers = new TrustManager[]{new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] x509Certificates, String str) + throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] x509Certificates, String str) + throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }}; + + try { + SSLContext context = SSLContext.getInstance("TLS"); + context.init((KeyManager[]) null, trustManagers, (SecureRandom) null); + ((HttpsURLConnection) urlConnection).setSSLSocketFactory(context.getSocketFactory()); + } catch (NoSuchAlgorithmException var10) { + throw new RuntimeException(var10); + } catch (KeyManagementException var11) { + throw new RuntimeException(var11); + } + } + + HttpURLConnection httpUrlConnection = (HttpURLConnection) urlConnection; + httpUrlConnection.setRequestMethod("GET"); + logger.info("get from url:" + url + "..."); + int responseCode = httpUrlConnection.getResponseCode(); + if (responseCode != 200) { + logger.error("failed"); + throw new RuntimeException("GET request:" + url + " failed with error code=" + responseCode); + } + logger.info("ok"); + } + + return urlConnection.getInputStream(); + + } + + /** + * get dependencies of a specified module. + * @param module module + * @return list of dependencies + */ + public static List getDependencies(Module module) { + List dependencies = new ArrayList<>(); + if (module == null) { + return dependencies; + } + List importStatements = module.getSubStatement(YangBuiltinKeyword.IMPORT.getQName()); + for (YangStatement importStatement : importStatements) { + String moduleName = importStatement.getArgStr(); + String revision = null; + List revisions = importStatement.getSubStatement(YangBuiltinKeyword.REVISIONDATE.getQName()); + if (revisions.isEmpty()) { + revision = ""; + } else { + revision = revisions.get(0).getArgStr(); + } + ModuleInfo moduleInfo = new ModuleInfo(moduleName, revision); + dependencies.add(moduleInfo); + } + List includeStatements = module.getSubStatement(YangBuiltinKeyword.INCLUDE.getQName()); + for (YangStatement includeStatement : includeStatements) { + String moduleName = includeStatement.getArgStr(); + String revision = null; + List revisions = + includeStatement.getSubStatement(YangBuiltinKeyword.REVISIONDATE.getQName()); + if (revisions.isEmpty()) { + revision = ""; + } else { + revision = revisions.get(0).getArgStr(); + } + ModuleInfo moduleInfo = new ModuleInfo(moduleName, revision); + dependencies.add(moduleInfo); + } + if (module instanceof SubModule) { + List belongsToStatements = module.getSubStatement(YangBuiltinKeyword.BELONGSTO.getQName()); + String moduleName = belongsToStatements.get(0).getArgStr(); + ModuleInfo moduleInfo = new ModuleInfo(moduleName, ""); + dependencies.add(moduleInfo); + } + return dependencies; + } +} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/YangCompilerPlugin.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/YangCompilerPlugin.java deleted file mode 100644 index a30f9fc..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/YangCompilerPlugin.java +++ /dev/null @@ -1,74 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin; - -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Matcher; - -import org.onap.modeling.yangkit.compiler.YangCompiler; -import org.onap.modeling.yangkit.compiler.YangCompilerException; -import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; - - -public interface YangCompilerPlugin { - /** - * default implementation of get parameter method. - * @param compilerProps the properties of yang compiler. - * @param name the name of parameter - * @param value the value of parameter - * @return yang compiler plugin parameter - * @throws YangCompilerException if error occurs, the exception will be thrown. - */ - default YangCompilerPluginParameter getParameter(Properties compilerProps, String name, String value) - throws YangCompilerException { - YangCompilerPluginParameter yangCompilerPluginParameter = new YangCompilerPluginParameter() { - @Override - public String getName() { - return name; - } - - @Override - public Object getValue() { - Iterator> it = compilerProps.entrySet().iterator(); - String formatStr = value; - while (it.hasNext()) { - Map.Entry entry = it.next(); - formatStr = formatStr.replaceAll("\\{" + entry.getKey() + "\\}", - Matcher.quoteReplacement((String) entry.getValue())); - } - return formatStr; - - } - - }; - return yangCompilerPluginParameter; - } - - /** - * the definition of run method. - * @param schemaContext yang schema context - * @param yangCompiler yang compiler instance - * @param parameters parameters - * @throws YangCompilerException if error occurs, the exception will be thrown. - */ - void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, List parameters) - throws YangCompilerException; - -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/YangCompilerPluginParameter.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/YangCompilerPluginParameter.java deleted file mode 100644 index f3cb7aa..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/YangCompilerPluginParameter.java +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin; - -import org.onap.modeling.yangkit.compiler.YangCompilerException; - - -public interface YangCompilerPluginParameter { - /** - * get parameter name. - * @return name - */ - String getName(); - - /** - * get parameter value. - * @return value - * @throws YangCompilerException yang compiler exception - */ - Object getValue() throws YangCompilerException; -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/stat/YangNodeDescription.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/stat/YangNodeDescription.java deleted file mode 100644 index 2a903ca..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/stat/YangNodeDescription.java +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.stat; - - -public class YangNodeDescription { - private String path; - private String description; - private String config; - private String schemaType; - private String nodeType; - private String module; - private boolean isActive; - private boolean isDeviated; - - public YangNodeDescription() { - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getConfig() { - return config; - } - - public void setConfig(String config) { - this.config = config; - } - - public String getSchemaType() { - return schemaType; - } - - public void setSchemaType(String schemaType) { - this.schemaType = schemaType; - } - - public String getNodeType() { - return nodeType; - } - - public void setNodeType(String nodeType) { - this.nodeType = nodeType; - } - - public String getModule() { - return module; - } - - public void setModule(String module) { - this.module = module; - } - - public boolean isActive() { - return isActive; - } - - public void setActive(boolean active) { - isActive = active; - } - - public boolean isDeviated() { - return isDeviated; - } - - public void setDeviated(boolean deviated) { - isDeviated = deviated; - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/stat/YangStatistics.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/stat/YangStatistics.java deleted file mode 100644 index f5863cc..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/stat/YangStatistics.java +++ /dev/null @@ -1,278 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.stat; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.xssf.streaming.SXSSFCell; -import org.apache.poi.xssf.streaming.SXSSFRow; -import org.apache.poi.xssf.streaming.SXSSFSheet; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.onap.modeling.yangkit.compiler.YangCompiler; -import org.onap.modeling.yangkit.compiler.YangCompilerException; -import org.onap.modeling.yangkit.plugin.YangCompilerPlugin; -import org.onap.modeling.yangkit.plugin.YangCompilerPluginParameter; -import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; -import org.yangcentral.yangkit.model.api.stmt.Module; -import org.yangcentral.yangkit.model.api.stmt.SchemaNode; -import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer; -import org.yangcentral.yangkit.model.api.stmt.SubModule; -import org.yangcentral.yangkit.model.api.stmt.TypedDataNode; -import org.yangcentral.yangkit.model.api.stmt.VirtualSchemaNode; - - -public class YangStatistics implements YangCompilerPlugin { - /** - * get node description. - * @param schemaNode schema node - * @return node description - */ - public YangNodeDescription getNodeDescription(SchemaNode schemaNode) { - if (schemaNode == null) { - return null; - } - if (schemaNode instanceof VirtualSchemaNode) { - return null; - } - if (schemaNode.getSchemaPath() == null) { - return null; - } - YangNodeDescription nodeDescription = new YangNodeDescription(); - nodeDescription.setPath(schemaNode.getSchemaPath().toString()); - nodeDescription.setDescription( - schemaNode.getDescription() == null ? "" : schemaNode.getDescription().getArgStr()); - nodeDescription.setConfig(schemaNode.isConfig() ? "true" : "false"); - nodeDescription.setSchemaType(schemaNode.getYangKeyword().getLocalName()); - if (schemaNode instanceof TypedDataNode) { - TypedDataNode typedDataNode = (TypedDataNode) schemaNode; - nodeDescription.setNodeType(typedDataNode.getType().getArgStr()); - } - nodeDescription.setModule(schemaNode.getContext().getCurModule().getArgStr()); - nodeDescription.setActive(schemaNode.isActive()); - nodeDescription.setDeviated(schemaNode.isDeviated()); - return nodeDescription; - } - - /** - * get node description for schema node container. - * @param schemaNodeContainer schema node container - * @return list of node description. - */ - public List getNodeDescriptions(SchemaNodeContainer schemaNodeContainer) { - if (schemaNodeContainer == null) { - return new ArrayList<>(); - } - List nodeDescriptions = new ArrayList<>(); - if (schemaNodeContainer instanceof SchemaNode) { - SchemaNode schemaNode = (SchemaNode) schemaNodeContainer; - YangNodeDescription nodeDescription = getNodeDescription(schemaNode); - if (nodeDescription != null) { - nodeDescriptions.add(nodeDescription); - } - } - - for (SchemaNode schemaNode : schemaNodeContainer.getSchemaNodeChildren()) { - if (schemaNode instanceof SchemaNodeContainer) { - nodeDescriptions.addAll(getNodeDescriptions((SchemaNodeContainer) schemaNode)); - } else { - YangNodeDescription nodeDescription = getNodeDescription(schemaNode); - if (nodeDescription != null) { - nodeDescriptions.add(nodeDescription); - } - } - } - return nodeDescriptions; - } - - /** - * get yang statistics for yang schema context. - * @param schemaContext yang schema context. - * @return list of node description. - */ - public List getYangStatistics(YangSchemaContext schemaContext) { - List nodeDescriptions = new ArrayList<>(); - if (schemaContext == null) { - return nodeDescriptions; - } - for (Module module : schemaContext.getModules()) { - if (module instanceof SubModule) { - continue; - } - nodeDescriptions.addAll(getNodeDescriptions(module)); - } - return nodeDescriptions; - } - - /** - * serialize the yang statistics of schema context to xlsx format. - * @param schemaContext yang schema context. - * @return xlsx document - */ - public SXSSFWorkbook serializeXlsx(YangSchemaContext schemaContext) { - SXSSFWorkbook workbook = new SXSSFWorkbook(); - SXSSFSheet summary = workbook.createSheet("summary"); - summary.setDisplayGridlines(true); - summary.setAutobreaks(true); - summary.setColumnWidth(0, 5000); - summary.setColumnWidth(1, 5000); - SXSSFRow sumFirstRow = summary.createRow(0); - SXSSFCell totalModules = sumFirstRow.createCell(0); - totalModules.setCellValue("Total modules:"); - SXSSFCell totalModulesVal = sumFirstRow.createCell(1); - totalModulesVal.setCellValue(schemaContext.getModules().size()); - - SXSSFSheet detail = workbook.createSheet("detail"); - detail.setDisplayGridlines(true); - detail.setAutobreaks(true); - detail.setColumnWidth(0, 20000); - detail.setColumnWidth(1, 5000); - detail.setColumnWidth(2, 20000); - detail.setColumnWidth(3, 5000); - detail.setColumnWidth(4, 5000); - detail.setColumnWidth(5, 5000); - detail.setColumnWidth(6, 5000); - detail.setColumnWidth(7, 5000); - - CellStyle style = workbook.createCellStyle(); - style.setBorderBottom(BorderStyle.THIN); - style.setBorderLeft(BorderStyle.THIN); - style.setBorderRight(BorderStyle.THIN); - style.setBorderTop(BorderStyle.THIN); - - CellStyle desStyle = workbook.createCellStyle(); - desStyle.cloneStyleFrom(style); - desStyle.setAlignment(HorizontalAlignment.JUSTIFY); - - detail.setDefaultColumnStyle(0, style); - detail.setDefaultColumnStyle(1, desStyle); - detail.setDefaultColumnStyle(2, style); - detail.setDefaultColumnStyle(3, style); - detail.setDefaultColumnStyle(4, style); - detail.setDefaultColumnStyle(5, style); - detail.setDefaultColumnStyle(6, style); - detail.setDefaultColumnStyle(7, style); - - //generate header - SXSSFRow firstRow = detail.createRow(0); - SXSSFCell yangpath = firstRow.createCell(0); - yangpath.setCellValue("Path"); - yangpath.setCellStyle(style); - SXSSFCell active = firstRow.createCell(1); - active.setCellValue("Active"); - active.setCellStyle(style); - SXSSFCell description = firstRow.createCell(2); - description.setCellValue("Description"); - description.setCellStyle(style); - SXSSFCell config = firstRow.createCell(3); - config.setCellValue("Config"); - config.setCellStyle(style); - SXSSFCell schema = firstRow.createCell(4); - schema.setCellValue("schema"); - schema.setCellStyle(style); - SXSSFCell type = firstRow.createCell(5); - type.setCellValue("type"); - type.setCellStyle(style); - SXSSFCell moduleHeader = firstRow.createCell(6); - moduleHeader.setCellValue("module"); - moduleHeader.setCellStyle(style); - SXSSFCell deviated = firstRow.createCell(7); - deviated.setCellValue("deviated"); - deviated.setCellStyle(style); - - - List totalPaths = getYangStatistics(schemaContext); - - - if (null != totalPaths) { - int pathSize = totalPaths.size(); - SXSSFRow summarySecRow = summary.createRow(1); - SXSSFCell totalNodes = summarySecRow.createCell(0); - totalNodes.setCellValue("Total nodes:"); - SXSSFCell totalNodesVal = summarySecRow.createCell(1); - totalNodesVal.setCellValue(pathSize); - for (int i = 0; i < pathSize; i++) { - YangNodeDescription path = totalPaths.get(i); - SXSSFRow row = detail.createRow(i + 1); - SXSSFCell pathCell = row.createCell(0); - pathCell.setCellValue(path.getPath()); - pathCell.setCellStyle(style); - SXSSFCell activeCell = row.createCell(1); - activeCell.setCellValue(path.isActive()); - activeCell.setCellStyle(style); - SXSSFCell descriptionCell = row.createCell(2); - String str = path.getDescription(); - if (str.length() >= 32767) { - str = str.substring(0, 32767); - } - descriptionCell.setCellValue(str); - descriptionCell.setCellStyle(desStyle); - - SXSSFCell configCell = row.createCell(3); - configCell.setCellValue(path.getConfig()); - configCell.setCellStyle(style); - - SXSSFCell schemaCell = row.createCell(4); - schemaCell.setCellValue(path.getSchemaType()); - schemaCell.setCellStyle(style); - - SXSSFCell typeCell = row.createCell(5); - typeCell.setCellValue(path.getNodeType()); - typeCell.setCellStyle(style); - - SXSSFCell moduleCell = row.createCell(6); - moduleCell.setCellValue(path.getModule()); - moduleCell.setCellStyle(style); - SXSSFCell deviateCell = row.createCell(7); - deviateCell.setCellValue(path.isDeviated()); - deviateCell.setCellStyle(style); - } - } - return workbook; - } - - /** - * a yang compiler plugin implementation (run method). - * @param schemaContext yang schema context - * @param yangCompiler yang compiler instance - * @param parameters parameters for plugin - * @throws YangCompilerException if error occurs, throw the exception - */ - @Override - public void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, - List parameters) throws YangCompilerException { - - YangCompilerPluginParameter para = parameters.get(0); - if (!para.getName().equals("output")) { - throw new YangCompilerException("unknown parameter:" + para.getName()); - } - String output = (String) para.getValue(); - SXSSFWorkbook workbook = serializeXlsx(schemaContext); - try { - workbook.write(new FileOutputStream(output)); - workbook.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/validator/YangValidator.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/validator/YangValidator.java deleted file mode 100644 index 5131416..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/validator/YangValidator.java +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.validator; - -import java.util.List; - -import org.onap.modeling.yangkit.compiler.YangCompiler; -import org.onap.modeling.yangkit.compiler.YangCompilerException; -import org.onap.modeling.yangkit.plugin.YangCompilerPlugin; -import org.onap.modeling.yangkit.plugin.YangCompilerPluginParameter; -import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; -import org.yangcentral.yangkit.utils.file.FileUtil; - - -public class YangValidator implements YangCompilerPlugin { - /** - * the implementation of run method. - * @param schemaContext yang schema context. - * @param yangCompiler yang compiler instance. - * @param parameters parameters of plugin. - * @throws YangCompilerException if error occurs, the exception will be thrown. - */ - @Override - public void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, - List parameters) throws YangCompilerException { - YangCompilerPluginParameter parameter = parameters.get(0); - if (!parameter.getName().equals("output")) { - throw new YangCompilerException("unknown parameter:" + parameter.getName()); - } - FileUtil.writeUtf8File((String) parameter.getValue(), schemaContext.getValidateResult().toString()); - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/ModuleInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/ModuleInfo.java deleted file mode 100644 index 1b2a4b4..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/ModuleInfo.java +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.yangpackage; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.net.URI; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - - -public class ModuleInfo extends SubComponentInfo { - private URI namespace; - private final List subModules = new ArrayList<>(); - - /** - * constructor. - * @param name module name - * @param revision module revision - */ - public ModuleInfo(String name, String revision) { - super(name, revision); - } - - /** - * constructor. - * @param name module name - */ - public ModuleInfo(String name) { - super(name); - } - - /** - * serialize the revision. - * @return serialized revision - */ - @Override - protected Map.Entry serializeRevision() { - if (this.getRevision() == null) { - return null; - } - return new AbstractMap.SimpleEntry<>("revision", this.getRevision()); - } - - /** - * get namespace. - * @return the uri of namespace - */ - public URI getNamespace() { - return namespace; - } - - /** - * set namespace. - * @param namespace the uri of namespace - */ - public void setNamespace(URI namespace) { - this.namespace = namespace; - } - - /** - * get submodules. - * @return list of submodules. - */ - public List getSubModules() { - return subModules; - } - - /** - * add submodule. - * @param subModuleInfo submodule - */ - public void addSubModule(SubModuleInfo subModuleInfo) { - if (subModules.contains(subModuleInfo)) { - return; - } - subModules.add(subModuleInfo); - } - - /** - * serialize the module information. - * @return json element. - */ - @Override - public JsonElement serialize() { - JsonObject jsonObject = super.serialize().getAsJsonObject(); - if (this.getNamespace() != null) { - jsonObject.addProperty("namespace", this.getNamespace().toString()); - } - if (!this.getSubModules().isEmpty()) { - JsonArray subModules = new JsonArray(); - for (SubModuleInfo subModule : this.getSubModules()) { - subModules.add(subModule.serialize()); - } - jsonObject.add("submodule", subModules); - } - return jsonObject; - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/PackageInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/PackageInfo.java deleted file mode 100644 index a46f5f3..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/PackageInfo.java +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.yangpackage; - -import java.util.AbstractMap; -import java.util.Map; - - -public class PackageInfo extends SubComponentInfo { - /** - * constructor. - * @param name package name - * @param revision package revision. - */ - public PackageInfo(String name, String revision) { - super(name, revision); - } - - /** - * serialize the revision. - * @return serialized revision. - */ - @Override - protected Map.Entry serializeRevision() { - if (this.getRevision() == null) { - return null; - } - Map.Entry revisionEntry = new AbstractMap.SimpleEntry<>("version", this.getRevision()); - return revisionEntry; - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/SubComponentInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/SubComponentInfo.java deleted file mode 100644 index 6cdd005..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/SubComponentInfo.java +++ /dev/null @@ -1,171 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.yangpackage; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; - - -public abstract class SubComponentInfo { - private final String name; - private String revision; - private final List replaceRevisions = new ArrayList<>(); - private List locations; - - /** - * constructor. - * @param name the name of subcomponent. - * @param revision the revision of subcomponent. - */ - public SubComponentInfo(String name, String revision) { - this.name = name; - this.revision = revision; - } - - /** - * constructor. - * @param name the name of subcomponent. - */ - public SubComponentInfo(String name) { - this.name = name; - } - - /** - * get the name of subcomponent. - * @return name. - */ - public String getName() { - return name; - } - - /** - * get the revision of subcomponent. - * @return revision - */ - public String getRevision() { - return revision; - } - - /** - * set the revision of subcomponent. - * @param revision revision - */ - public void setRevision(String revision) { - this.revision = revision; - } - - /** - * get the replaced revisions. - * @return the list of revisions. - */ - public List getReplaceRevisions() { - return replaceRevisions; - } - - /** - * add replace revision. - * @param revision the revision to be replaced. - */ - public void addReplaceRevision(String revision) { - if (replaceRevisions.contains(revision)) { - return; - } - replaceRevisions.add(revision); - } - - /** - * get locations of subcomponent. - * @return list of location uri. - */ - public List getLocations() { - return locations; - } - - /** - * add location. - * @param location location uri. - */ - public void addLocation(URI location) { - if (locations.contains(location)) { - return; - } - locations.add(location); - } - - /** - * equals method. - * @param obj other object. - * @return true or false. - */ - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof SubComponentInfo)) { - return false; - } - SubComponentInfo that = (SubComponentInfo) obj; - return getName().equals(that.getName()) && getRevision().equals(that.getRevision()); - } - - @Override - public int hashCode() { - return Objects.hash(getName(), getRevision()); - } - - /** - * the abstract method of serialize the revision. - * @return serialized revision. - */ - protected abstract Map.Entry serializeRevision(); - - /** - * serialize the subcomponent to json element. - * @return json element. - */ - public JsonElement serialize() { - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("name", this.getName()); - if (this.getRevision() != null) { - Map.Entry revisionEntry = serializeRevision(); - jsonObject.addProperty(revisionEntry.getKey(), revisionEntry.getValue()); - } - if (!this.getReplaceRevisions().isEmpty()) { - JsonArray replaceRevisions = new JsonArray(); - for (String replaceRevision : this.getReplaceRevisions()) { - replaceRevisions.add(replaceRevision); - } - jsonObject.add("replaces-version", replaceRevisions); - } - if (!this.getLocations().isEmpty()) { - JsonArray locations = new JsonArray(); - for (URI location : this.getLocations()) { - locations.add(location.toString()); - } - jsonObject.add("location", locations); - } - return jsonObject; - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/SubModuleInfo.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/SubModuleInfo.java deleted file mode 100644 index eb290fc..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/SubModuleInfo.java +++ /dev/null @@ -1,125 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.yangpackage; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - - -public class SubModuleInfo { - private final String name; - private final String revision; - private List locations = new ArrayList<>(); - - /** - * constructor. - * @param name submodule name - * @param revision submodule revision - */ - public SubModuleInfo(String name, String revision) { - this.name = name; - this.revision = revision; - } - - /** - * get the submodule name. - * @return name - */ - public String getName() { - return name; - } - - /** - * get the revision of submodule. - * @return revision - */ - public String getRevision() { - return revision; - } - - /** - * get locations of submodule. - * @return list of location. - */ - public List getLocations() { - return locations; - } - - /** - * set the locations. - * @param locations list of location. - */ - public void setLocations(List locations) { - this.locations = locations; - } - - /** - * add a location. - * @param location location uri - */ - public void addLocation(URI location) { - if (locations.contains(location)) { - return; - } - locations.add(location); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof SubModuleInfo)) { - return false; - } - SubModuleInfo that = (SubModuleInfo) obj; - return getName().equals(that.getName()) && getRevision().equals(that.getRevision()); - } - - @Override - public int hashCode() { - return Objects.hash(getName(), getRevision()); - } - - /** - * serialize submodule to json. - * @return json element. - */ - public JsonElement serialize() { - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("name", this.getName()); - if (this.getRevision() != null) { - jsonObject.addProperty("revision", this.getRevision()); - } - - if (!this.getLocations().isEmpty()) { - JsonArray locations = new JsonArray(); - for (URI location : this.getLocations()) { - locations.add(location.toString()); - } - jsonObject.add("location", locations); - } - return jsonObject; - - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackage.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackage.java deleted file mode 100644 index 2a7913f..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackage.java +++ /dev/null @@ -1,395 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.yangpackage; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.util.ArrayList; -import java.util.List; - - -public class YangPackage { - private final String name; - private final String revision; - private String timestamp; - private String organization; - private String contact; - private String description; - private String reference; - private boolean complete = true; - private boolean local; - private List tags = new ArrayList<>(); - private List mandatoryFeatures = new ArrayList<>(); - private List includePackages = new ArrayList<>(); - private List modules = new ArrayList<>(); - private List importOnlyModules = new ArrayList<>(); - - /** - * constructor. - * @param name package name - * @param revision package revision - */ - public YangPackage(String name, String revision) { - this.name = name; - this.revision = revision; - } - - /** - * get the package name. - * @return name - */ - public String getName() { - return name; - } - - /** - * get the package revision. - * @return revision - */ - public String getRevision() { - return revision; - } - - /** - * get the timestamp. - * @return timestamp. - */ - public String getTimestamp() { - return timestamp; - } - - /** - * set the timestamp. - * @param timestamp timestamp - */ - public void setTimestamp(String timestamp) { - this.timestamp = timestamp; - } - - /** - * get organization. - * @return organization. - */ - public String getOrganization() { - return organization; - } - - /** - * set organization. - * @param organization organization - */ - public void setOrganization(String organization) { - this.organization = organization; - } - - /** - * get contact information. - * @return contact. - */ - public String getContact() { - return contact; - } - - /** - * set the contact. - * @param contact contact. - */ - public void setContact(String contact) { - this.contact = contact; - } - - /** - * get description. - * @return description. - */ - public String getDescription() { - return description; - } - - /** - * set description. - * @param description description. - */ - public void setDescription(String description) { - this.description = description; - } - - /** - * get reference. - * @return reference. - */ - public String getReference() { - return reference; - } - - /** - * set reference. - * @param reference reference. - */ - public void setReference(String reference) { - this.reference = reference; - } - - /** - * whether the package is complete. - * @return true or false. - */ - public boolean isComplete() { - return complete; - } - - /** - * set whether the package is complete. - * @param complete true or false. - */ - public void setComplete(boolean complete) { - this.complete = complete; - } - - /** - * whether the package is local. - * @return true or false - */ - public boolean isLocal() { - return local; - } - - /** - * set whether the package is local. - * @param local true or false - */ - public void setLocal(boolean local) { - this.local = local; - } - - /** - * get the tags of package. - * @return the list of tags. - */ - public List getTags() { - return tags; - } - - /** - * set the tags of package. - * @param tags the list of tags. - */ - public void setTags(List tags) { - this.tags = tags; - } - - /** - * add a tag to package. - * @param tag tag - */ - public void addTag(String tag) { - if (tags.contains(tag)) { - return; - } - tags.add(tag); - } - - /** - * get mandatory features of package. - * @return list of features. - */ - public List getMandatoryFeatures() { - return mandatoryFeatures; - } - - /** - * set mandatory features. - * @param mandatoryFeatures list of mandatory features. - */ - public void setMandatoryFeatures(List mandatoryFeatures) { - this.mandatoryFeatures = mandatoryFeatures; - } - - /** - * add mandatory feature. - * @param feature feature - */ - public void addMandatoryFeature(String feature) { - if (mandatoryFeatures.contains(feature)) { - return; - } - mandatoryFeatures.add(feature); - } - - /** - * get include packages. - * @return list of included packages. - */ - public List getIncludePackages() { - return includePackages; - } - - /** - * set the include packages. - * @param includePackages the list of include packages. - */ - public void setIncludePackages(List includePackages) { - this.includePackages = includePackages; - } - - /** - * add a include package. - * @param packageInfo package - */ - public void addIncludePackage(PackageInfo packageInfo) { - if (includePackages.contains(packageInfo)) { - return; - } - includePackages.add(packageInfo); - } - - /** - * get the modules of package. - * @return list of modules. - */ - public List getModules() { - return modules; - } - - /** - * set the modules of package. - * @param modules list of modules - */ - public void setModules(List modules) { - this.modules = modules; - } - - /** - * add a module to package. - * @param module module - */ - public void addModule(ModuleInfo module) { - if (this.modules.contains(module)) { - return; - } - modules.add(module); - } - - /** - * get import-only modules. - * @return list of modules. - */ - public List getImportOnlyModules() { - return importOnlyModules; - } - - /** - * add a import-only module. - * @param module module - */ - public void addImportOnlyModule(ModuleInfo module) { - if (importOnlyModules.contains(module)) { - return; - } - importOnlyModules.add(module); - } - - /** - * set import-only modules. - * @param importOnlyModules list of modules - */ - public void setImportOnlyModules(List importOnlyModules) { - this.importOnlyModules = importOnlyModules; - } - - /** - * serialize yang package to json. - * @return json element - */ - public JsonElement serialize() { - JsonObject document = new JsonObject(); - JsonObject instanceDataset = new JsonObject(); - document.add("ietf-yang-instance-data:instance-data-set", instanceDataset); - instanceDataset.addProperty("name", this.getName()); - JsonObject contentSchema = new JsonObject(); - instanceDataset.add("content-schema", contentSchema); - JsonArray moduleArray = new JsonArray(); - moduleArray.add("ietf-yang-package-instance@2020-01-21"); - contentSchema.add("module", moduleArray); - JsonObject contentData = new JsonObject(); - instanceDataset.add("content-data", contentData); - JsonObject yangPackage = new JsonObject(); - contentData.add("ietf-yang-package-instance:yang-package", yangPackage); - yangPackage.addProperty("name", this.getName()); - yangPackage.addProperty("version", this.getRevision()); - // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); - // String dateTime = sdf.format(new Date(System.currentTimeMillis())); - if (this.getTimestamp() != null) { - yangPackage.addProperty("timestamp", this.getTimestamp()); - } - - if (this.getOrganization() != null) { - yangPackage.addProperty("organization", this.getOrganization()); - } - if (this.getContact() != null) { - yangPackage.addProperty("contact", this.getContact()); - } - if (this.getDescription() != null) { - yangPackage.addProperty("description", this.getDescription()); - } - if (this.getReference() != null) { - yangPackage.addProperty("reference", this.getReference()); - } - yangPackage.addProperty("complete", this.isComplete()); - yangPackage.addProperty("local", this.isLocal()); - - if (!this.getTags().isEmpty()) { - JsonArray tags = new JsonArray(); - for (String tag : this.getTags()) { - tags.add(tag); - } - yangPackage.add("tag", tags); - } - if (!this.getMandatoryFeatures().isEmpty()) { - JsonArray mandatoryFeatures = new JsonArray(); - for (String mandatoryFeature : this.getMandatoryFeatures()) { - mandatoryFeatures.add(mandatoryFeature); - } - yangPackage.add("mandatory-feature", mandatoryFeatures); - } - if (!this.getIncludePackages().isEmpty()) { - JsonArray includePackages = new JsonArray(); - for (PackageInfo packageInfo : this.getIncludePackages()) { - includePackages.add(packageInfo.serialize()); - } - yangPackage.add("included-package", includePackages); - } - if (!this.getModules().isEmpty()) { - JsonArray modules = new JsonArray(); - for (ModuleInfo moduleInfo : this.getModules()) { - modules.add(moduleInfo.serialize()); - } - yangPackage.add("module", modules); - } - - if (!this.getImportOnlyModules().isEmpty()) { - JsonArray importOnlyModules = new JsonArray(); - for (ModuleInfo importOnlyModule : this.getImportOnlyModules()) { - importOnlyModules.add(importOnlyModule.serialize()); - } - yangPackage.add("import-only-module", importOnlyModules); - } - return yangPackage; - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackageGenerator.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackageGenerator.java deleted file mode 100644 index a6cfbef..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackageGenerator.java +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.yangpackage; - -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FilenameFilter; -import java.util.List; -import java.util.Properties; - -import org.onap.modeling.yangkit.compiler.YangCompiler; -import org.onap.modeling.yangkit.compiler.YangCompilerException; -import org.onap.modeling.yangkit.plugin.YangCompilerPlugin; -import org.onap.modeling.yangkit.plugin.YangCompilerPluginParameter; -import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; -import org.yangcentral.yangkit.model.api.stmt.Include; -import org.yangcentral.yangkit.model.api.stmt.MainModule; -import org.yangcentral.yangkit.model.api.stmt.Module; -import org.yangcentral.yangkit.model.api.stmt.SubModule; - - -public class YangPackageGenerator implements YangCompilerPlugin { - @Override - public YangCompilerPluginParameter getParameter(Properties compilerProps, String name, String value) - throws YangCompilerException { - if (!name.equals("complete") && !name.equals("meta") && !name.equals("output")) { - throw new YangCompilerException("unrecognized parameter:" + name); - } - if (name.equals("complete")) { - YangCompilerPluginParameter pluginParameter = new YangCompilerPluginParameter() { - @Override - public String getName() { - return name; - } - - @Override - public Object getValue() throws YangCompilerException { - return Boolean.valueOf(value); - } - }; - return pluginParameter; - } - return YangCompilerPlugin.super.getParameter(compilerProps, name, value); - } - - @Override - public void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, - List parameters) - throws YangCompilerException { - String output = null; - for (YangCompilerPluginParameter parameter : parameters) { - if (parameter.getName().equals("output")) { - output = (String) parameter.getValue(); - } else { - throw new YangCompilerException("unknown parameter:" + parameter.getName()); - } - } - if (output == null) { - throw new YangCompilerException("missing mandatory parameter:output"); - } - - File yangDir = yangCompiler.getYang(); - //search package_meta.json - File packageMetaFile = new File(yangDir, "package_meta.json"); - if (!packageMetaFile.exists()) { - throw new YangCompilerException("missing package_meta.json in directory:" + yangDir.getAbsolutePath()); - } - - try { - //parse yang package meta information - JsonElement element = JsonParser.parseReader(new FileReader(packageMetaFile)); - YangPackageMeta yangPackageMeta = new YangPackageMeta(); - yangPackageMeta.deserialize(element); - //set meta information for yang package - YangPackage yangPackage = new YangPackage(yangPackageMeta.getName(), yangPackageMeta.getRevision()); - yangPackage.setOrganization(yangPackageMeta.getOrganization()); - yangPackage.setContact(yangPackageMeta.getContact()); - yangPackage.setDescription(yangPackageMeta.getDescription()); - yangPackage.setReference(yangPackageMeta.getReference()); - yangPackage.setLocal(yangPackageMeta.isLocal()); - yangPackage.setTags(yangPackageMeta.getTags()); - yangPackage.setMandatoryFeatures(yangPackageMeta.getMandatoryFeatures()); - yangPackage.setIncludePackages(yangPackageMeta.getIncludePackages()); - if (schemaContext.getImportOnlyModules().isEmpty()) { - yangPackage.setComplete(true); - } - FilenameFilter packageMetaFilter = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - if (name.equals("package_meta.json")) { - return true; - } - return false; - } - }; - File[] metaFiles = yangDir.listFiles(packageMetaFilter); - List modules = schemaContext.getModules(); - for (Module module : modules) { - if (module instanceof MainModule) { - ModuleInfo moduleInfo = new ModuleInfo(module.getArgStr(), module.getCurRevisionDate().get()); - moduleInfo.setNamespace(((MainModule) module).getNamespace().getUri()); - if (!module.getIncludes().isEmpty()) { - for (Include include : module.getIncludes()) { - SubModule subModule = include.getInclude().get(); - SubModuleInfo subModuleInfo = - new SubModuleInfo(subModule.getArgStr(), subModule.getCurRevisionDate().get()); - moduleInfo.addSubModule(subModuleInfo); - } - } - yangPackage.addModule(moduleInfo); - } - } - for (Module importOnlyModule : schemaContext.getImportOnlyModules()) { - if (!(importOnlyModule instanceof MainModule)) { - continue; - } - ModuleInfo moduleInfo = - new ModuleInfo(importOnlyModule.getArgStr(), importOnlyModule.getCurRevisionDate().get()); - moduleInfo.setNamespace(((MainModule) importOnlyModule).getNamespace().getUri()); - if (!importOnlyModule.getIncludes().isEmpty()) { - for (Include include : importOnlyModule.getIncludes()) { - SubModule subModule = include.getInclude().get(); - SubModuleInfo subModuleInfo = - new SubModuleInfo(subModule.getArgStr(), subModule.getCurRevisionDate().get()); - moduleInfo.addSubModule(subModuleInfo); - } - } - yangPackage.addImportOnlyModule(moduleInfo); - } - - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackageMeta.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackageMeta.java deleted file mode 100644 index 40da4ba..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangpackage/YangPackageMeta.java +++ /dev/null @@ -1,187 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.yangpackage; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import java.util.ArrayList; -import java.util.List; - - -public class YangPackageMeta { - private String name; - private String revision; - private String organization; - private String contact; - private String description; - private String reference; - private boolean local; - private final List tags = new ArrayList<>(); - private final List mandatoryFeatures = new ArrayList<>(); - private final List includePackages = new ArrayList<>(); - - /** - * get the package name. - * @return name - */ - public String getName() { - return name; - } - - /** - * get revision of package. - * @return revision - */ - public String getRevision() { - return revision; - } - - /** - * get organization. - * @return organization. - */ - public String getOrganization() { - return organization; - } - - /** - * get contact. - * @return contact. - */ - public String getContact() { - return contact; - } - - /** - * get description. - * @return description. - */ - public String getDescription() { - return description; - } - - /** - * get reference. - * @return reference. - */ - public String getReference() { - return reference; - } - - /** - * whether the package is local. - * @return true or false - */ - public boolean isLocal() { - return local; - } - - /** - * get tags of package. - * @return list of tags. - */ - public List getTags() { - return tags; - } - - /** - * get mandatory features. - * @return list of features/ - */ - public List getMandatoryFeatures() { - return mandatoryFeatures; - } - - /** - * get include packages. - * @return list of packages. - */ - public List getIncludePackages() { - return includePackages; - } - - /** - * deserialized package meta from json. - * @param metaDoc json element - */ - public void deserialize(JsonElement metaDoc) { - JsonObject jsonObject = metaDoc.getAsJsonObject(); - JsonElement nameElement = jsonObject.get("name"); - if (nameElement != null) { - this.name = nameElement.getAsString(); - } - JsonElement versionElement = jsonObject.get("version"); - if (versionElement != null) { - this.revision = versionElement.getAsString(); - } - JsonElement organizationElement = jsonObject.get("organization"); - if (organizationElement != null) { - this.organization = organizationElement.getAsString(); - } - JsonElement contactElement = jsonObject.get("contact"); - if (contactElement != null) { - this.contact = contactElement.getAsString(); - } - JsonElement descElement = jsonObject.get("description"); - if (descElement != null) { - this.description = descElement.getAsString(); - } - JsonElement referElement = jsonObject.get("reference"); - if (referElement != null) { - this.reference = referElement.getAsString(); - } - - JsonElement localElement = jsonObject.get("local"); - if (localElement != null) { - this.local = referElement.getAsBoolean(); - } - JsonElement tagElement = jsonObject.get("tag"); - if (tagElement != null) { - JsonArray tagArray = tagElement.getAsJsonArray(); - int size = tagArray.size(); - for (int i = 0; i < size; i++) { - JsonElement tagIns = tagArray.get(i); - this.tags.add(tagIns.getAsString()); - } - } - - JsonElement mandatoryFeaturesElement = jsonObject.get("mandatory-feature"); - if (mandatoryFeaturesElement != null) { - JsonArray mandatoryFeaturesArray = mandatoryFeaturesElement.getAsJsonArray(); - int size = mandatoryFeaturesArray.size(); - for (int i = 0; i < size; i++) { - JsonElement featureIns = mandatoryFeaturesArray.get(i); - this.mandatoryFeatures.add(featureIns.getAsString()); - } - } - JsonElement includePackagesElement = jsonObject.get("include-package"); - if (includePackagesElement != null) { - JsonArray includePackageArray = includePackagesElement.getAsJsonArray(); - int size = includePackageArray.size(); - for (int i = 0; i < size; i++) { - JsonElement includePackageIns = includePackageArray.get(i); - JsonObject includePackageObj = includePackageIns.getAsJsonObject(); - PackageInfo packageInfo = new PackageInfo(includePackageObj.get("name").getAsString(), - includePackageObj.get("version").getAsString()); - this.includePackages.add(packageInfo); - } - } - - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangtree/GroupingSchemaNodeContainer.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangtree/GroupingSchemaNodeContainer.java deleted file mode 100644 index 67fd48d..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangtree/GroupingSchemaNodeContainer.java +++ /dev/null @@ -1,141 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.yangtree; - -import java.util.ArrayList; -import java.util.List; - -import org.yangcentral.yangkit.common.api.QName; -import org.yangcentral.yangkit.common.api.validate.ValidatorResult; -import org.yangcentral.yangkit.model.api.stmt.Action; -import org.yangcentral.yangkit.model.api.stmt.ActionContainer; -import org.yangcentral.yangkit.model.api.stmt.Augment; -import org.yangcentral.yangkit.model.api.stmt.DataDefContainer; -import org.yangcentral.yangkit.model.api.stmt.DataDefinition; -import org.yangcentral.yangkit.model.api.stmt.DataNode; -import org.yangcentral.yangkit.model.api.stmt.Grouping; -import org.yangcentral.yangkit.model.api.stmt.GroupingDefContainer; -import org.yangcentral.yangkit.model.api.stmt.Notification; -import org.yangcentral.yangkit.model.api.stmt.NotificationContainer; -import org.yangcentral.yangkit.model.api.stmt.SchemaNode; -import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer; -import org.yangcentral.yangkit.model.api.stmt.Uses; -import org.yangcentral.yangkit.model.api.stmt.YangStatement; - - -public class GroupingSchemaNodeContainer implements SchemaNodeContainer, GroupingDefContainer { - - private final YangStatement container; - - /** - * constructor. - * @param container schema node container - */ - public GroupingSchemaNodeContainer(YangStatement container) { - this.container = container; - } - - @Override - public List getGroupings() { - List groupings = new ArrayList<>(); - if (container instanceof GroupingDefContainer) { - groupings.addAll(((GroupingDefContainer) container).getGroupings()); - } - return groupings; - } - - @Override - public Grouping getGrouping(String name) { - return null; - } - - @Override - public List getSchemaNodeChildren() { - List schemaNodes = new ArrayList<>(); - if (container instanceof DataDefContainer) { - DataDefContainer dataDefContainer = (DataDefContainer) container; - for (DataDefinition dataDefinition : dataDefContainer.getDataDefChildren()) { - schemaNodes.add(dataDefinition); - } - } - - if (container instanceof ActionContainer) { - ActionContainer actionContainer = (ActionContainer) container; - for (Action action : actionContainer.getActions()) { - schemaNodes.add(action); - } - } - - if (container instanceof NotificationContainer) { - for (Notification notification : ((NotificationContainer) container).getNotifications()) { - schemaNodes.add(notification); - } - } - if (container instanceof Uses) { - for (Augment augment : ((Uses) container).getAugments()) { - schemaNodes.add(augment); - } - } - - return schemaNodes; - } - - @Override - public ValidatorResult addSchemaNodeChild(SchemaNode schemaNode) { - return null; - } - - @Override - public ValidatorResult addSchemaNodeChildren(List schemaNodes) { - return null; - } - - @Override - public SchemaNode getSchemaNodeChild(QName identifier) { - return null; - } - - @Override - public DataNode getDataNodeChild(QName identifier) { - return null; - } - - @Override - public List getDataNodeChildren() { - return null; - } - - @Override - public List getEffectiveSchemaNodeChildren(boolean ignoreNamespace) { - return null; - } - - @Override - public void removeSchemaNodeChild(QName identifier) { - - } - - @Override - public void removeSchemaNodeChild(SchemaNode schemaNode) { - - } - - @Override - public SchemaNode getMandatoryDescendant() { - return null; - } -} diff --git a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangtree/YangTreeGenerator.java b/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangtree/YangTreeGenerator.java deleted file mode 100644 index 45f7b94..0000000 --- a/yang-compiler/src/main/java/org/onap/modeling/yangkit/plugin/yangtree/YangTreeGenerator.java +++ /dev/null @@ -1,654 +0,0 @@ -/* -Copyright 2023 Huawei Technologies - -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. -*/ - -package org.onap.modeling.yangkit.plugin.yangtree; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import org.onap.modeling.yangkit.compiler.YangCompiler; -import org.onap.modeling.yangkit.compiler.YangCompilerException; -import org.onap.modeling.yangkit.plugin.YangCompilerPlugin; -import org.onap.modeling.yangkit.plugin.YangCompilerPluginParameter; -import org.yangcentral.yangkit.common.api.QName; -import org.yangcentral.yangkit.model.api.restriction.LeafRef; -import org.yangcentral.yangkit.model.api.schema.SchemaTreeType; -import org.yangcentral.yangkit.model.api.schema.YangSchemaContext; - -import org.yangcentral.yangkit.model.api.stmt.Action; -import org.yangcentral.yangkit.model.api.stmt.Anydata; -import org.yangcentral.yangkit.model.api.stmt.Anyxml; -import org.yangcentral.yangkit.model.api.stmt.Augment; -import org.yangcentral.yangkit.model.api.stmt.Case; -import org.yangcentral.yangkit.model.api.stmt.Choice; -import org.yangcentral.yangkit.model.api.stmt.Container; -import org.yangcentral.yangkit.model.api.stmt.DataDefinition; -import org.yangcentral.yangkit.model.api.stmt.Entity; -import org.yangcentral.yangkit.model.api.stmt.Grouping; -import org.yangcentral.yangkit.model.api.stmt.GroupingDefContainer; -import org.yangcentral.yangkit.model.api.stmt.IfFeature; -import org.yangcentral.yangkit.model.api.stmt.IfFeatureSupport; -import org.yangcentral.yangkit.model.api.stmt.Leaf; -import org.yangcentral.yangkit.model.api.stmt.MainModule; -import org.yangcentral.yangkit.model.api.stmt.Module; -import org.yangcentral.yangkit.model.api.stmt.MultiInstancesDataNode; -import org.yangcentral.yangkit.model.api.stmt.Notification; -import org.yangcentral.yangkit.model.api.stmt.Rpc; -import org.yangcentral.yangkit.model.api.stmt.SchemaDataNode; -import org.yangcentral.yangkit.model.api.stmt.SchemaNode; -import org.yangcentral.yangkit.model.api.stmt.SchemaNodeContainer; -import org.yangcentral.yangkit.model.api.stmt.Status; -import org.yangcentral.yangkit.model.api.stmt.TypedDataNode; -import org.yangcentral.yangkit.model.api.stmt.Uses; -import org.yangcentral.yangkit.model.api.stmt.YangList; -import org.yangcentral.yangkit.model.api.stmt.YangStatement; -import org.yangcentral.yangkit.model.api.stmt.YangUnknown; -import org.yangcentral.yangkit.model.api.stmt.ext.AugmentStructure; -import org.yangcentral.yangkit.model.api.stmt.ext.YangData; -import org.yangcentral.yangkit.model.api.stmt.ext.YangDataStructure; -import org.yangcentral.yangkit.utils.file.FileUtil; - - -public class YangTreeGenerator implements YangCompilerPlugin { - private int lineLength = 72; - private boolean expandGrouping = true; - private String output; - private static final String SPACE = " "; - private static final String TWO_SPACES = " "; - private static final String OFFSET = " "; - private static final String VERTICAL_OFFSET = "| "; - - /** - * build yang tree from module. - * @param module module - * @return yang tree string - */ - public String buildYangTree(Module module) { - StringBuilder sb = new StringBuilder(); - if (module instanceof MainModule) { - sb.append("module:"); - } else { - sb.append("submodule:"); - } - sb.append(SPACE); - sb.append(module.getArgStr()); - sb.append("\n"); - //data nodes - List dataDefs = module.getDataDefChildren(); - - //augments - List augments = module.getAugments(); - - - List yangDataList = module.getUnknowns( - new QName("urn:ietf:params:xml:ns:yang:ietf-restconf", "yang-data")); - - // yang structure extension - List yangStructureList = module.getUnknowns(YangDataStructure.YANG_KEYWORD); - - // augment structure extension - List augmentStructureList = module.getUnknowns(AugmentStructure.YANG_KEYWORD); - - if (!module.getGroupings().isEmpty() - && (!expandGrouping - || (module.getDataDefChildren().isEmpty() - && module.getRpcs().isEmpty() - && module.getNotifications().isEmpty() - && module.getAugments().isEmpty() - && yangDataList.isEmpty() - && yangStructureList.isEmpty() - && augmentStructureList.isEmpty()))) { - sb.append(buildGroupingContainer(module, TWO_SPACES)); - } - //data nodes - if (!dataDefs.isEmpty()) { - int size = dataDefs.size(); - boolean last = false; - for (int i = 0; i < size; i++) { - if (i == (size - 1)) { - last = true; - } - DataDefinition dataDefinition = dataDefs.get(i); - sb.append(buildYangTree(dataDefinition, last, TWO_SPACES, !expandGrouping)); - } - } - //augments - if (!augments.isEmpty()) { - for (Augment augment : augments) { - sb.append(buildAugmentRepresentation(augment, TWO_SPACES)); - sb.append(buildChildren(augment, TWO_SPACES + TWO_SPACES, !expandGrouping)); - } - } - //rpcs - List rpcs = module.getRpcs(); - if (!rpcs.isEmpty()) { - sb.append(TWO_SPACES); - sb.append("rpcs:\n"); - int size = rpcs.size(); - boolean last = false; - for (int i = 0; i < size; i++) { - if (i == (size - 1)) { - last = true; - } - Rpc rpc = rpcs.get(i); - sb.append(buildYangTree(rpc, last, TWO_SPACES + TWO_SPACES, !expandGrouping)); - } - } - //notifications - List notifications = module.getNotifications(); - if (!notifications.isEmpty()) { - sb.append(TWO_SPACES); - sb.append("notifications:\n"); - int size = notifications.size(); - boolean last = false; - for (int i = 0; i < size; i++) { - if (i == (size - 1)) { - last = true; - } - Notification notification = notifications.get(i); - sb.append(buildYangTree(notification, last, TWO_SPACES + TWO_SPACES, !expandGrouping)); - } - } - //yang data - if (!yangDataList.isEmpty()) { - for (YangUnknown unknown : yangDataList) { - YangData yangData = (YangData) unknown; - sb.append(TWO_SPACES); - sb.append("yang-data"); - sb.append(" "); - sb.append(yangData.getArgStr()); - sb.append(":\n"); - sb.append(buildChildren(yangData, TWO_SPACES + TWO_SPACES, !expandGrouping)); - } - } - //structures - if (!yangStructureList.isEmpty()) { - for (YangUnknown unknown : yangStructureList) { - YangDataStructure structure = (YangDataStructure) unknown; - sb.append(TWO_SPACES); - sb.append("structure"); - sb.append(" "); - sb.append(structure.getArgStr()); - sb.append(":\n"); - if (!expandGrouping) { - sb.append(buildGroupingContainer(structure, TWO_SPACES + TWO_SPACES)); - } - sb.append(buildChildren(structure, TWO_SPACES + TWO_SPACES, !expandGrouping)); - - } - } - //augment-structures - if (!augmentStructureList.isEmpty()) { - for (YangUnknown unknown : augmentStructureList) { - AugmentStructure augmentStructure = (AugmentStructure) unknown; - sb.append(TWO_SPACES); - sb.append("augment-structure"); - sb.append(" "); - sb.append(augmentStructure.getArgStr()); - sb.append(":\n"); - sb.append(buildChildren(augmentStructure, TWO_SPACES + TWO_SPACES, !expandGrouping)); - } - } - - return sb.toString(); - } - - private String buildYangTree(SchemaNode schemaNode, boolean last, String offSet, boolean grouping) { - StringBuilder sb = new StringBuilder(); - if (!grouping && (schemaNode instanceof Uses)) { - Uses uses = (Uses) schemaNode; - List schemaNodes = uses.getSchemaNodeChildren(); - for (int i = 0; i < schemaNodes.size(); i++) { - SchemaNode exSchemaNode = schemaNodes.get(i); - boolean subLast = last; - if (i != (schemaNodes.size() - 1)) { - subLast = false; - } - sb.append(buildYangTree(exSchemaNode, subLast, offSet, grouping)); - } - return sb.toString(); - } - if (schemaNode instanceof Augment) { - sb.append(buildAugmentRepresentation((Augment) schemaNode, offSet)); - } else { - sb.append(buildNodeRepresentation(schemaNode, offSet)); - } - if ((schemaNode instanceof GroupingDefContainer) && grouping) { - sb.append(buildGroupingContainer((GroupingDefContainer) schemaNode, offSet + TWO_SPACES)); - } - if (schemaNode instanceof SchemaNodeContainer) { - String childOffSet = offSet; - if (schemaNode instanceof Augment) { - childOffSet = childOffSet.concat(TWO_SPACES); - } else { - if (last) { - childOffSet = childOffSet.concat(OFFSET); - } else { - childOffSet = childOffSet.concat(VERTICAL_OFFSET); - } - } - - SchemaNodeContainer schemaNodeContainer; - if (!grouping) { - schemaNodeContainer = (SchemaNodeContainer) schemaNode; - } else { - schemaNodeContainer = new GroupingSchemaNodeContainer(schemaNode); - } - - sb.append(buildChildren(schemaNodeContainer, childOffSet, grouping)); - } - - return sb.toString(); - } - - private String buildGroupingContainer(GroupingDefContainer groupingDefContainer, String offSet) { - StringBuilder sb = new StringBuilder(); - //sb.append(offSet); - List groupings = groupingDefContainer.getGroupings(); - int size = groupings.size(); - for (int i = 0; i < size; i++) { - boolean last = false; - if (i == (size - 1)) { - last = true; - } - Grouping grouping = groupings.get(i); - sb.append(buildGrouping(grouping, last, offSet)); - } - return sb.toString(); - } - - private List getRealSchemaChildren(SchemaNodeContainer schemaNodeContainer, boolean grouping) { - List realSchemaNodeChildren = new ArrayList<>(); - - for (SchemaNode schemaChild : schemaNodeContainer.getSchemaNodeChildren()) { - if (schemaChild instanceof Augment) { - Augment augment = (Augment) schemaChild; - if (schemaNodeContainer instanceof SchemaNode) { - SchemaNode schemaNodeParent = (SchemaNode) schemaNodeContainer; - if (augment.getContext().getNamespace() != null && !augment.getContext().getNamespace() - .equals(schemaNodeParent.getContext().getNamespace())) { - continue; - } - } - if (!grouping) { - realSchemaNodeChildren.addAll(getRealSchemaChildren(augment, grouping)); - continue; - } - } - realSchemaNodeChildren.add(schemaChild); - } - return realSchemaNodeChildren; - } - - private String buildChildren(SchemaNodeContainer schemaNodeContainer, String offSet, boolean grouping) { - StringBuilder sb = new StringBuilder(); - List schemaNodeChildren = schemaNodeContainer.getSchemaNodeChildren(); - List realSchemaNodeChildren = getRealSchemaChildren(schemaNodeContainer, grouping); - - int size = realSchemaNodeChildren.size(); - for (int i = 0; i < size; i++) { - SchemaNode realSchemaNode = realSchemaNodeChildren.get(i); - boolean subLast = false; - if (i == (size - 1)) { - subLast = true; - } - sb.append(buildYangTree(realSchemaNode, subLast, offSet, grouping)); - - } - return sb.toString(); - } - - private String buildGrouping(Grouping grouping, boolean last, String offset) { - StringBuilder sb = new StringBuilder(); - sb.append(offset); - sb.append("grouping "); - sb.append(grouping.getArgStr()); - sb.append(":\n"); - GroupingSchemaNodeContainer groupingSchemaNodeContainer = new GroupingSchemaNodeContainer(grouping); - sb.append(buildGroupingContainer(grouping, offset + TWO_SPACES)); - sb.append(buildChildren(groupingSchemaNodeContainer, offset + TWO_SPACES, true)); - return sb.toString(); - } - - - - private String getStatus(YangStatement yangStatement) { - if (yangStatement instanceof Entity) { - Status status = ((Entity) yangStatement).getEffectiveStatus(); - switch (status) { - case CURRENT: { - return "+"; - } - case DEPRECATED: { - return "x"; - } - case OBSOLETE: { - return "o"; - } - default: - throw new IllegalStateException("Unexpected value: " + status); - } - } - return ""; - } - - private String getFlags(YangStatement yangStatement) { - String flags = ""; - if (yangStatement instanceof SchemaNode) { - SchemaNode schemaNode = (SchemaNode) yangStatement; - if (schemaNode instanceof Uses) { - flags = "-u"; - } else if ((schemaNode instanceof Rpc) || (schemaNode instanceof Action)) { - flags = "-x"; - } else if (schemaNode instanceof Notification) { - flags = "-n"; - } else if (schemaNode instanceof Case) { - flags = ""; - } else if (schemaNode.isConfig()) { - flags = "rw"; - } else { - flags = "ro"; - if (schemaNode.getSchemaTreeType() == SchemaTreeType.INPUTTREE) { - flags = "-w"; - } - } - - if (!schemaNode.getSubStatement(new QName("urn:ietf:params:xml:ns:yang:ietf-yang-schema-mount", - "mount-point")).isEmpty()) { - flags = "mp"; - } - } else if (yangStatement instanceof Grouping) { - flags = "rw"; - } - - return flags; - } - - private String getNodeName(YangStatement yangStatement) { - if (yangStatement instanceof Case) { - return ":(" + yangStatement.getArgStr() + ")"; - } else if (yangStatement instanceof Choice) { - return " (" + yangStatement.getArgStr() + ")"; - } else { - return " " + yangStatement.getArgStr(); - } - } - - private boolean isMandatory(SchemaDataNode dataNode) { - //key nodes - if (dataNode instanceof Leaf) { - SchemaNodeContainer parent = dataNode.getClosestAncestorNode(); - if (parent instanceof YangList) { - YangList list = (YangList) parent; - if (list.getKey().getKeyNode(dataNode.getIdentifier()) != null) { - return true; - } - } - } - return dataNode.isMandatory(); - } - - private String getOpts(YangStatement yangStatement) { - if ((yangStatement instanceof Leaf) - || (yangStatement instanceof Choice) - || (yangStatement instanceof Anydata) - || (yangStatement instanceof Anyxml)) { - if (!isMandatory((SchemaDataNode) yangStatement)) { - return "?"; - } - } else if (yangStatement instanceof Container) { - if (((Container) yangStatement).isPresence()) { - return "!"; - } - } else if (yangStatement instanceof MultiInstancesDataNode) { - StringBuilder sb = new StringBuilder("*"); - if (yangStatement instanceof YangList) { - YangList yangList = (YangList) yangStatement; - if (yangList.getKey() != null) { - sb.append(" ["); - sb.append(yangList.getKey().getArgStr()); - sb.append("]"); - } - } - return sb.toString(); - } - return ""; - } - - private String getType(TypedDataNode typedDataNode) { - if (typedDataNode.getType().getRestriction() instanceof LeafRef) { - LeafRef leafRef = (LeafRef) typedDataNode.getType().getRestriction(); - return "-> " + leafRef.getEffectivePath().getArgStr(); - } else { - return typedDataNode.getType().getArgStr(); - } - } - - private String getFeatures(IfFeatureSupport ifFeatureSupport) { - StringBuilder sb = new StringBuilder(); - List ifFeatures = ifFeatureSupport.getIfFeatures(); - if (!ifFeatures.isEmpty()) { - sb.append(" {"); - int size = ifFeatures.size(); - for (int i = 0; i < size; i++) { - IfFeature ifFeature = ifFeatures.get(i); - sb.append(ifFeature.getArgStr()); - if (i != (size - 1)) { - sb.append(","); - } - } - sb.append("}?"); - } - return sb.toString(); - } - - private String wrapLongPath(String offSet, String longPath) { - if ((offSet.length() + longPath.length()) <= lineLength) { - return offSet + longPath; - } - StringBuilder wrappedLine = new StringBuilder(offSet); - String firstCandidatePath = longPath.substring(0, lineLength - offSet.length()); - int index = firstCandidatePath.lastIndexOf("/"); - firstCandidatePath = firstCandidatePath.substring(0, index); - wrappedLine.append(firstCandidatePath); - wrappedLine.append("\n"); - String nextOffSet = offSet + " "; - String nextLongPath = longPath.substring(index); - wrappedLine.append(wrapLongPath(nextOffSet, nextLongPath)); - return wrappedLine.toString(); - } - - /** - * build augmentation representation string. - * @param augment augment - * @param offSet offset - * @return string - */ - public String buildAugmentRepresentation(Augment augment, String offSet) { - StringBuilder sb = new StringBuilder(offSet); - int beginIndex = sb.length(); - sb.append("augment"); - sb.append(" "); - int nameIndex = sb.length(); - sb.append(augment.getArgStr()); - sb.append(":\n"); - if (sb.length() > lineLength) { - String subString = sb.substring(0, lineLength); - int index = subString.lastIndexOf("/"); - StringBuilder newSb = new StringBuilder(); - String firstLine = sb.substring(0, index); - newSb.append(firstLine); - newSb.append("\n"); - newSb.append(offSet); - for (int i = beginIndex; i < (nameIndex + 2); i++) { - newSb.append(" "); - } - newSb.append(sb.substring(index)); - return newSb.toString(); - } - return sb.toString(); - } - - /** - * build a node representation from yang statement. - * @param yangStatement yang statement. - * @param offSet offset. - * @return string - */ - public String buildNodeRepresentation(YangStatement yangStatement, String offSet) { - StringBuilder sb = new StringBuilder(offSet); - int beginIndex = sb.length(); - //status - sb.append(getStatus(yangStatement)).append("--"); - //flags - sb.append(getFlags(yangStatement)); - //name - String name = getNodeName(yangStatement); - int nameIndex = sb.length(); - if (name.startsWith(" ")) { - nameIndex++; - } - sb.append(name); - sb.append(getOpts(yangStatement)); - - - if (yangStatement instanceof TypedDataNode) { - int typeIndex = sb.length(); - TypedDataNode typedDataNode = (TypedDataNode) yangStatement; - String type = getType(typedDataNode); - if (type.length() + typeIndex + 1 > lineLength) { - //change line - StringBuilder newLine = new StringBuilder(); - - StringBuilder newOffSet = new StringBuilder(offSet); - - for (int i = beginIndex; i < nameIndex + 2; i++) { - newOffSet.append(" "); - } - newLine.append(newOffSet); - newLine.append(type); - - if ((typedDataNode.getType().getRestriction() instanceof LeafRef) - && (newLine.length() > lineLength)) { - sb.append(" "); - sb.append("leafref"); - } else { - sb.append("\n"); - sb.append(newLine); - } - - - } else { - sb.append(" "); - sb.append(type); - } - } - - if (yangStatement instanceof IfFeatureSupport) { - IfFeatureSupport ifFeatureSupport = (IfFeatureSupport) yangStatement; - String features = getFeatures(ifFeatureSupport); - if (features.length() > 0) { - int ifFeatureIndex = sb.length(); - int lastCrIndex = sb.lastIndexOf("\n"); - if (lastCrIndex == -1) { - lastCrIndex = 0; - } - if (((ifFeatureIndex - lastCrIndex) + features.length()) > lineLength) { - //change line - sb.append("\n"); - sb.append(offSet); - for (int i = beginIndex; i < (nameIndex + 2); i++) { - sb.append(" "); - } - sb.append(features); - } else { - sb.append(" "); - sb.append(features); - } - } - - } - sb.append("\n"); - return sb.toString(); - } - - @Override - public YangCompilerPluginParameter getParameter(Properties compilerProps, String name, String value) - throws YangCompilerException { - if (!name.equals("output") && !name.equals("line-length") - && !name.equals("expand-grouping")) { - throw new YangCompilerException("unrecognized parameter:" + name); - } - if (name.equals("output")) { - return YangCompilerPlugin.super.getParameter(compilerProps, name, value); - } - YangCompilerPluginParameter yangCompilerPluginParameter = new YangCompilerPluginParameter() { - @Override - public String getName() { - return name; - } - - @Override - public Object getValue() { - - if (name.equals("line-length")) { - return Integer.parseInt(value); - } - - if (name.equals("expand-grouping")) { - return Boolean.valueOf(value); - } - return null; - } - - }; - return yangCompilerPluginParameter; - - - } - - @Override - public void run(YangSchemaContext schemaContext, YangCompiler yangCompiler, - List parameters) throws YangCompilerException { - for (YangCompilerPluginParameter parameter : parameters) { - if (parameter.getName().equals("output")) { - output = (String) parameter.getValue(); - } else if (parameter.getName().equals("line-length")) { - lineLength = (int) parameter.getValue(); - } else if (parameter.getName().equals("expand-grouping")) { - expandGrouping = (boolean) parameter.getValue(); - } - } - if (output == null) { - throw new YangCompilerException("missing mandatory parameter:output"); - } - File outputDir = new File(output); - if (!outputDir.exists()) { - outputDir.mkdirs(); - } - - List modules = schemaContext.getModules(); - for (Module module : modules) { - String yangTree = buildYangTree(module); - FileUtil.writeUtf8File(yangTree, new File(outputDir, - module.getArgStr() - + (module.getCurRevisionDate().isPresent() ? "@" + module.getCurRevisionDate().get() : "") - + "_tree.txt")); - } - } -} diff --git a/yang-compiler/src/main/resources/log4j.properties b/yang-compiler/src/main/resources/log4j.properties new file mode 100644 index 0000000..7fae67c --- /dev/null +++ b/yang-compiler/src/main/resources/log4j.properties @@ -0,0 +1,25 @@ +### settings### +log4j.rootLogger = debug,stdout,D,E + +### output to console ### +log4j.appender.stdout = org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target = System.out +log4j.appender.stdout.layout = org.apache.log4j.PatternLayout +log4j.appender.stdout.Threshold = INFO +log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} %m%n +### method:%l%n### +### ??DEBUG ????????=logs/debug.log ### +log4j.appender.D = org.apache.log4j.DailyRollingFileAppender +log4j.appender.D.File = logs/debug.log +log4j.appender.D.Append = true +log4j.appender.D.Threshold = DEBUG +log4j.appender.D.layout = org.apache.log4j.PatternLayout +log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n + +### ??ERROR ????????=logs/error.log ### +log4j.appender.E = org.apache.log4j.DailyRollingFileAppender +log4j.appender.E.File = logs/error.log +log4j.appender.E.Append = true +log4j.appender.E.Threshold = ERROR +log4j.appender.E.layout = org.apache.log4j.PatternLayout +log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n diff --git a/yang-compiler/src/main/resources/plugins.json b/yang-compiler/src/main/resources/plugins.json new file mode 100644 index 0000000..afd32f0 --- /dev/null +++ b/yang-compiler/src/main/resources/plugins.json @@ -0,0 +1,60 @@ +{ + "plugins": { + "plugin": [ + { + "name": "schema_validator", + "class-path": "", + "class": "org.yangcentral.yangkit.compiler.plugin.validator.YangValidator", + "description": "a plugin for validating yang files", + "parameter": [ + { + "name": "output", + "description": "the output directory." + } + ] + }, + { + "name": "yang_statistics", + "class-path": "", + "class": "org.yangcentral.yangkit.compiler.plugin.stat.YangStatistics", + "description": "a plugin for retrieving yang statistics", + "parameter": [ + { + "name": "output", + "description": "the output file." + } + ] + }, + { + "name": "yangtree_generator", + "class": "org.yangcentral.yangkit.compiler.plugin.yangtree.YangTreeGenerator", + "description": "a plugin for generating yang tree", + "parameter": [ + { + "name": "output", + "description": "the output directory for generated yang tree." + }, + { + "name": "line-length", + "description": "integer,default is 72, a line max length." + }, + { + "name": "expand-grouping", + "description": "boolean,default is true,indicate whether expand grouping" + } + ] + }, + { + "name": "yangpackage_generator", + "class": "org.yangcentral.yangkit.compiler.plugin.yangpackage.YangPackageGenerator", + "description": "a plugin for generating yang package", + "parameter": [ + { + "name": "output", + "description": "string, the file name(include parent path) of yang package instance." + } + ] + } + ] + } +} \ No newline at end of file diff --git a/yang-compiler/src/main/resources/yang-compiler.png b/yang-compiler/src/main/resources/yang-compiler.png new file mode 100644 index 0000000..2abbbb2 Binary files /dev/null and b/yang-compiler/src/main/resources/yang-compiler.png differ diff --git a/yang-compiler/src/main/resources/yc-build.yang b/yang-compiler/src/main/resources/yc-build.yang new file mode 100644 index 0000000..b8c2929 --- /dev/null +++ b/yang-compiler/src/main/resources/yc-build.yang @@ -0,0 +1,54 @@ +module yc-build { + namespace "urn:yangcentral:yang:yang-compiler-settings"; + prefix "ycs"; + yang-version "1.1"; + import ietf-inet { + prefix inet; + } + description "The definition about yang compiler settings."; + + revision 2022-09-02 { + description "init version."; + } + container yang { + leaf-list dir { + type string; + } + leaf-list file { + type string; + } + list module { + key "name revision"; + leaf name { + type string; + } + leaf revision { + type string; + } + leaf organization { + type string; + } + leaf schema { + type inet:uri; + } + } + } + leaf settings { + type string; + description "the path of settings file."; + } + list plugin { + key name; + leaf name { + type string; + } + list parameter { + key name; + leaf name { + type string; + } + anydata value; + } + } + +} \ No newline at end of file diff --git a/yang-compiler/src/main/resources/yc-yang-compiler-settings.yang b/yang-compiler/src/main/resources/yc-yang-compiler-settings.yang new file mode 100644 index 0000000..7fb3910 --- /dev/null +++ b/yang-compiler/src/main/resources/yc-yang-compiler-settings.yang @@ -0,0 +1,20 @@ +module yc-yang-compiler-settings { + namespace "urn:yangcentral:yang:yang-compiler-settings"; + prefix "ycs"; + import ietf-inet { + prefix inet; + } + description "The definition about yang compiler settings."; + + revision 2022-09-02 { + description "init version."; + } + + container settings { + leaf local-repository { + type string; + description "The definition of local repository. It should be a local directory. + if not present, the default is ${user.home}/.yang"; + } + } +} -- cgit 1.2.3-korg