/* * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * Copyright (c) 2021 PANTHEON.tech, s.r.o. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.mdsal.binding.yang.wadl.generator import static java.util.Objects.requireNonNull import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.ArrayList import java.util.List import org.opendaylight.yangtools.yang.common.XMLNamespace import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode import org.opendaylight.yangtools.yang.model.api.DataNodeContainer import org.opendaylight.yangtools.yang.model.api.DataSchemaNode import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode import org.opendaylight.yangtools.yang.model.api.ListSchemaNode import org.opendaylight.yangtools.yang.model.api.Module final class WadlTemplate { static val PATH_DELIMETER = '/' val EffectiveModelContext context val Module module val List configData = new ArrayList val List operationalData = new ArrayList var List pathListParams new(EffectiveModelContext context, Module module) { this.context = requireNonNull(context) this.module = requireNonNull(module) for (child : module.childNodes) { if (child instanceof ContainerSchemaNode || child instanceof ListSchemaNode) { if (child.configuration) { configData.add(child) } else { operationalData.add(child) } } } } def body() { if (!module.rpcs.empty || !configData.empty || !operationalData.empty) { return application() } return null } private def application() ''' «FOR imprt : module.imports» «ENDFOR» «IF !operationalData.nullOrEmpty» «FOR schemaNode : operationalData» «schemaNode.firstResource(false)» «ENDFOR» «ENDIF» «IF !configData.nullOrEmpty» «FOR schemaNode : configData» «schemaNode.mehodPost» «ENDFOR» «FOR schemaNode : configData» «schemaNode.firstResource(true)» «ENDFOR» «ENDIF» «IF !module.rpcs.nullOrEmpty» «FOR rpc : module.rpcs» «methodPostRpc(rpc.input !== null, rpc.output !== null)» «ENDFOR» «ENDIF» ''' private def importsAsNamespaces(Module module) ''' «FOR imprt : module.imports» xmlns:«imprt.prefix»="«context.findModule(imprt.moduleName, imprt.revision).get.namespace»" «ENDFOR» ''' private def String firstResource(DataSchemaNode schemaNode, boolean config) ''' «resourceBody(schemaNode, config)» ''' private def String resource(DataSchemaNode schemaNode, boolean config) ''' «resourceBody(schemaNode, config)» ''' private def String createPath(DataSchemaNode schemaNode) { pathListParams = new ArrayList var StringBuilder path = new StringBuilder path.append(schemaNode.QName.localName) if (schemaNode instanceof ListSchemaNode) { for (listKey : schemaNode.keyDefinition) { pathListParams.add((schemaNode as DataNodeContainer).getDataChildByName(listKey) as LeafSchemaNode) path.append(PATH_DELIMETER).append('{').append(listKey.localName).append('}') } } return path.toString } private def String resourceBody(DataSchemaNode schemaNode, boolean config) ''' «IF !pathListParams.nullOrEmpty» «resourceParams» «ENDIF» «schemaNode.methodGet» «val children = (schemaNode as DataNodeContainer).childNodes.filter[it|it.listOrContainer]» «IF config» «schemaNode.methodDelete» «schemaNode.methodPut» «FOR child : children» «child.mehodPost» «ENDFOR» «ENDIF» «FOR child : children» «child.resource(config)» «ENDFOR» ''' private def resourceParams() ''' «FOR pathParam : pathListParams» «IF pathParam !== null» «val type = pathParam.type.QName.localName» «ENDIF» «ENDFOR» ''' private static def methodGet(DataSchemaNode schemaNode) ''' «representation(schemaNode.QName.namespace, schemaNode.QName.localName)» ''' private static def methodPut(DataSchemaNode schemaNode) ''' «representation(schemaNode.QName.namespace, schemaNode.QName.localName)» ''' private static def mehodPost(DataSchemaNode schemaNode) ''' «representation(schemaNode.QName.namespace, schemaNode.QName.localName)» ''' private static def methodPostRpc(boolean input, boolean output) ''' «IF input» «representation(null, "input")» «ENDIF» «IF output» «representation(null, "output")» «ENDIF» ''' private static def methodDelete(DataSchemaNode schemaNode) ''' ''' private static def representation(XMLNamespace prefix, String name) ''' «val elementData = name» ''' @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD", justification = "https://github.com/spotbugs/spotbugs/issues/811") private static def boolean isListOrContainer(DataSchemaNode schemaNode) { return schemaNode instanceof ListSchemaNode || schemaNode instanceof ContainerSchemaNode } }