2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.mdsal.binding.yang.wadl.generator
10 import java.io.BufferedWriter
12 import java.io.OutputStreamWriter
14 import java.nio.charset.StandardCharsets
15 import java.util.ArrayList
16 import java.util.HashSet
19 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
20 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
21 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
22 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext
23 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
24 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
25 import org.opendaylight.yangtools.yang.model.api.Module
26 import org.sonatype.plexus.build.incremental.BuildContext
28 class WadlRestconfGenerator {
30 static val PATH_DELIMETER = '/'
31 val BuildContext buildContext;
33 var EffectiveModelContext context;
34 var List<DataSchemaNode> configData;
35 var List<DataSchemaNode> operationalData;
37 var List<LeafSchemaNode> pathListParams;
39 new(BuildContext buildContext, File targetPath) {
40 if (!targetPath.exists) targetPath.mkdirs
42 this.buildContext = buildContext
45 def generate(EffectiveModelContext context, Set<Module> modules) {
46 val result = new HashSet;
47 this.context = context
48 for (module : modules) {
49 val dataContainers = module.childNodes.filter[it|it.listOrContainer]
50 if (!dataContainers.empty || !module.rpcs.nullOrEmpty) {
51 configData = new ArrayList
52 operationalData = new ArrayList
54 for (data : dataContainers) {
55 if (data.configuration) {
58 operationalData.add(data)
63 val destination = new File(path, '''«module.name».wadl''')
64 val fw = new OutputStreamWriter(buildContext.newFileOutputStream(destination), StandardCharsets.UTF_8)
65 val bw = new BufferedWriter(fw)
66 bw.append(application);
69 result.add(destination)
75 private def application() '''
77 <application xmlns="http://wadl.dev.java.net/2009/02" «module.importsAsNamespaces» xmlns:«module.prefix»="«module.namespace»">
85 private def importsAsNamespaces(Module module) '''
86 «FOR imprt : module.imports»
87 xmlns:«imprt.prefix»="«context.findModule(imprt.moduleName, imprt.revision).get.namespace»"
91 private def grammars() '''
93 <include href="«module.name».yang"/>
94 «FOR imprt : module.imports»
95 <include href="«imprt.moduleName».yang"/>
100 private def resources() '''
101 <resources base="http://localhost:9998/restconf">
102 «resourceOperational»
108 private def resourceOperational() '''
109 «IF !operationalData.nullOrEmpty»
110 <resource path="operational">
111 «FOR schemaNode : operationalData»
112 «schemaNode.firstResource(false)»
118 private def resourceConfig() '''
119 «IF !configData.nullOrEmpty»
120 <resource path="config">
121 «FOR schemaNode : configData»
122 «schemaNode.mehodPost»
124 «FOR schemaNode : configData»
125 «schemaNode.firstResource(true)»
131 private def resourceOperations() '''
132 «IF !module.rpcs.nullOrEmpty»
133 <resource path="operations">
134 «FOR rpc : module.rpcs»
135 <resource path="«module.name»:«rpc.QName.localName»">
136 «methodPostRpc(rpc.input !== null, rpc.output !== null)»
143 private def String firstResource(DataSchemaNode schemaNode, boolean config) '''
144 <resource path="«module.name»:«schemaNode.createPath»">
145 «resourceBody(schemaNode, config)»
149 private def String resource(DataSchemaNode schemaNode, boolean config) '''
150 <resource path="«schemaNode.createPath»">
151 «resourceBody(schemaNode, config)»
155 private def String createPath(DataSchemaNode schemaNode) {
156 pathListParams = new ArrayList
157 var StringBuilder path = new StringBuilder
158 path.append(schemaNode.QName.localName)
159 if (schemaNode instanceof ListSchemaNode) {
160 for (listKey : schemaNode.keyDefinition) {
161 pathListParams.add((schemaNode as DataNodeContainer).getDataChildByName(listKey) as LeafSchemaNode)
162 path.append(PATH_DELIMETER)
164 path.append(listKey.localName)
171 private def String resourceBody(DataSchemaNode schemaNode, boolean config) '''
172 «IF !pathListParams.nullOrEmpty»
175 «schemaNode.methodGet»
176 «val children = (schemaNode as DataNodeContainer).childNodes.filter[it|it.listOrContainer]»
178 «schemaNode.methodDelete»
179 «schemaNode.mehodPut»
180 «FOR child : children»
184 «FOR child : children»
185 «child.resource(config)»
189 private def resourceParams() '''
190 «FOR pathParam : pathListParams»
191 «IF pathParam !== null»
192 «val type = pathParam.type.QName.localName»
193 <param required="true" style="template" name="«pathParam.QName.localName»" type="«type»"/>
198 private def methodGet(DataSchemaNode schemaNode) '''
201 «representation(schemaNode.QName.namespace, schemaNode.QName.localName)»
206 private def mehodPut(DataSchemaNode schemaNode) '''
209 «representation(schemaNode.QName.namespace, schemaNode.QName.localName)»
214 private def mehodPost(DataSchemaNode schemaNode) '''
217 «representation(schemaNode.QName.namespace, schemaNode.QName.localName)»
222 private def methodPostRpc(boolean input, boolean output) '''
226 «representation(null, "input")»
231 «representation(null, "output")»
237 private def methodDelete(DataSchemaNode schemaNode) '''
238 <method name="DELETE" />
241 private def representation(URI prefix, String name) '''
242 «val elementData = name»
243 <representation mediaType="application/xml" element="«elementData»"/>
244 <representation mediaType="text/xml" element="«elementData»"/>
245 <representation mediaType="application/json" element="«elementData»"/>
246 <representation mediaType="application/yang.data+xml" element="«elementData»"/>
247 <representation mediaType="application/yang.data+json" element="«elementData»"/>
250 private def boolean isListOrContainer(DataSchemaNode schemaNode) {
251 return (schemaNode instanceof ListSchemaNode || schemaNode instanceof ContainerSchemaNode)