import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.computeDefaultSUID;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForAugmentedGeneratedType;
import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.DATA_OBJECT;
final GeneratedTypeBuilder childOf, final ListSchemaNode node) {
final GeneratedTypeBuilder genType = processDataSchemaNode(module, basePackageName, childOf, node);
if (genType != null) {
- constructGetter(parent, node.getQName().getLocalName(), node.getDescription(), Types.listTypeFor(genType));
+ constructGetter(parent, node.getQName().getLocalName(), node.getDescription(),
+ Types.listTypeFor(genType));
final List<String> listKeys = listKeys(node);
final String packageName = packageNameForGeneratedType(basePackageName, node.getPath());
if (rpc != null) {
final String rpcName = BindingMapping.getClassName(rpc.getQName());
final String rpcMethodName = BindingMapping.getPropertyName(rpcName);
- final String rpcComment = rpc.getDescription();
+ final String rpcComment = encodeAngleBrackets(rpc.getDescription());
final MethodSignatureBuilder method = interfaceBuilder.addMethod(rpcMethodName);
final ContainerSchemaNode input = rpc.getInput();
final ContainerSchemaNode output = rpc.getOutput();
listenerInterface.addMethod("on" + notificationInterface.getName())
.setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification")
- .setComment(notification.getDescription()).setReturnType(Types.VOID);
+ .setComment(encodeAngleBrackets(notification.getDescription())).setReturnType(Types.VOID);
}
}
listenerInterface.setDescription(createDescription(notifications, module.getName(), module.getModuleSourcePath()));
&& (enumTypeDef.getQName().getLocalName() != null)) {
final String enumerationName = BindingMapping.getClassName(enumName);
final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
- enumBuilder.setDescription(enumTypeDef.getDescription());
+ final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
+ enumBuilder.setDescription(enumTypedefDescription);
enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
ModuleContext ctx = genCtx.get(module);
ctx.addInnerTypedefType(enumTypeDef.getPath(), enumBuilder);
if (!choiceNode.isAddedByUses()) {
final String packageName = packageNameForGeneratedType(basePackageName, choiceNode.getPath());
final GeneratedTypeBuilder choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
- constructGetter(parent, choiceNode.getQName().getLocalName(), choiceNode.getDescription(),
- choiceTypeBuilder);
+ constructGetter(parent, choiceNode.getQName().getLocalName(),
+ choiceNode.getDescription(), choiceTypeBuilder);
choiceTypeBuilder.addImplementsType(typeForClass(DataContainer.class));
annotateDeprecatedIfNecessary(choiceNode.getStatus(), choiceTypeBuilder);
genCtx.get(module).addChildNodeType(choiceNode, choiceTypeBuilder);
return false;
}
final String leafName = leaf.getQName().getLocalName();
- final String leafDesc = leaf.getDescription();
+ final String leafDesc = encodeAngleBrackets(leaf.getDescription());
final GeneratedPropertyBuilder propBuilder = toBuilder.addProperty(BindingMapping.getPropertyName(leafName));
propBuilder.setReadOnly(isReadOnly);
propBuilder.setReturnType(returnType);
final GeneratedTypeBuilder typeBuilder, final Module parentModule) {
final GeneratedTOBuilderImpl returnType = new GeneratedTOBuilderImpl(genTOBuilder.getPackageName(),
genTOBuilder.getName());
+ final String typedefDescription = encodeAngleBrackets(typeDef.getDescription());
- returnType.setDescription(typeDef.getDescription());
+ returnType.setDescription(typedefDescription);
returnType.setReference(typeDef.getReference());
returnType.setSchemaPath(typeDef.getPath().getPathFromRoot());
returnType.setModuleName(parentModule.getName());
final String schemaNodeName, final String comment, final Type returnType) {
final MethodSignatureBuilder getMethod = interfaceBuilder
.addMethod(getterMethodName(schemaNodeName, returnType));
- getMethod.setComment(comment);
+ getMethod.setComment(encodeAngleBrackets(comment));
getMethod.setReturnType(returnType);
return getMethod;
}
if (verboseClassComments) {
sb.append("<pre>");
sb.append(NEW_LINE);
- sb.append(YangTemplate.generateYangSnipet(schemaNodes));
+ sb.append(encodeAngleBrackets(YangTemplate.generateYangSnipet(schemaNodes)));
sb.append("</pre>");
sb.append(NEW_LINE);
}
private String createDescription(final SchemaNode schemaNode, final String fullyQualifiedName) {
final StringBuilder sb = new StringBuilder();
- final String formattedDescription = YangTemplate.formatToParagraph(schemaNode.getDescription(), 0);
+ final String nodeDescription = encodeAngleBrackets(schemaNode.getDescription());
+ final String formattedDescription = YangTemplate.formatToParagraph(nodeDescription, 0);
if (!Strings.isNullOrEmpty(formattedDescription)) {
sb.append(formattedDescription);
sb.append(NEW_LINE);
sb.append("<pre>");
sb.append(NEW_LINE);
- sb.append(YangTemplate.generateYangSnipet(schemaNode));
+ sb.append(encodeAngleBrackets(YangTemplate.generateYangSnipet(schemaNode)));
sb.append("</pre>");
sb.append(NEW_LINE);
sb.append("The schema path to identify an instance is");
private String createDescription(final Module module) {
final StringBuilder sb = new StringBuilder();
- final String formattedDescription = YangTemplate.formatToParagraph(module.getDescription(), 0);
+ final String moduleDescription = encodeAngleBrackets(module.getDescription());
+ final String formattedDescription = YangTemplate.formatToParagraph(moduleDescription, 0);
if (!Strings.isNullOrEmpty(formattedDescription)) {
sb.append(formattedDescription);
sb.append(NEW_LINE);
sb.append("<pre>");
sb.append(NEW_LINE);
- sb.append(YangTemplate.generateYangSnipet(module));
+ sb.append(encodeAngleBrackets(YangTemplate.generateYangSnipet(module)));
sb.append("</pre>");
}
var boolean isFirstElementOnNewLineEmptyChar = false;
val lineIndent = computeNextLineIndent(nextLineIndent);
- formattedText = formattedText.replace("*/", "*/");
formattedText = NEWLINE_OR_TAB.removeFrom(formattedText);
formattedText = formattedText.replaceAll(" +", " ");
*/
package org.opendaylight.yangtools.sal.binding.yang.types;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath;
import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule());
final EnumerationBuilderImpl enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName);
- enumBuilder.setDescription(enumTypeDef.getDescription());
+ final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
+ enumBuilder.setDescription(enumTypedefDescription);
enumBuilder.setReference(enumTypeDef.getReference());
enumBuilder.setModuleName(module.getName());
enumBuilder.setSchemaPath(enumTypeDef.getPath().getPathFromRoot());
final String enumerationName = BindingMapping.getClassName(enumName);
final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
- enumBuilder.setDescription(enumTypeDef.getDescription());
+ final String enumTypedefDescription = encodeAngleBrackets(enumTypeDef.getDescription());
+ enumBuilder.setDescription(enumTypedefDescription);
enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
return enumBuilder.toInstance(enumBuilder);
}
if (typeDefName != null && !typeDefName.isEmpty()) {
final String typeName = BindingMapping.getClassName(typeDefName);
unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
- unionGenTOBuilder.setDescription(typedef.getDescription());
+ final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
+ unionGenTOBuilder.setDescription(typedefDescription);
unionGenTOBuilder.setReference(typedef.getReference());
unionGenTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot());
unionGenTOBuilder.setModuleName(module.getName());
if ((packageName != null) && (typeDefTOName != null)) {
final String genTOName = BindingMapping.getClassName(typeDefTOName);
final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTOName);
+ final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
- newType.setDescription(typedef.getDescription());
+ newType.setDescription(typedefDescription);
newType.setReference(typedef.getReference());
newType.setSchemaPath(typedef.getPath().getPathFromRoot());
newType.setModuleName(moduleName);
final String typeName = BindingMapping.getClassName(typeDefName);
final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
+ final String typedefDescription = encodeAngleBrackets(typeDef.getDescription());
- genTOBuilder.setDescription(typeDef.getDescription());
+ genTOBuilder.setDescription(typedefDescription);
genTOBuilder.setReference(typeDef.getReference());
genTOBuilder.setSchemaPath(typeDef.getPath().getPathFromRoot());
genTOBuilder.setModuleName(moduleName);
final String classTypedefName = BindingMapping.getClassName(typedefName);
final String innerTypeDef = innerExtendedType.getQName().getLocalName();
final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, classTypedefName);
+ final String typedefDescription = encodeAngleBrackets(typedef.getDescription());
- genTOBuilder.setDescription(typedef.getDescription());
+ genTOBuilder.setDescription(typedefDescription);
genTOBuilder.setReference(typedef.getReference());
genTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot());
genTOBuilder.setModuleName(moduleName);
/**
* Contains the methods for converting strings to valid JAVA language strings
- * (package names, class names, attribute names).
+ * (package names, class names, attribute names) and to valid javadoc comments.
*
*
*/
*/
private static final CharMatcher DOT_MATCHER = CharMatcher.is('.');
private static final CharMatcher DASH_COLON_MATCHER = CharMatcher.anyOf("-:");
+ private static final CharMatcher GT_MATCHER = CharMatcher.is('>');
+ private static final CharMatcher LT_MATCHER = CharMatcher.is('<');
private static final Restrictions EMPTY_RESTRICTIONS = new Restrictions() {
@Override
}
};
}
+
+ /**
+ * Encodes angle brackets in yang statement description
+ * @param description description of a yang statement which is used to generate javadoc comments
+ * @return string with encoded angle brackets
+ */
+ public static String encodeAngleBrackets(String description) {
+ if (description != null) {
+ description = LT_MATCHER.replaceFrom(description, "<");
+ description = GT_MATCHER.replaceFrom(description, ">");
+ }
+ return description;
+ }
}
}
private static final CharMatcher AMP_MATCHER = CharMatcher.is('&');
- private static final CharMatcher GT_MATCHER = CharMatcher.is('>');
- private static final CharMatcher LT_MATCHER = CharMatcher.is('<');
def encodeJavadocSymbols(String description) {
if (description.nullOrEmpty) {
return description;
}
- var ret = description.replace("*/", "*/")
-
- // FIXME: Use Guava's HtmlEscapers once we have it available
+ var ret = description.replace("*/", "*/");
ret = AMP_MATCHER.replaceFrom(ret, "&");
- ret = GT_MATCHER.replaceFrom(ret, ">");
- ret = LT_MATCHER.replaceFrom(ret, "<");
+
return ret;
}
var StringBuilder lineBuilder = new StringBuilder();
var boolean isFirstElementOnNewLineEmptyChar = false;
- formattedText = formattedText.encodeJavadocSymbols
+ formattedText = encodeJavadocSymbols(formattedText)
formattedText = NL_MATCHER.removeFrom(formattedText)
formattedText = TAB_MATCHER.removeFrom(formattedText)
formattedText = SPACES_PATTERN.matcher(formattedText).replaceAll(" ")
*/
package org.opendaylight.yangtools.sal.java.api.generator
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.encodeAngleBrackets;
+
import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
}
def writeEnumItem(String name, int value, String description) '''
- «asJavadoc(formatToParagraph(description))»
+ «asJavadoc(encodeAngleBrackets(description))»
«name»(«value»)
'''
+/*
+ * Copyright (c) 2015 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.yangtools.sal.java.api.generator.test;
import static org.junit.Assert.assertTrue;
import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.cleanUp;
import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.getSourceFiles;
import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.testCompilation;
+
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.util.List;
* Test if generated classes from yang file is compilable, generated javadoc comments contains
* symbols as javadoc comment tag, which caused of compilation problem.
*/
-public class EndodingInJavaDocTest extends BaseCompilationTest {
+public class EncodingInJavaDocTest extends BaseCompilationTest {
@Test
- public void testAugmentToUsesInAugment() throws Exception {
+ public void testJavadocEncodingCompilation() throws Exception {
final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "encoding-javadoc");
assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "encoding-javadoc");
namespace "urn:opendaylight:encoding-javadoc";
prefix "enc";
+ description "testing module description <should_be_encoded>";
+
revision "2014-04-09" {
}
+ extension test-extension {
+ description "testing extension description <should_be_encoded>";
+ argument "name";
+ }
+
+ identity test-identity {
+ description "testing identity description <should_be_ encoded>";
+ }
+
+ typedef port-number {
+ type uint16 {
+ range "0..65535";
+ }
+
+ description "testing typedef description <should_be_encoded>";
+ }
+
+ rpc rock-the-house {
+ input {
+ leaf zip-code {
+ type string;
+ }
+ }
+
+ description "testing rpc description <should_be_encoded>";
+ }
+
+ notification event {
+ leaf event-class {
+ type string;
+ }
+
+ anyxml reporting-entity;
+
+ leaf severity {
+ type string;
+ }
+
+ description "testing notification description <should_be_encoded>";
+ }
+
+ augment "/enc:cont1" {
+ leaf augment-leaf {
+ type string;
+ }
+
+ description "testing augment description <should_be_encoded>";
+ }
+
container cont1 {
- description "/e.g. 1/*/*";
+ description "/e.g. 1/*/* testing container description <should_be_encoded>";
reference "RFC 6020 - http://tools.ietf.org/html/rfc6020";
list list1 {
- description "/e.g. 1/*/*";
+ description "/e.g. 1/*/* testing list description <should_be_encoded>";
reference "RFC 6020 - http://tools.ietf.org/html/rfc6020";
key "topology-id";
leaf topology-id {
- description "/e.g. 1/*/*";
+ description "/e.g. 1/*/* testing leaf description <should_be_encoded>";
reference "RFC 6020 - http://tools.ietf.org/html/rfc6020";
type int32;
}
+
uses link1;
}
}
grouping link1 {
list link1 {
- description "/e.g. 1/*/*";
+ description "/e.g. 1/*/* testing list description <should_be_encoded>";
reference "RFC 6020 - http://tools.ietf.org/html/rfc6020";
key "link-id";
uses link-attributes;
}
+
+ description "testing grouping description <should_be_encoded>";
}
grouping link-attributes {
leaf link-id {
- description "/e.g. 1/*/*";
+ description "/e.g. 1/*/* testing leaf description <should_be_encoded>";
reference "RFC 6020 - http://tools.ietf.org/html/rfc6020";
type int8;
}
}
leaf inclusion-rulez {
- description "/e.g. 1/*/*";
+ description "/e.g. 1/*/* testing leaf description <should be encoded>";
reference "RFC 6020 http://technet.com";
type string;
type enumeration {
enum include {
description
- "/e.g. 1/*/*";
+ "/e.g. 1/*/* testing enum description <should be encoded>";
}
enum exclude {
description
}
}
}
+
+ leaf-list test-leaf-list {
+ type string;
+ description "testing leaf-list description <should be encoded>";
+ }
+
+ choice test-choice {
+ description "testing choice description <should be encoded>";
+
+ case test-case-1 {
+ description "testing case description <should be encoded>";
+
+ leaf case-1-leaf {
+ type string;
+ description "testing leaf in case description <should be encoded>";
+ }
+ }
+
+ case test-case-2 {
+ description "testing case description <should be encoded>";
+
+ leaf case-2-leaf {
+ type string;
+ description "testing leaf in case description <should be encoded>";
+ }
+ }
+ }
}