writer.write(NL);
for (GeneratedProperty field : fields) {
writer.write(GeneratorUtil.createGetter(field, TAB) + NL);
+ if (!field.isReadOnly()) {
+ writer.write(GeneratorUtil.createSetter(field, TAB) + NL);
+ }
}
writer.write(NL);
+
+ if (!genTO.getHashCodeIdentifiers().isEmpty()) {
+ writer.write(GeneratorUtil.createHashCode(
+ genTO.getHashCodeIdentifiers(), TAB)
+ + NL);
+ }
+
+ if (!genTO.getEqualsIdentifiers().isEmpty()) {
+ writer.write(GeneratorUtil.createEquals(genTO,
+ genTO.getEqualsIdentifiers(), TAB)
+ + NL);
+ }
+
+ if (!genTO.getToStringIdentifiers().isEmpty()) {
+ writer.write(GeneratorUtil.createToString(genTO,
+ genTO.getToStringIdentifiers(), TAB)
+ + NL);
- writer.write(GeneratorUtil.createHashCode(
- genTO.getHashCodeIdentifiers(), TAB)
- + NL);
- writer.write(GeneratorUtil.createEquals(genTO,
- genTO.getEqualsIdentifiers(), TAB)
- + NL);
- writer.write(GeneratorUtil.createToString(genTO,
- genTO.getToStringIdentifiers(), TAB)
- + NL);
-
+ }
+
writer.write(RCB);
}
}
-/*\r
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-package org.opendaylight.controller.sal.java.api.generator;\r
-\r
-public class Constants {\r
-\r
- public static final String IFC = "interface";\r
- public static final String CLASS = "class";\r
- public static final String PKG = "package";\r
- public static final String ENUM = "enum";\r
-\r
- public static final String LCB = "{";\r
- public static final String RCB = "}";\r
-\r
- public static final String LB = "(";\r
- public static final String RB = ")";\r
-\r
- public static final String GAP = " ";\r
- public static final String COMMA = ",";\r
- public static final String NL = "\n";\r
- public static final String SC = ";";\r
- public static final String TAB = "\t";\r
-\r
- public static final String PUBLIC = "public";\r
- public static final String PRIVATE = "private";\r
- public static final String STATIC = "static";\r
- public static final String FINAL = "final";\r
-\r
-}\r
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. 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.controller.sal.java.api.generator;
+
+public class Constants {
+
+ public static final String IFC = "interface";
+ public static final String CLASS = "class";
+ public static final String PKG = "package";
+ public static final String ENUM = "enum";
+
+ public static final String LCB = "{";
+ public static final String RCB = "}";
+
+ public static final String LB = "(";
+ public static final String RB = ")";
+
+ public static final String GAP = " ";
+ public static final String COMMA = ",";
+ public static final String NL = "\n";
+ public static final String SC = ";";
+ public static final String TAB = "\t";
+
+ public static final String PUBLIC = "public";
+ public static final String PRIVATE = "private";
+ public static final String STATIC = "static";
+ public static final String FINAL = "final";
+ public static final String EXTENDS = "extends";
+ public static final String IMPLEMENTS = "implements";
+}
return result;
}
- public List<File> generateToFile(final File directory) throws IOException {
+ public List<File> generateToFile(final File parentDirectory) throws IOException {
final List<File> result = new ArrayList<File>();
for (GeneratedType type : genTypes) {
- final File genFile = generateTypeToJavaFile(directory, type,
+ final File genFile = generateTypeToJavaFile(parentDirectory, type,
interfaceGenerator);
if (genFile != null) {
}
}
for (GeneratedTransferObject transferObject : genTransferObjects) {
- final File genFile = generateTypeToJavaFile(directory,
+ final File genFile = generateTypeToJavaFile(parentDirectory,
transferObject, classGenerator);
if (genFile != null) {
return result;
}
- private File generateTypeToJavaFile(final File directory, final Type type,
+ private File generateTypeToJavaFile(final File parentDir, final Type type,
final CodeGenerator generator) throws IOException {
- if ((directory != null) && (type != null) && (generator != null)) {
-
- if (!directory.exists()) {
- directory.mkdirs();
- }
+ if (parentDir == null) {
+ log.warn("Parent Directory not specified, files will be generated "
+ + "accordingly to generated Type package path.");
+ }
+ if (type == null) {
+ log.error("Cannot generate Type into Java File because " +
+ "Generated Type is NULL!");
+ throw new IllegalArgumentException("Generated Type Cannot be NULL!");
+ }
+ if (generator == null) {
+ log.error("Cannot generate Type into Java File because " +
+ "Code Generator instance is NULL!");
+ throw new IllegalArgumentException("Code Generator Cannot be NULL!");
+ }
+ final File packageDir = packageToDirectory(parentDir,
+ type.getPackageName());
- final File file = new File(directory, type.getName() + ".java");
- try (final FileWriter fw = new FileWriter(file)) {
- file.createNewFile();
+ if (!packageDir.exists()) {
+ packageDir.mkdirs();
+ }
+ final File file = new File(packageDir, type.getName() + ".java");
+ try (final FileWriter fw = new FileWriter(file)) {
+ file.createNewFile();
- try (final BufferedWriter bw = new BufferedWriter(fw)) {
- Writer writer = generator.generate(type);
- bw.write(writer.toString());
- }
- } catch (IOException e) {
- log.error(e.getMessage());
- throw new IOException(e.getMessage());
+ try (final BufferedWriter bw = new BufferedWriter(fw)) {
+ Writer writer = generator.generate(type);
+ bw.write(writer.toString());
}
-
- return file;
+ } catch (IOException e) {
+ log.error(e.getMessage());
+ throw new IOException(e.getMessage());
}
- return null;
+ return file;
}
+ private File packageToDirectory(final File parentDirectory,
+ final String packageName) {
+ if (packageName == null) {
+ throw new IllegalArgumentException("Package Name cannot be NULL!");
+ }
+
+ final String[] subDirNames = packageName.split("\\.");
+ final StringBuilder dirPathBuilder = new StringBuilder();
+ dirPathBuilder.append(subDirNames[0]);
+ for (int i = 1; i < subDirNames.length; ++i) {
+ dirPathBuilder.append(File.separator);
+ dirPathBuilder.append(subDirNames[i]);
+ }
+ return new File(parentDirectory, dirPathBuilder.toString());
+ }
+
+ @Deprecated
private String generateParentPath(String path, String pkg) {
List<String> dirs = new ArrayList<String>();
String pkgPath = "";
import static org.opendaylight.controller.sal.java.api.generator.Constants.SC;
import static org.opendaylight.controller.sal.java.api.generator.Constants.STATIC;
import static org.opendaylight.controller.sal.java.api.generator.Constants.TAB;
+import static org.opendaylight.controller.sal.java.api.generator.Constants.EXTENDS;
+import static org.opendaylight.controller.sal.java.api.generator.Constants.IMPLEMENTS;
+import java.util.ArrayList;
import java.util.List;
import org.opendaylight.controller.sal.binding.model.api.AnnotationType;
builder.append(NL);
builder.append(NL);
createComment(builder, genType.getComment(), indent);
-
+
if (!genType.getAnnotations().isEmpty()) {
final List<AnnotationType> annotations = genType.getAnnotations();
appendAnnotations(builder, annotations);
builder.append(NL);
}
- builder.append(PUBLIC + GAP + type + GAP + genType.getName() + GAP
- + LCB);
+ builder.append(PUBLIC + GAP + type + GAP + genType.getName() + GAP);
+
+ final List<GeneratedType> genImplements = genType.getImplements();
+ if (genType instanceof GeneratedTransferObject) {
+ GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
+
+ if (genTO.getExtends() != null) {
+ builder.append(EXTENDS + GAP);
+ builder.append(genTO.getExtends() + GAP);
+ }
+ }
+ if (!genImplements.isEmpty()) {
+ if (genType instanceof GeneratedTransferObject) {
+ builder.append(IMPLEMENTS + GAP);
+ } else {
+ builder.append(EXTENDS + GAP);
+ }
+ builder.append(genImplements.get(0).getPackageName()
+ + "." + genImplements.get(0).getName());
+ for (int i = 1; i < genImplements.size(); ++i) {
+ builder.append(", ");
+ builder.append(genImplements.get(i).getPackageName()
+ + "." + genImplements.get(i).getName());
+ }
+ }
+
+ builder.append(GAP + LCB);
return builder.toString();
}
- private static StringBuilder appendAnnotations(final StringBuilder builder, final List<AnnotationType> annotations) {
+ private static StringBuilder appendAnnotations(final StringBuilder builder,
+ final List<AnnotationType> annotations) {
if ((builder != null) && (annotations != null)) {
for (final AnnotationType annotation : annotations) {
builder.append("@");
createComment(builder, comment, indent);
builder.append(NL);
builder.append(indent);
-
+
if (!method.getAnnotations().isEmpty()) {
final List<AnnotationType> annotations = method.getAnnotations();
appendAnnotations(builder, annotations);
builder.append(NL);
}
-
+
builder.append(indent + getExplicitType(type) + GAP + name);
builder.append(LB);
for (int i = 0; i < parameters.size(); i++) {
final List<GeneratedProperty> properties = genTransferObject
.getProperties();
+ final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
+ for (final GeneratedProperty property : properties) {
+ if (property.isReadOnly()) {
+ ctorParams.add(property);
+ }
+ }
+
builder.append(indent);
builder.append(PUBLIC);
builder.append(GAP);
builder.append(genTransferObject.getName());
builder.append(LB);
-
- boolean first = true;
- if (properties != null) {
- for (final GeneratedProperty property : properties) {
- if (first) {
- builder.append(getExplicitType(property.getReturnType()));
- builder.append(" ");
- builder.append(property.getName());
- first = false;
- } else {
- builder.append(", ");
- builder.append(getExplicitType(property.getReturnType()));
- builder.append(builder.append(" "));
- builder.append(property.getName());
- }
+
+ if (!ctorParams.isEmpty()) {
+ builder.append(getExplicitType(ctorParams.get(0).getReturnType()));
+ builder.append(" ");
+ builder.append(ctorParams.get(0).getName());
+ for (int i = 1; i < ctorParams.size(); ++i) {
+ final GeneratedProperty param = ctorParams.get(i);
+ builder.append(", ");
+ builder.append(getExplicitType(param.getReturnType()));
+ builder.append(GAP);
+ builder.append(param.getName());
}
}
-
- builder.append(RB);
- builder.append(GAP);
- builder.append(LCB);
- builder.append(NL);
- builder.append(indent);
- builder.append(TAB);
- builder.append("super();");
- builder.append(NL);
-
- if (properties != null) {
- for (final GeneratedProperty property : properties) {
+ builder.append(RB + GAP + LCB + NL + indent + TAB + "super();" + NL);
+ if (!ctorParams.isEmpty()) {
+ for (final GeneratedProperty property : ctorParams) {
builder.append(indent);
builder.append(TAB);
builder.append("this.");
builder.append(NL);
}
}
-
builder.append(indent);
builder.append(RCB);
-
return builder.toString();
}
builder.append(indent + RCB);
return builder.toString();
}
+
+ public static String createSetter(final GeneratedProperty property,
+ final String indent) {
+ final StringBuilder builder = new StringBuilder();
+
+ final Type type = property.getReturnType();
+ final String varName = property.getName();
+ final char first = Character.toUpperCase(varName.charAt(0));
+ final String methodName = "set" + first + varName.substring(1);
+
+ builder.append(indent + PUBLIC + GAP + "void" + GAP
+ + methodName);
+ builder.append(LB + getExplicitType(type) + GAP + varName + RB + LCB + NL);
+ String currentIndent = indent + TAB;
+ builder.append(currentIndent + "this." + varName + " = " + varName + SC + NL);
+ builder.append(indent + RCB);
+ return builder.toString();
+ }
public static String createHashCode(
final List<GeneratedProperty> properties, final String indent) {
builder.append(indent + "public int hashCode() {" + NL);
builder.append(indent + TAB + "final int prime = 31;" + NL);
builder.append(indent + TAB + "int result = 1;" + NL);
-
+
for (GeneratedProperty property : properties) {
String fieldName = property.getName();
builder.append(indent + TAB + "result = prime * result + (("
--- /dev/null
+package org.opendaylight.controller.sal.java.api.generator.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.controller.binding.generator.util.Types;
+import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
+import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
+import org.opendaylight.controller.sal.binding.generator.impl.BindingGeneratorImpl;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
+import org.opendaylight.controller.sal.binding.model.api.GeneratedType;
+import org.opendaylight.controller.sal.binding.model.api.Type;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;
+import org.opendaylight.controller.sal.java.api.generator.ClassCodeGenerator;
+import org.opendaylight.controller.yang.model.api.Module;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
+import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
+import org.opendaylight.controller.yang.parser.impl.YangParserImpl;
+
+public class ClassCodeGeneratorTest {
+
+ private final static List<File> testModels = new ArrayList<File>();
+
+ @BeforeClass
+ public static void loadTestResources() {
+ final File listModelFile = new File(ClassCodeGeneratorTest.class
+ .getResource("/list-composite-key.yang").getPath());
+ testModels.add(listModelFile);
+ }
+
+ @Test
+ public void compositeKeyClassTest() {
+ final YangModelParser parser = new YangParserImpl();
+ final Set<Module> modules = parser.parseYangModels(testModels);
+ final SchemaContext context = parser.resolveSchemaContext(modules);
+
+ assertNotNull(context);
+ final BindingGenerator bindingGen = new BindingGeneratorImpl();
+ final List<Type> genTypes = bindingGen.generateTypes(context);
+
+ assertTrue(genTypes != null);
+ assertEquals(7, genTypes.size());
+
+ int genTypesCount = 0;
+ int genTOsCount = 0;
+ for (final Type type : genTypes) {
+ if (type instanceof GeneratedType
+ && !(type instanceof GeneratedTransferObject)) {
+ genTypesCount++;
+ } else if (type instanceof GeneratedTransferObject) {
+ final GeneratedTransferObject genTO = (GeneratedTransferObject) type;
+
+ if (genTO.getName().equals("CompositeKeyListKey")) {
+ final List<GeneratedProperty> properties = genTO
+ .getProperties();
+ int propertyCount = 0;
+ for (final GeneratedProperty prop : properties) {
+ if (prop.getName().equals("Key1")) {
+ propertyCount++;
+ } else if (prop.getName().equals("Key2")) {
+ propertyCount++;
+ }
+ }
+
+ final ClassCodeGenerator clsGen = new ClassCodeGenerator();
+ try {
+ final Writer writer = clsGen.generate(genTO);
+ assertNotNull(writer);
+
+ final String outputStr = writer.toString();
+ writer.close();
+
+ assertNotNull(outputStr);
+ assertTrue(outputStr
+ .contains("public CompositeKeyListKey(java.lang.String Key2, " +
+ "java.lang.Byte Key1)"));
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ assertEquals(2, propertyCount);
+ genTOsCount++;
+ } else if (genTO.getName().equals("InnerListKey")) {
+ final List<GeneratedProperty> properties = genTO
+ .getProperties();
+ assertEquals(1, properties.size());
+ genTOsCount++;
+ }
+ }
+ }
+
+ assertEquals(5, genTypesCount);
+ assertEquals(2, genTOsCount);
+ }
+
+ @Test
+ public void defaultConstructorTest() {
+ final GeneratedTOBuilder toBuilder = new GeneratedTOBuilderImpl("simple.pack", "DefCtor");
+
+ GeneratedPropertyBuilder propBuilder = toBuilder.addProperty("foo");
+ propBuilder.addReturnType(Types.typeForClass(String.class));
+ propBuilder.setReadOnly(false);
+
+ propBuilder = toBuilder.addProperty("bar");
+ propBuilder.addReturnType(Types.typeForClass(Integer.class));
+ propBuilder.setReadOnly(false);
+
+ final GeneratedTransferObject genTO = toBuilder.toInstance();
+
+ final ClassCodeGenerator clsGen = new ClassCodeGenerator();
+ try {
+ final Writer writer = clsGen.generate(genTO);
+ assertNotNull(writer);
+
+ final String outputStr = writer.toString();
+ writer.close();
+
+ assertNotNull(outputStr);
+ assertTrue(outputStr
+ .contains("public DefCtor()"));
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
types.add(t3);
GeneratorJavaFile generator = new GeneratorJavaFile(
new InterfaceGenerator(), types);
- generator.generateToFile(PATH);
+ generator.generateToFile(new File(PATH));
String[] files = new File(PATH + FS + "org" + FS + "opendaylight" + FS
+ "controller" + FS + "gen").list();
final GeneratorJavaFile generator = new GeneratorJavaFile(
typesToGenerate, tosToGenerate);
- generator.generateToFile(GENERATOR_OUTPUT_PATH);
+ generator.generateToFile(new File(GENERATOR_OUTPUT_PATH));
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(
--- /dev/null
+module list-composite-key {
+ yang-version 1;
+ namespace "urn:composite.key";
+ prefix "scd";
+
+ organization "OPEN DAYLIGHT";
+ contact "http://www.opendaylight.org/";
+
+ description "
+ This module contains the definitions of elements that creates network
+ topology i.e. definition of network nodes and links. This module is
+ not designed to be used solely for network representation. This module
+ SHOULD be used as base module in defining the network topology.
+ ";
+
+ revision "2013-02-27" {
+ reference " WILL BE DEFINED LATER";
+ }
+
+ container list-parent-container {
+
+ list composite-key-list {
+ key "key1 key2";
+
+ leaf key1 {
+ type int8;
+ }
+
+ leaf key2 {
+ type string;
+ }
+
+ list inner-list {
+ key "key1";
+
+ leaf key1 {
+ type uint16;
+ }
+
+ leaf foo {
+ type int32;
+ }
+ }
+
+ leaf foo {
+ type int32;
+ }
+ }
+
+ list no-key-list {
+ leaf foo {
+ type int32;
+ }
+
+ leaf bar {
+ type decimal64 {
+ fraction-digits 2;
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
import org.opendaylight.controller.sal.java.api.generator.GeneratorJavaFile;
import org.opendaylight.controller.yang.model.api.Module;
import org.opendaylight.controller.yang.model.api.SchemaContext;
-import org.opendaylight.controller.yang.model.parser.impl.YangModelParserImpl;
+import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
+import org.opendaylight.controller.yang.parser.impl.YangParserImpl;
public class Demo {
private static final String ERR_MSG = "2 parameters expected: 1. -f=<path-to-input-folder>, 2. -o=<output-folder>";
inputFiles.add(new File(resourceDir, fileName));
}
- final YangModelParserImpl parser = new YangModelParserImpl();
+ final YangModelParser parser = new YangParserImpl();
final BindingGenerator bindingGenerator = new BindingGeneratorImpl();
final Set<Module> modulesToBuild = parser.parseYangModels(inputFiles);