1 package org.opendaylight.yangtools.yang.wadl.generator
3 import java.io.BufferedWriter
5 import java.io.OutputStreamWriter
6 import java.util.ArrayList
7 import java.util.HashSet
10 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
11 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
12 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
13 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
14 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
15 import org.opendaylight.yangtools.yang.model.api.Module
16 import org.opendaylight.yangtools.yang.model.api.SchemaContext
17 import org.sonatype.plexus.build.incremental.BuildContext
18 import org.sonatype.plexus.build.incremental.DefaultBuildContext
20 class WadlRestconfGenerator {
23 static val BuildContext CTX = new DefaultBuildContext();
24 var SchemaContext context;
25 var List<DataSchemaNode> configData;
26 var List<DataSchemaNode> operationalData;
28 var List<LeafSchemaNode> pathListParams;
29 val PATH_DELIMETER = "/"
31 new(File targetPath) {
32 if (!targetPath.exists) targetPath.mkdirs
36 def generate(SchemaContext context, Set<Module> modules) {
37 val result = new HashSet;
38 this.context = context
39 for (module : modules) {
40 val dataContainers = module.childNodes.filter[it|it instanceof ContainerSchemaNode || it instanceof ListSchemaNode]
41 if (!dataContainers.empty) {
42 configData = new ArrayList
43 operationalData = new ArrayList
45 for (data : dataContainers) {
46 if (data.configuration) {
49 operationalData.add(data)
54 val destination = new File(path, '''«module.name».wadl''')
55 val fw = new OutputStreamWriter(CTX.newFileOutputStream(destination))
56 val bw = new BufferedWriter(fw)
57 bw.append(application);
60 result.add(destination)
66 private def application() '''
68 <application xmlns="http://wadl.dev.java.net/2009/02" «module.importsAsNamespaces» xmlns:«module.prefix»="«module.namespace»">
76 private def importsAsNamespaces(Module module) '''
77 «FOR imprt : module.imports»
78 xmlns:«imprt.prefix»="«context.findModuleByName(imprt.moduleName, imprt.revision).namespace»"
82 private def grammars() '''
84 <include href="«module.name».yang"/>
85 «FOR imprt : module.imports»
86 <include href="«imprt.moduleName».yang"/>
91 private def resources() '''
92 <resources base="http://localhost:9998/restconf">
99 private def resourceOperational() '''
100 «IF !operationalData.nullOrEmpty»
101 <resource path="operational">
102 «FOR schemaNode : operationalData»
103 «schemaNode.firstResource(false)»
109 private def resourceConfig() '''
110 «IF !configData.nullOrEmpty»
111 <resource path="config">
112 «FOR schemaNode : configData»
113 «schemaNode.firstResource(true)»
119 private def resourceOperations() '''
120 «IF !module.rpcs.nullOrEmpty»
121 <resource path="operations">
122 «FOR rpc : module.rpcs»
123 <resource path="«module.name»:«rpc.QName.localName»">
124 «methodPostRpc(rpc.input != null, rpc.output !== null)»
131 private def String firstResource(DataSchemaNode schemaNode, boolean config) '''
132 <resource path="«module.name»:«schemaNode.createPath»">
133 «IF !pathListParams.nullOrEmpty»
136 «schemaNode.methodGet»
138 «schemaNode.mehodPut»
139 «schemaNode.mehodPost»
142 «IF schemaNode instanceof DataNodeContainer»
143 «val children = (schemaNode as DataNodeContainer).childNodes.filter[it|it instanceof ContainerSchemaNode || it instanceof ListSchemaNode]»
145 «FOR child : children»
146 «child.resource(config)»
153 private def String resource(DataSchemaNode schemaNode, boolean config) '''
154 <resource path="«schemaNode.createPath»">
155 «IF !pathListParams.nullOrEmpty»
158 «schemaNode.methodGet»
160 «schemaNode.mehodPut»
161 «schemaNode.mehodPost»
164 «IF schemaNode instanceof DataNodeContainer»
165 «val children = (schemaNode as DataNodeContainer).childNodes.filter[it|it instanceof ContainerSchemaNode || it instanceof ListSchemaNode]»
167 «FOR child : children»
168 «child.resource(config)»
175 private def String createPath(DataSchemaNode schemaNode) {
176 pathListParams = new ArrayList
177 var StringBuilder path = new StringBuilder
178 path.append(schemaNode.QName.localName)
179 if (schemaNode instanceof ListSchemaNode) {
180 val listKeys = (schemaNode as ListSchemaNode).keyDefinition
181 for (listKey : listKeys) {
182 pathListParams.add((schemaNode as DataNodeContainer).getDataChildByName(listKey) as LeafSchemaNode)
183 path.append(PATH_DELIMETER + "{" + listKey.localName + "}")
189 private def resourceParams() '''
190 «FOR pathParam : pathListParams»
191 «val prefix = pathParam.type.QName.prefix»
192 «val type = if (prefix.nullOrEmpty) pathParam.type.QName.localName else prefix + ":" + pathParam.type.QName.localName»
193 <param required="true" style="template" name="«pathParam.QName.localName»" type="«type»"/>
197 private def methodGet(DataSchemaNode schemaNode) '''
200 <representation mediaType="application/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
201 <representation mediaType="text/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
202 <representation mediaType="application/json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
203 <representation mediaType="application/yang.data+xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
204 <representation mediaType="application/yang.data+json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
209 private def mehodPut(DataSchemaNode schemaNode) '''
212 <representation mediaType="application/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
213 <representation mediaType="text/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
214 <representation mediaType="application/json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
215 <representation mediaType="application/yang.data+xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
216 <representation mediaType="application/yang.data+json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
221 private def mehodPost(DataSchemaNode schemaNode) '''
224 <representation mediaType="application/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
225 <representation mediaType="text/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
226 <representation mediaType="application/json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
227 <representation mediaType="application/yang.data+xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
228 <representation mediaType="application/yang.data+json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
233 private def methodPostRpc(boolean input, boolean output) '''
237 <representation mediaType="application/xml" element="input"/>
238 <representation mediaType="text/xml" element="input"/>
239 <representation mediaType="application/json" element="input"/>
240 <representation mediaType="application/yang.data+xml" element="input"/>
241 <representation mediaType="application/yang.data+json" element="input"/>
246 <representation mediaType="application/xml" element="output"/>
247 <representation mediaType="text/xml" element="output"/>
248 <representation mediaType="application/json" element="output"/>
249 <representation mediaType="application/yang.data+xml" element="output"/>
250 <representation mediaType="application/yang.data+json" element="output"/>