*/
package org.opendaylight.mdsal.binding.yang.wadl.generator;
-import static com.google.common.base.Preconditions.checkState;
-import static java.util.Objects.requireNonNull;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Map;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.collect.Table;
import java.util.Set;
+import org.opendaylight.yangtools.plugin.generator.api.FileGenerator;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFile;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileLifecycle;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFilePath;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileType;
+import org.opendaylight.yangtools.plugin.generator.api.ModuleResourceResolver;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.model.api.Module;
-import org.opendaylight.yangtools.yang2sources.spi.BasicCodeGenerator;
-import org.opendaylight.yangtools.yang2sources.spi.BuildContextAware;
-import org.opendaylight.yangtools.yang2sources.spi.ModuleResourceResolver;
-import org.sonatype.plexus.build.incremental.BuildContext;
-
-public class WadlGenerator implements BasicCodeGenerator, BuildContextAware {
- private BuildContext buildContext;
-
- @Override
- public void setAdditionalConfig(final Map<String, String> additionalConfiguration) {
- // No-op
- }
-
- @Override
- public void setBuildContext(final BuildContext buildContext) {
- this.buildContext = requireNonNull(buildContext);
- }
-
- @Override
- public void setResourceBaseDir(final File resourceBaseDir) {
- // No-op
- }
+final class WadlGenerator implements FileGenerator {
@Override
- public Collection<File> generateSources(final EffectiveModelContext context, final File outputBaseDir,
- final Set<Module> currentModules, final ModuleResourceResolver moduleResourcePathResolver)
- throws IOException {
- final File outputDir;
- if (outputBaseDir == null) {
- // FIXME: this hard-codes the destination
- outputDir = new File("target" + File.separator + "generated-sources" + File.separator
- + "maven-sal-api-gen" + File.separator + "wadl");
- } else {
- outputDir = outputBaseDir;
+ public Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> generateFiles(final EffectiveModelContext context,
+ final Set<Module> localModules, final ModuleResourceResolver moduleResourcePathResolver) {
+ final var result = ImmutableTable.<GeneratedFileType, GeneratedFilePath, GeneratedFile>builder();
+
+ for (Module module : localModules) {
+ final CharSequence body = new WadlTemplate(context, module).body();
+ if (body != null) {
+ result.put(GeneratedFileType.RESOURCE, GeneratedFilePath.ofPath(module.getName() + ".wadl"),
+ GeneratedFile.of(GeneratedFileLifecycle.TRANSIENT, body));
+ }
}
-
- checkState(buildContext != null, "BuildContext should have been set");
- return new WadlRestconfGenerator(buildContext, outputDir).generate(context, currentModules);
+ return result.build();
}
}
--- /dev/null
+/*
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
+ *
+ * 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 java.util.Map;
+import org.kohsuke.MetaInfServices;
+import org.opendaylight.yangtools.plugin.generator.api.AbstractFileGeneratorFactory;
+import org.opendaylight.yangtools.plugin.generator.api.FileGenerator;
+import org.opendaylight.yangtools.plugin.generator.api.FileGeneratorFactory;
+
+@MetaInfServices(value = FileGeneratorFactory.class)
+public final class WadlGeneratorFactory extends AbstractFileGeneratorFactory {
+ public WadlGeneratorFactory() {
+ super(WadlGenerator.class.getName());
+ }
+
+ @Override
+ public FileGenerator newFileGenerator(final Map<String, String> configuration) {
+ return new WadlGenerator();
+ }
+}
/*
* 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,
*/
package org.opendaylight.mdsal.binding.yang.wadl.generator
-import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import java.io.BufferedWriter
-import java.io.File
-import java.io.IOException
-import java.io.OutputStreamWriter
-import java.nio.charset.StandardCharsets
import java.util.ArrayList
-import java.util.Collection
-import java.util.HashSet
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.LeafSchemaNode
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
import org.opendaylight.yangtools.yang.model.api.Module
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
-import org.sonatype.plexus.build.incremental.BuildContext
-
-class WadlRestconfGenerator {
-
- static val Logger LOG = LoggerFactory.getLogger(WadlRestconfGenerator)
+final class WadlTemplate {
static val PATH_DELIMETER = '/'
- val BuildContext buildContext;
- val File path
- var EffectiveModelContext context;
- var List<DataSchemaNode> configData;
- var List<DataSchemaNode> operationalData;
- var Module module;
- var List<LeafSchemaNode> pathListParams;
- new(BuildContext buildContext, File targetPath) {
- if (!targetPath.exists) {
- checkState(targetPath.mkdirs, "Unable to create directory: %s", targetPath);
- }
- path = targetPath
- this.buildContext = buildContext
- }
+ val EffectiveModelContext context
+ val Module module
+ val List<DataSchemaNode> configData = new ArrayList
+ val List<DataSchemaNode> operationalData = new ArrayList
- def generate(EffectiveModelContext context, Collection<? extends Module> modules) {
- val result = new HashSet;
- this.context = context
- for (module : modules) {
- val dataContainers = module.childNodes.filter[it|it.listOrContainer]
- if (!dataContainers.empty || !module.rpcs.nullOrEmpty) {
- configData = new ArrayList
- operationalData = new ArrayList
+ var List<LeafSchemaNode> pathListParams
- for (data : dataContainers) {
- if (data.configuration) {
- configData.add(data)
- } else {
- operationalData.add(data)
- }
- }
+ new(EffectiveModelContext context, Module module) {
+ this.context = requireNonNull(context)
+ this.module = requireNonNull(module)
- this.module = module
- val destination = new File(path, '''«module.name».wadl''')
- var OutputStreamWriter fw
- var BufferedWriter bw
- try {
- fw = new OutputStreamWriter(buildContext.newFileOutputStream(destination), StandardCharsets.UTF_8)
- bw = new BufferedWriter(fw)
- bw.append(application);
- } catch (IOException e) {
- LOG.error("Failed to emit file {}", destination, e);
- } finally {
- if (bw !== null) {
- bw.close();
- }
- if (fw !== null) {
- fw.close();
- }
+ for (child : module.childNodes) {
+ if (child instanceof ContainerSchemaNode || child instanceof ListSchemaNode) {
+ if (child.configuration) {
+ configData.add(child)
+ } else {
+ operationalData.add(child)
}
- result.add(destination)
}
}
- return result
+ }
+
+ def body() {
+ if (!module.rpcs.empty || !configData.empty || !operationalData.empty) {
+ return application()
+ }
+ return null
}
private def application() '''
if (schemaNode instanceof ListSchemaNode) {
for (listKey : schemaNode.keyDefinition) {
pathListParams.add((schemaNode as DataNodeContainer).getDataChildByName(listKey) as LeafSchemaNode)
- path.append(PATH_DELIMETER)
- path.append('{')
- path.append(listKey.localName)
- path.append('}')
+ path.append(PATH_DELIMETER).append('{').append(listKey.localName).append('}')
}
}
return path.toString
«val children = (schemaNode as DataNodeContainer).childNodes.filter[it|it.listOrContainer]»
«IF config»
«schemaNode.methodDelete»
- «schemaNode.mehodPut»
+ «schemaNode.methodPut»
«FOR child : children»
«child.mehodPost»
«ENDFOR»
«ENDFOR»
'''
- private def methodGet(DataSchemaNode schemaNode) '''
+ private static def methodGet(DataSchemaNode schemaNode) '''
<method name="GET">
<response>
«representation(schemaNode.QName.namespace, schemaNode.QName.localName)»
</method>
'''
- private def mehodPut(DataSchemaNode schemaNode) '''
+ private static def methodPut(DataSchemaNode schemaNode) '''
<method name="PUT">
<request>
«representation(schemaNode.QName.namespace, schemaNode.QName.localName)»
</method>
'''
- private def mehodPost(DataSchemaNode schemaNode) '''
+ private static def mehodPost(DataSchemaNode schemaNode) '''
<method name="POST">
<request>
«representation(schemaNode.QName.namespace, schemaNode.QName.localName)»
</method>
'''
- private def methodPostRpc(boolean input, boolean output) '''
+ private static def methodPostRpc(boolean input, boolean output) '''
<method name="POST">
«IF input»
<request>
</method>
'''
- private def methodDelete(DataSchemaNode schemaNode) '''
+ private static def methodDelete(DataSchemaNode schemaNode) '''
<method name="DELETE" />
'''
- private def representation(XMLNamespace prefix, String name) '''
+ private static def representation(XMLNamespace prefix, String name) '''
«val elementData = name»
<representation mediaType="application/xml" element="«elementData»"/>
<representation mediaType="text/xml" element="«elementData»"/>
@SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
justification = "https://github.com/spotbugs/spotbugs/issues/811")
- private def boolean isListOrContainer(DataSchemaNode schemaNode) {
- return (schemaNode instanceof ListSchemaNode || schemaNode instanceof ContainerSchemaNode)
+ private static def boolean isListOrContainer(DataSchemaNode schemaNode) {
+ return schemaNode instanceof ListSchemaNode || schemaNode instanceof ContainerSchemaNode
}
-
}
package org.opendaylight.mdsal.binding.yang.wadl.generator;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
+import com.google.common.collect.Table;
import java.util.Optional;
import java.util.Set;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFile;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFilePath;
+import org.opendaylight.yangtools.plugin.generator.api.GeneratedFileType;
import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
-import org.sonatype.plexus.build.incremental.DefaultBuildContext;
public class WadlGenTest {
-
- private static final String FS = File.separator;
- private static final String TEST_PATH = "target" + FS + "test" + FS + "site";
- private static final File GENERATOR_OUTPUT_DIR = new File(TEST_PATH);
-
- @Before
- public void init() {
- if (GENERATOR_OUTPUT_DIR.exists()) {
- deleteTestDir(GENERATOR_OUTPUT_DIR);
- }
- assertTrue(GENERATOR_OUTPUT_DIR.mkdirs());
- }
-
- @After
- public void cleanUp() {
- if (GENERATOR_OUTPUT_DIR.exists()) {
- deleteTestDir(GENERATOR_OUTPUT_DIR);
- }
- }
-
@Test
- public void testListGeneration() throws Exception {
- final List<File> sourceFiles = getSourceFiles("/wadl-gen");
- final EffectiveModelContext context = YangParserTestUtils.parseYangFiles(sourceFiles);
+ public void testListGeneration() {
final WadlGenerator generator = new WadlGenerator();
- generator.setBuildContext(new DefaultBuildContext());
- Collection<File> generatedWadlFiles = generator.generateSources(context, GENERATOR_OUTPUT_DIR,
+ final EffectiveModelContext context = YangParserTestUtils.parseYangResourceDirectory("/wadl-gen");
+ Table<GeneratedFileType, GeneratedFilePath, GeneratedFile> generatedWadlFiles = generator.generateFiles(context,
Set.copyOf(context.getModules()), (module, representation) -> Optional.empty());
assertEquals(3, generatedWadlFiles.size());
- generatedWadlFiles.forEach(file -> assertTrue(file.exists()));
- }
-
- @Test
- public void testListGenerationWithoutPath() throws Exception {
- final List<File> sourceFiles = getSourceFiles("/wadl-gen");
- final EffectiveModelContext context = YangParserTestUtils.parseYangFiles(sourceFiles);
- final WadlGenerator generator = new WadlGenerator();
- generator.setBuildContext(new DefaultBuildContext());
- Collection<File> generatedWadlFiles = generator.generateSources(context, null, Set.copyOf(context.getModules()),
- (module, representation) -> Optional.empty());
- assertEquals(3, generatedWadlFiles.size());
- generatedWadlFiles.forEach(file -> {
- deleteTestDir(file);
- assertFalse(file.exists());
- });
- }
-
- private static List<File> getSourceFiles(final String path) throws Exception {
- final URI resPath = WadlGenTest.class.getResource(path).toURI();
- final File sourcesDir = new File(resPath);
- if (!sourcesDir.exists()) {
- throw new FileNotFoundException("Testing files were not found(" + sourcesDir.getName() + ")");
- }
- final List<File> sourceFiles = new ArrayList<>();
- final File[] fileArray = sourcesDir.listFiles();
- if (fileArray == null) {
- throw new IllegalArgumentException("Unable to locate files in " + sourcesDir);
- }
- sourceFiles.addAll(Arrays.asList(fileArray));
- return sourceFiles;
- }
-
- private static void deleteTestDir(final File file) {
- if (file.isDirectory()) {
- File[] filesToDelete = file.listFiles();
- if (filesToDelete != null) {
- for (File f : filesToDelete) {
- deleteTestDir(f);
- }
- }
- }
- if (!file.delete()) {
- throw new RuntimeException("Failed to clean up after test");
- }
+ // TODO: more asserts
}
}