package org.opendaylight.yangtools.sal.binding.generator.impl;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
-
import org.opendaylight.yangtools.yang.binding.Augmentation;
import org.opendaylight.yangtools.yang.binding.BindingMapping;
import org.opendaylight.yangtools.yang.binding.ChildOf;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.util.SchemaNodeUtils;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
+public final class BindingSchemaContextUtils {
-public class BindingSchemaContextUtils {
+ private BindingSchemaContextUtils() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
// FIXME: THis method does not search in case augmentations.
public static Optional<DataNodeContainer> findDataNodeContainer(final SchemaContext ctx,
// This solves case, if choice was inside grouping
// which was used in different module and thus namespaces are
// different, but local names are still same.
- //
+ //
// Still we need to check equality of definition, because local name is not
// sufficient to uniquelly determine equality of cases
//
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class CodecMapping {
+public final class CodecMapping {
private static final Logger LOG = LoggerFactory.getLogger(CodecMapping.class);
public static final String AUGMENTATION_CODEC = "AUGMENTATION_CODEC";
public static final String DISPATCH_CODEC = "DISPATCH_CODEC";
+ private CodecMapping() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
+
public static void setIdentifierCodec(Class<?> obj,InstanceIdentifierCodec codec) {
Field instanceIdField;
try {
import org.opendaylight.yangtools.yang.binding.Identifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
-public class CodecTypeUtils {
+public final class CodecTypeUtils {
+
+ private CodecTypeUtils() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
@SuppressWarnings({"unchecked","rawtypes"})
public static IdentifiableItem<?, ?> newIdentifiableItem(Class<?> type, Object key) {
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
-
-import java.net.URI;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-
import javassist.ClassPool;
-
-import javax.annotation.concurrent.GuardedBy;
-
import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
import org.opendaylight.yangtools.binding.generator.util.Types;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.annotation.concurrent.GuardedBy;
+import java.net.URI;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+
public class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaContextListener,
SchemaLock, AutoCloseable, SchemaContextHolder, TypeResolver {
Type serviceClass = new ReferencedTypeImpl(namespace, BindingMapping.getClassName(module.getName())
+ "Service");
serviceTypeToRpc.put(serviceClass, rpcs);
+ updatePromisedSchemas(serviceClass);
}
Map<SchemaPath, Type> typedefs = context.getTypedefs();
Set<QName> serviceRef = serviceTypeToRpc.get(new ReferencedTypeImpl(service.getPackage().getName(), service
.getSimpleName()));
if (serviceRef == null) {
- serviceRef = Collections.emptySet();
- }
+ waitForSchema(service);
+ serviceRef = serviceTypeToRpc.get(new ReferencedTypeImpl(service.getPackage().getName(), service
+ .getSimpleName()));
+ }
return serviceRef;
}
import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
+import com.google.common.base.Preconditions
/**
* Template for generating JAVA class.
* List of generated types which are enclosed inside <code>genType</code>
*/
protected val List<GeneratedType> enclosedGeneratedTypes;
-
+
protected val GeneratedTransferObject genTO;
/**
* Creates instance of this class with concrete <code>genType</code>.
- *
+ *
* @param genType generated transfer object which will be transformed to JAVA class source code
*/
new(GeneratedTransferObject genType) {
/**
* Generates JAVA class source code (class body only).
- *
+ *
* @return string with JAVA class body source code
*/
def CharSequence generateAsInnerClass() {
/**
* Template method which generates class body.
- *
+ *
* @param isInnerClass boolean value which specify if generated class is|isn't inner
* @return string with class source code in JAVA format
*/
«enumDeclarations»
«constantsDeclarations»
«generateFields»
-
- «IF restrictions != null && (!restrictions.rangeConstraints.nullOrEmpty ||
+
+ «IF restrictions != null && (!restrictions.rangeConstraints.nullOrEmpty ||
!restrictions.lengthConstraints.nullOrEmpty)»
«generateConstraints»
-
+
«ENDIF»
«constructors»
/**
* Template method which generates inner classes inside this interface.
- *
+ *
* @return string with the source code for inner classes in JAVA format
*/
def protected innerClassesDeclarations() '''
«IF false == parentProperties.empty»
super(«parentProperties.asArguments»);
«ENDIF»
- «FOR p : allProperties»
+ «FOR p : allProperties»
«generateRestrictions(type, p.fieldName.toString, p.returnType)»
«ENDFOR»
- «FOR p : properties»
+
+ «/*
+ * If we have patterns, we need to apply them to the value field. This is a sad
+ * consequence of how this code is structured.
+ */
+ IF genTO.typedef && !allProperties.empty && allProperties.size == 1 && allProperties.get(0).name.equals("value")»
+
+ «Preconditions.importedName».checkNotNull(_value, "Supplied value may not be null");
+
+ «FOR c : consts»
+ «IF c.name == TypeConstants.PATTERN_CONSTANT_NAME && c.value instanceof List<?>»
+ boolean valid = false;
+ for (Pattern p : patterns) {
+ if (p.matcher(_value).matches()) {
+ valid = true;
+ break;
+ }
+ }
+
+ «Preconditions.importedName».checkArgument(valid, "Supplied value \"%s\" does not match any of the permitted patterns %s", _value, «TypeConstants.PATTERN_CONSTANT_NAME»);
+ «ENDIF»
+ «ENDFOR»
+ «ENDIF»
+
+ «FOR p : properties»
this.«p.fieldName» = «p.fieldName»;
«ENDFOR»
}
-
+
'''
def protected genUnionConstructor() '''
«IF false == parentProperties.empty»
super(«parentProperties.asArguments»);
«ENDIF»
- «generateRestrictions(type, property.fieldName.toString, property.returnType)»
- this.«property.fieldName» = «property.name»;
- «FOR p : other»
+
+ «generateRestrictions(type, property.fieldName.toString, property.returnType)»
+
+ this.«property.fieldName» = «property.name»;
+ «FOR p : other»
this.«p.fieldName» = null;
- «ENDFOR»
+ «ENDFOR»
}
'''
«IF false == parentProperties.empty»
super(source);
«ENDIF»
- «FOR p : properties»
+ «FOR p : properties»
this.«p.fieldName» = source.«p.fieldName»;
«ENDFOR»
}
«IF !("org.opendaylight.yangtools.yang.binding.InstanceIdentifier".equals(prop.returnType.fullyQualifiedName))»
public static «genTO.name» getDefaultInstance(String defaultValue) {
«IF "byte[]".equals(prop.returnType.name)»
- «BaseEncoding.importedName» baseEncoding = «BaseEncoding.importedName».base64();
+ «BaseEncoding.importedName» baseEncoding = «BaseEncoding.importedName».base64();
return new «genTO.name»(baseEncoding.decode(defaultValue));
«ELSEIF "java.lang.String".equals(prop.returnType.fullyQualifiedName)»
return new «genTO.name»(defaultValue);
/**
* Template method which generates JAVA class declaration.
- *
+ *
* @param isInnerClass boolean value which specify if generated class is|isn't inner
* @return string with class declaration in JAVA format
*/
/**
* Template method which generates JAVA enum type.
- *
+ *
* @return string with inner enum source code in JAVA format
*/
def protected enumDeclarations() '''
def protected suidDeclaration() '''
«IF genTO.SUID != null»
- private static final long serialVersionUID = «genTO.SUID.value»L;
+ private static final long serialVersionUID = «genTO.SUID.value»L;
«ENDIF»
'''
/**
- * Template method wich generates JAVA constants.
- *
- * @return string with constants in JAVA format
+ * Template method which generates JAVA constants.
+ *
+ * @return string with constants in JAVA format
*/
def protected constantsDeclarations() '''
«IF !consts.empty»
«val cValue = c.value»
«IF cValue instanceof List<?>»
«val cValues = cValue as List<?>»
- private static final «List.importedName»<«Pattern.importedName»> «Constants.MEMBER_PATTERN_LIST» = new «ArrayList.importedName»<«Pattern.importedName»>();
- public static final «List.importedName»<String> «TypeConstants.PATTERN_CONSTANT_NAME» = «Arrays.importedName».asList(«
+ private static final «List.importedName»<«Pattern.importedName»> «Constants.MEMBER_PATTERN_LIST»;
+ public static final «List.importedName»<String> «TypeConstants.PATTERN_CONSTANT_NAME» = «ImmutableList.importedName».of(«
FOR v : cValues SEPARATOR ", "»«
IF v instanceof String»"«
v as String»"«
*/
def protected generateStaticInicializationBlock() '''
static {
+ final «List.importedName»<«Pattern.importedName»> l = new «ArrayList.importedName»<«Pattern.importedName»>();
for (String regEx : «TypeConstants.PATTERN_CONSTANT_NAME») {
- «Constants.MEMBER_PATTERN_LIST».add(Pattern.compile(regEx));
+ l.add(Pattern.compile(regEx));
}
+
+ «Constants.MEMBER_PATTERN_LIST» = «ImmutableList.importedName».copyOf(l);
}
'''
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.net.URI;
import java.util.ArrayList;
* instead of marking it with @After annotation to prevent removing
* generated code if test fails.
*/
- static void cleanUp(File... resourceDirs) {
+ static void cleanUp(final File... resourceDirs) {
for (File resourceDir : resourceDirs) {
if (resourceDir.exists()) {
deleteTestDir(resourceDir);
* field type
* @return field with given name if present in class
*/
- static Field assertContainsField(Class<?> clazz, String name, Class<?> type) {
+ static Field assertContainsField(final Class<?> clazz, final String name, final Class<?> type) {
try {
Field f = clazz.getDeclaredField(name);
assertEquals(type, f.getType());
* @param constructorArgs
* constructor arguments of class to test
*/
- static void assertContainsFieldWithValue(Class<?> clazz, String name, Class<?> returnType, Object expectedValue,
- Class<?>... constructorArgs) {
+ static void assertContainsFieldWithValue(final Class<?> clazz, final String name, final Class<?> returnType, final Object expectedValue,
+ final Class<?>... constructorArgs) {
Object[] initargs = null;
if (constructorArgs != null && constructorArgs.length > 0) {
initargs = new Object[constructorArgs.length];
* @param initargs
* array of constructor values
*/
- static void assertContainsFieldWithValue(Class<?> clazz, String name, Class<?> returnType, Object expectedValue,
- Class<?>[] constructorArgs, Object... initargs) {
+ static void assertContainsFieldWithValue(final Class<?> clazz, final String name, final Class<?> returnType, final Object expectedValue,
+ final Class<?>[] constructorArgs, final Object... initargs) {
Field f = assertContainsField(clazz, name, returnType);
f.setAccessible(true);
+
+ final Object obj;
+ if ((f.getModifiers() & Modifier.STATIC) == 0) {
+ try {
+ Constructor<?> c = clazz.getDeclaredConstructor(constructorArgs);
+ obj = c.newInstance(initargs);
+ } catch (Exception e) {
+ throw new AssertionError("Failed to instantiate object for " + clazz, e);
+ }
+ } else {
+ obj = null;
+ }
+
try {
- Constructor<?> c = clazz.getDeclaredConstructor(constructorArgs);
- Object o = c.newInstance(initargs);
- assertEquals(expectedValue, f.get(o));
- } catch (Exception e) {
- throw new AssertionError("Failed to perform " + name + " field test", e);
+ assertEquals(expectedValue, f.get(obj));
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ throw new AssertionError("Failed to get field " + name + " of class " + clazz, e);
}
}
* @param args
* array of argument classes
*/
- static Constructor<?> assertContainsConstructor(Class<?> clazz, Class<?>... args) {
+ static Constructor<?> assertContainsConstructor(final Class<?> clazz, final Class<?>... args) {
try {
return clazz.getDeclaredConstructor(args);
} catch (NoSuchMethodException e) {
* array of parameter type classes
* @return method with given name, return type and parameter types
*/
- static Method assertContainsMethod(Class<?> clazz, Class<?> returnType, String name, Class<?>... args) {
+ static Method assertContainsMethod(final Class<?> clazz, final Class<?> returnType, final String name, final Class<?>... args) {
try {
Method m = clazz.getDeclaredMethod(name, args);
assertEquals(returnType, m.getReturnType());
* @param loader
* current class loader
*/
- static void assertContainsMethod(Class<?> clazz, String returnTypeStr, String name, ClassLoader loader) {
+ static void assertContainsMethod(final Class<?> clazz, final String returnTypeStr, final String name, final ClassLoader loader) {
Class<?> returnType;
try {
returnType = Class.forName(returnTypeStr, true, loader);
* @param clazz
* class to test
*/
- static void assertContainsDefaultMethods(Class<?> clazz) {
+ static void assertContainsDefaultMethods(final Class<?> clazz) {
assertContainsMethod(clazz, Integer.TYPE, "hashCode");
assertContainsMethod(clazz, Boolean.TYPE, "equals", Object.class);
assertContainsMethod(clazz, String.class, "toString");
* constructor arguments
* @throws Exception
*/
- static void assertContainsRestrictionCheck(Constructor<?> constructor, String errorMsg, Object... args)
+ static void assertContainsRestrictionCheck(final Constructor<?> constructor, final String errorMsg, final Object... args)
throws Exception {
try {
constructor.newInstance(args);
* constructor arguments
* @throws Exception
*/
- static void assertContainsRestrictionCheck(Object obj, Method method, String errorMsg, Object... args)
+ static void assertContainsRestrictionCheck(final Object obj, final Method method, final String errorMsg, final Object... args)
throws Exception {
try {
method.invoke(obj, args);
* @param clazz
* class to test
*/
- static void assertContainsGetLengthOrRange(Class<?> clazz, boolean isLength) {
+ static void assertContainsGetLengthOrRange(final Class<?> clazz, final boolean isLength) {
try {
Method m = clazz.getDeclaredMethod(isLength ? "length" : "range");
java.lang.reflect.Type returnType = m.getGenericReturnType();
* @param ifc
* expected interface
*/
- static void assertImplementsIfc(Class<?> clazz, Class<?> ifc) {
+ static void assertImplementsIfc(final Class<?> clazz, final Class<?> ifc) {
Class<?>[] interfaces = clazz.getInterfaces();
List<Class<?>> ifcsList = Arrays.asList(interfaces);
if (!ifcsList.contains(ifc)) {
* @param genericTypeName
* fully qualified name of expected parameter type
*/
- static void testAugmentation(Class<?> clazz, String genericTypeName) {
+ static void testAugmentation(final Class<?> clazz, final String genericTypeName) {
assertImplementsParameterizedIfc(clazz, AUGMENTATION, genericTypeName);
}
* @param genericTypeName
* name of generic type
*/
- static void assertImplementsParameterizedIfc(Class<?> clazz, String ifcName, String genericTypeName) {
+ static void assertImplementsParameterizedIfc(final Class<?> clazz, final String ifcName, final String genericTypeName) {
ParameterizedType ifcType = null;
for (java.lang.reflect.Type ifc : clazz.getGenericInterfaces()) {
if (ifc instanceof ParameterizedType) {
* @param compiledOutputDir
* compiler output directory
*/
- static void testCompilation(File sourcesOutputDir, File compiledOutputDir) {
+ static void testCompilation(final File sourcesOutputDir, final File compiledOutputDir) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
List<File> filesList = getJavaFiles(sourcesOutputDir);
* @param count
* expected count of files in directory
*/
- static void assertFilesCount(File dir, int count) {
+ static void assertFilesCount(final File dir, final int count) {
File[] dirContent = dir.listFiles();
if (dirContent == null) {
throw new AssertionError("File " + dir + " doesn't exists or it's not a directory");
* directory to search
* @return List of java files found
*/
- private static List<File> getJavaFiles(File directory) {
+ private static List<File> getJavaFiles(final File directory) {
List<File> result = new ArrayList<>();
File[] filesToRead = directory.listFiles();
if (filesToRead != null) {
return result;
}
- static List<File> getSourceFiles(String path) throws Exception {
+ static List<File> getSourceFiles(final String path) throws Exception {
final URI resPath = BaseCompilationTest.class.getResource(path).toURI();
final File sourcesDir = new File(resPath);
if (sourcesDir.exists()) {
}
}
- static void deleteTestDir(File file) {
+ static void deleteTestDir(final File file) {
if (file.isDirectory()) {
File[] filesToDelete = file.listFiles();
if (filesToDelete != null) {
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.Range;
import java.io.File;
import java.lang.reflect.Constructor;
arg = "abcd";
expectedMsg = String.format("Invalid length: %s, expected: %s.", arg, lengthConstraints);
assertContainsRestrictionCheck(expectedConstructor, expectedMsg, arg);
- obj = expectedConstructor.newInstance("hello world");
- assertEquals(obj, defInst.invoke(null, "hello world"));
+
+ obj = expectedConstructor.newInstance("abcde");
+ assertEquals(obj, defInst.invoke(null, "abcde"));
// typedef string-ext2
assertFalse(stringExt2Class.isInterface());
arg = "abcde";
expectedMsg = String.format("Invalid length: %s, expected: %s.", arg, lengthConstraints);
assertContainsRestrictionCheck(expectedConstructor, expectedMsg, arg);
- obj = expectedConstructor.newInstance("helloWorld");
- assertEquals(obj, defInst.invoke(null, "helloWorld"));
+ obj = expectedConstructor.newInstance("abcdef");
+ assertEquals(obj, defInst.invoke(null, "abcdef"));
// typedef string-ext3
assertFalse(stringExt3Class.isInterface());
defInst = assertContainsMethod(stringExt3Class, stringExt3Class, "getDefaultInstance", String.class);
// assertEquals(1, stringExt3Class.getDeclaredMethods().length);
- obj = expectedConstructor.newInstance("helloWorld");
- assertEquals(obj, defInst.invoke(null, "helloWorld"));
+ obj = expectedConstructor.newInstance("bbbbbb");
+ assertEquals(obj, defInst.invoke(null, "bbbbbb"));
// typedef my-decimal-type
assertFalse(myDecimalTypeClass.isInterface());
package org.opendaylight.yangtools.objcache;
import com.google.common.base.Preconditions;
-
import javax.annotation.Nonnull;
import javax.annotation.concurrent.GuardedBy;
-
import org.opendaylight.yangtools.objcache.impl.StaticObjectCacheBinder;
import org.opendaylight.yangtools.objcache.spi.IObjectCacheFactory;
import org.opendaylight.yangtools.objcache.spi.NoopObjectCacheBinder;
public final class ObjectCacheFactory {
private static volatile IObjectCacheFactory factory;
+ private ObjectCacheFactory() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
+
@GuardedBy("this")
private static synchronized IObjectCacheFactory initialize() {
// Double-check under lock
*/
public final class LazyCollections {
+ private LazyCollections() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
+
/**
* Add an element to a list, potentially transforming the list.
*
typedef iso-net-id {
description "ISO NET ID. RFC 1237";
type string {
- pattern '[0-9a-fA-F]{2}((.[0-9a-fA-F]{4}){6}*)';
+ pattern '[0-9a-fA-F]{2}((.[0-9a-fA-F]{4}){6})';
}
}
*/
package org.opendaylight.yangtools.restconf.common;
-public class MediaTypes {
+public final class MediaTypes {
+
+ private MediaTypes() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
+
public static final String API = "application/vnd.yang.api";
public static final String DATASTORE = "application/vnd.yang.datastore";
public static final String DATA = "application/vnd.yang.data";
.getAugmentation(IgpNodeAttributes1.class);
assertNotNull(igpAttributes1);
assertNotNull(igpAttributes1.getIsisNodeAttributes());
- assertEquals("66", igpAttributes1.getIsisNodeAttributes().getIso().getIsoSystemId().getValue());
+ assertEquals("0000.1111.2222", igpAttributes1.getIsisNodeAttributes().getIso().getIsoSystemId().getValue());
}
}
<router-id>42.42.42.42</router-id>
<isis-node-attributes xmlns="urn:TBD:params:xml:ns:yang:network:isis-topology">
<iso>
- <iso-system-id>66</iso-system-id>
+ <iso-system-id>0000.1111.2222</iso-system-id>
</iso>
<ted>
<te-router-id-ipv4>42.42.42.42</te-router-id-ipv4>
</isis-node-attributes>
</igp-node-attributes>
</node>
-</topology>
\ No newline at end of file
+</topology>
*
* @param id instance identifier
* @return key associated with the last component
+ * @throws IllegalArgumentException if the supplied identifier type cannot have a key.
+ * @throws NullPointerException if id is null.
*/
public static <N extends Identifiable<K> & DataObject, K extends Identifier<N>> K keyOf(final InstanceIdentifier<N> id) {
+ Preconditions.checkNotNull(id);
+ Preconditions.checkArgument(id instanceof KeyedInstanceIdentifier, "%s does not have a key", id);
+
@SuppressWarnings("unchecked")
final K ret = ((KeyedInstanceIdentifier<N, K>)id).getKey();
return ret;
*/
package org.opendaylight.yangtools.yang.common;
+import com.google.common.base.Objects;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
}
return compositeURI;
}
+
+ @Override
+ public String toString() {
+ return Objects.toStringHelper(this).omitNullValues().add("ns", getNamespace()).add("rev", getFormattedRevision()).toString();
+ }
}
import java.text.SimpleDateFormat;
-public class SimpleDateFormatUtil {
+public final class SimpleDateFormatUtil {
+
+ private SimpleDateFormatUtil() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
private static final ThreadLocal<SimpleDateFormat> REVISION_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+ @Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
};
+ @Override
public void set(SimpleDateFormat value) {
throw new UnsupportedOperationException();
};
*/
package org.opendaylight.yangtools.yang.data.composite.node.schema.json;
+import com.google.common.collect.LinkedListMultimap;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.api.Node;
-import com.google.common.collect.LinkedListMultimap;
+public final class CnSnToNormalizedNodesUtils {
-public class CnSnToNormalizedNodesUtils {
+
+ private CnSnToNormalizedNodesUtils() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
public static LinkedListMultimap<QName, Node<?>> mapChildElementsForSingletonNode(Node<?> node) {
return mapChildElements( ((CompositeNode)node).getValue());
<?xml version="1.0" encoding="UTF-8"?>
<!-- vi: set et smarttab sw=4 tabstop=4: -->
-<!--
- 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
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!-- 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 -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven.surefire.version}</version>
<configuration>
- <argLine>-Dlog4j.configuration=log4j-test.xml
- -Xmx1500m ${jacoco.agent.ut.arg}</argLine>
+ <argLine>-Dlog4j.configuration=log4j-test.xml
+ -Xmx1500m ${jacoco.agent.ut.arg}</argLine>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
</configuration>
</plugin>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
package org.opendaylight.yangtools.yang.data.impl.codec;
import java.util.Map.Entry;
-
import org.opendaylight.yangtools.yang.common.QName;
public class ValueWithQName<V> implements Entry<QName, V>{
return qname;
}
+ @Override
public V getValue() {
return value;
}
@SuppressWarnings("rawtypes")
ValueWithQName other = (ValueWithQName) obj;
if (qname == null) {
- if (other.qname != null)
+ if (other.qname != null) {
return false;
- } else if (!qname.equals(other.qname))
+ }
+ } else if (!qname.equals(other.qname)) {
return false;
+ }
if (value == null) {
if (other.value != null) {
return false;
import java.net.URI;
import java.util.Map.Entry;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
* {@link XMLStreamWriter}, resulting in a RFC 6020 XML encoding.
*/
public final class XMLStreamNormalizedNodeStreamWriter implements NormalizedNodeStreamWriter {
- private static final XmlStreamUtils UTILS = XmlStreamUtils.create(XmlUtils.DEFAULT_XML_CODEC_PROVIDER);
private final XMLStreamWriter writer;
private final SchemaTracker tracker;
+ private final XmlStreamUtils streamUtils;
private XMLStreamNormalizedNodeStreamWriter(final XMLStreamWriter writer, final SchemaContext context, final SchemaPath path) {
this.writer = Preconditions.checkNotNull(writer);
this.tracker = SchemaTracker.create(context, path);
+ this.streamUtils = XmlStreamUtils.create(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, context);
}
/**
try {
writeStartElement(qname);
if (value != null) {
- UTILS.writeValue(writer, type, value);
+ streamUtils.writeValue(writer, type, value);
+ }
+ writer.writeEndElement();
+ } catch (XMLStreamException e) {
+ throw new IOException("Failed to emit element", e);
+ }
+ }
+
+ private void writeElement(final QName qname, final SchemaNode schemaNode, final Object value) throws IOException {
+ try {
+ writeStartElement(qname);
+ if (value != null) {
+ streamUtils.writeValue(writer, schemaNode, value);
}
writer.writeEndElement();
} catch (XMLStreamException e) {
@Override
public void leafNode(final NodeIdentifier name, final Object value) throws IOException {
final LeafSchemaNode schema = tracker.leafNode(name);
-
- writeElement(schema.getQName(), schema.getType(), value);
+ writeElement(schema.getQName(), schema, value);
}
@Override
@Override
public void leafSetEntryNode(final Object value) throws IOException {
final LeafListSchemaNode schema = tracker.leafSetEntryNode();
- writeElement(schema.getQName(), schema.getType(), value);
+ writeElement(schema.getQName(), schema, value);
}
@Override
try {
writeStartElement(qname);
if (value != null) {
- UTILS.writeValue(writer, (Node<?>)value, schema);
+ streamUtils.writeValue(writer, (Node<?>)value, schema);
}
writer.writeEndElement();
} catch (XMLStreamException e) {
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
-
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-
import javax.activation.UnsupportedDataTypeException;
import javax.annotation.Nonnull;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.dom.DOMResult;
-
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
import org.opendaylight.yangtools.yang.data.api.CompositeNode;
import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
-public class XmlDocumentUtils {
+public final class XmlDocumentUtils {
+
+ private XmlDocumentUtils() {
+ throw new UnsupportedOperationException("Utility class should not be instantiated");
+ }
+
private static class ElementWithSchemaContext {
Element element;
SchemaContext schemaContext;
* Node Container Schema and transformed accordingly.
*
* @param data Data DOM root element
- * @param schema Data Node Container Schema
+ * @param schemaNode Data Node Container Schema
* @param codecProvider XML Codec Provider
* @return new instance of XML Document
* @throws UnsupportedDataTypeException
+ *
+ * @deprecated Use {@link #toDocument(org.opendaylight.yangtools.yang.data.api.CompositeNode, com.google.common.base.Optional, org.opendaylight.yangtools.yang.model.api.DataNodeContainer, XmlCodecProvider)} instead.
+ * The whole schema context allows for proper serialization of leafrefs.
+ */
+ @Deprecated
+ public static Document toDocument(final CompositeNode data, final DataNodeContainer schemaNode, final XmlCodecProvider codecProvider)
+ throws UnsupportedDataTypeException {
+ return toDocument(data, Optional.<SchemaContext>absent(), schemaNode, codecProvider);
+ }
+
+ /**
+ * Serializes data DOM node into a w3c DOM document. Whole schema context is used to resolve leafref elements.
+ *
+ * @param data Data DOM root element
+ * @param schemaContext Entire schema context for correct leafref resolution
+ * @param schema Data Node Container Schema
+ * @param codecProvider XML Codec Provider
+ * @return serialized w3c DOM document
+ * @throws UnsupportedDataTypeException
*/
- public static Document toDocument(final CompositeNode data, final DataNodeContainer schema, final XmlCodecProvider codecProvider)
+ public static Document toDocument(final CompositeNode data, final SchemaContext schemaContext, final DataNodeContainer schemaNode, final XmlCodecProvider codecProvider)
+ throws UnsupportedDataTypeException {
+ return toDocument(data, Optional.of(schemaContext), schemaNode, codecProvider);
+ }
+
+ private static Document toDocument(final CompositeNode data, final Optional<SchemaContext> schemaContext, final DataNodeContainer schema, final XmlCodecProvider codecProvider)
throws UnsupportedDataTypeException {
Preconditions.checkNotNull(data);
Preconditions.checkNotNull(schema);
final DOMResult result = new DOMResult(getDocument());
try {
final XMLStreamWriter writer = FACTORY.createXMLStreamWriter(result);
- XmlStreamUtils.create(codecProvider).writeDocument(writer, data, (SchemaNode)schema);
+ XmlStreamUtils xmlStreamUtils = schemaContext.isPresent() ? XmlStreamUtils.create(codecProvider, schemaContext.get()) : XmlStreamUtils.create(codecProvider);
+ xmlStreamUtils.writeDocument(writer, data, (SchemaNode) schema);
writer.close();
return (Document)result.getNode();
} catch (XMLStreamException e) {
return toSimpleNodeWithType(xmlElement, (LeafSchemaNode) schema, codecProvider,schemaCtx);
} else if (schema instanceof LeafListSchemaNode) {
return toSimpleNodeWithType(xmlElement, (LeafListSchemaNode) schema, codecProvider,schemaCtx);
+ } else if (schema instanceof AnyXmlSchemaNode) {
+ return toDomNode(xmlElement);
}
return null;
}
private static Object resolveValueFromSchemaType(final Element xmlElement, final DataSchemaNode schema, final TypeDefinition<?> type,
final XmlCodecProvider codecProvider,final SchemaContext schemaCtx) {
- final TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
+
+ TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
+ if (baseType instanceof LeafrefTypeDefinition) {
+ final LeafrefTypeDefinition leafrefTypeDefinition = (LeafrefTypeDefinition) baseType;
+ baseType = SchemaContextUtil.getBaseTypeForLeafRef(leafrefTypeDefinition, schemaCtx, schema);
+ }
+
final String text = xmlElement.getTextContent();
final Object value;
} else if (baseType instanceof IdentityrefTypeDefinition) {
value = InstanceIdentifierForXmlCodec.toIdentity(text, xmlElement, schemaCtx);
} else {
- final TypeDefinitionAwareCodec<?, ?> codec = codecProvider.codecFor(type);
+ final TypeDefinitionAwareCodec<?, ?> codec = codecProvider.codecFor(baseType);
if (codec == null) {
LOG.info("No codec for schema {}, falling back to text", schema);
value = text;
import com.google.common.annotations.Beta;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import java.net.URI;
import java.util.Collection;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class XmlStreamUtils {
private static final Logger LOG = LoggerFactory.getLogger(XmlStreamUtils.class);
private final XmlCodecProvider codecProvider;
+ private final Optional<SchemaContext> schemaContext;
protected XmlStreamUtils(final XmlCodecProvider codecProvider) {
+ this(codecProvider, null);
+ }
+
+ private XmlStreamUtils(XmlCodecProvider codecProvider, SchemaContext schemaContext) {
this.codecProvider = Preconditions.checkNotNull(codecProvider);
+ this.schemaContext = Optional.fromNullable(schemaContext);
}
/**
if (data instanceof SimpleNode<?>) {
// Simple node
- if (schema instanceof LeafListSchemaNode) {
- writeValue(writer, ((LeafListSchemaNode) schema).getType(), data.getValue());
- } else if (schema instanceof LeafSchemaNode) {
- writeValue(writer, ((LeafSchemaNode) schema).getType(), data.getValue());
+ if (schema instanceof LeafListSchemaNode || schema instanceof LeafSchemaNode) {
+ writeValue(writer, schema, data.getValue());
} else {
Object value = data.getValue();
if (value != null) {
* emitted by the caller.
*
* @param writer XML Stream writer
- * @param type data type
+ * @param schemaNode Schema node that describes the value
+ * @param value data value
+ * @throws XMLStreamException if an encoding problem occurs
+ */
+ public void writeValue(final @Nonnull XMLStreamWriter writer, final @Nonnull SchemaNode schemaNode, final Object value) throws XMLStreamException {
+ if (value == null) {
+ LOG.debug("Value of {}:{} is null, not encoding it", schemaNode.getQName().getNamespace(), schemaNode.getQName().getLocalName());
+ return;
+ }
+
+ Preconditions.checkArgument(schemaNode instanceof LeafSchemaNode || schemaNode instanceof LeafListSchemaNode,
+ "Unable to write value for node %s, only nodes of type: leaf and leaf-list can be written at this point", schemaNode.getQName());
+
+ TypeDefinition<?> type = schemaNode instanceof LeafSchemaNode ?
+ ((LeafSchemaNode) schemaNode).getType():
+ ((LeafListSchemaNode) schemaNode).getType();
+
+ TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
+
+ if (schemaContext.isPresent() && baseType instanceof LeafrefTypeDefinition) {
+ LeafrefTypeDefinition leafrefTypeDefinition = (LeafrefTypeDefinition) baseType;
+ baseType = SchemaContextUtil.getBaseTypeForLeafRef(leafrefTypeDefinition, schemaContext.get(), schemaNode);
+ }
+
+ writeValue(writer, baseType, value);
+ }
+
+ /**
+ * Write a value into a XML stream writer. This method assumes the start and end of element is
+ * emitted by the caller.
+ *
+ * @param writer XML Stream writer
+ * @param type data type. In case of leaf ref this should be the type of leaf being referenced
* @param value data value
* @throws XMLStreamException if an encoding problem occurs
*/
LOG.debug("Value of {}:{} is null, not encoding it", type.getQName().getNamespace(), type.getQName().getLocalName());
return;
}
+ TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
- final TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
if (baseType instanceof IdentityrefTypeDefinition) {
write(writer, (IdentityrefTypeDefinition) baseType, value);
} else if (baseType instanceof InstanceIdentifierTypeDefinition) {
writer.writeCharacters(String.valueOf(value));
}
}
+
+ public static XmlStreamUtils create(XmlCodecProvider codecProvider, SchemaContext schemaContext) {
+ return new XmlStreamUtils(codecProvider, schemaContext);
+ }
}
import org.opendaylight.yangtools.yang.data.api.Node;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.Node;
import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
package org.opendaylight.yangtools.yang.data.impl.schema;
import com.google.common.base.Preconditions;
-
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;
-
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.ListNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableAugmentationNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableOrderedMapNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListNodeBuilder;
/**
* <p>
* This method is useful for clients, which knows there will be one
* top level node written, but does not know which type of {@link NormalizedNode}
- * will be writen.
- *
+ * will be written.
*
* @param result {@link NormalizedNodeResult} object which will hold result value.
- * @return {@link NormalizedNodeStreamWriter} whcih will write item to supplied result holder.
+ * @return {@link NormalizedNodeStreamWriter} which will write item to supplied result holder.
*/
public static final NormalizedNodeStreamWriter from(final NormalizedNodeResult result) {
return new ImmutableNormalizedNodeStreamWriter(new NormalizedNodeResultBuilder(result));
}
@Override
- public void startLeafSet(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+ public void startLeafSet(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
checkDataNodeContainer();
- ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder = Builders.leafSetBuilder();
+ ListNodeBuilder<Object, LeafSetEntryNode<Object>> builder = UNKNOWN_SIZE == childSizeHint ?
+ ImmutableLeafSetNodeBuilder.create() : ImmutableLeafSetNodeBuilder.create(childSizeHint);
builder.withNodeIdentifier(name);
enter(builder);
}
@Override
public void anyxmlNode(final NodeIdentifier name, final Object value) throws IllegalArgumentException {
checkDataNodeContainer();
-
-
}
@Override
- public void startContainerNode(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+ public void startContainerNode(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
checkDataNodeContainer();
- enter(Builders.containerBuilder().withNodeIdentifier(name));
+
+ final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> builder = UNKNOWN_SIZE == childSizeHint ?
+ ImmutableContainerNodeBuilder.create() : ImmutableContainerNodeBuilder.create(childSizeHint);
+ enter(builder.withNodeIdentifier(name));
}
@Override
- public void startUnkeyedList(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+ public void startUnkeyedList(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
checkDataNodeContainer();
- enter(Builders.unkeyedListBuilder().withNodeIdentifier(name));
+
+ final CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> builder = UNKNOWN_SIZE == childSizeHint ?
+ ImmutableUnkeyedListNodeBuilder.create() : ImmutableUnkeyedListNodeBuilder.create(childSizeHint);
+ enter(builder.withNodeIdentifier(name));
}
@Override
- public void startUnkeyedListItem(final NodeIdentifier name,final int childSizeHint) throws IllegalStateException {
+ public void startUnkeyedListItem(final NodeIdentifier name, final int childSizeHint) throws IllegalStateException {
Preconditions.checkArgument(getCurrent() instanceof ImmutableUnkeyedListNodeBuilder);
- enter(Builders.unkeyedListEntryBuilder().withNodeIdentifier(name));
+
+ final DataContainerNodeAttrBuilder<NodeIdentifier, UnkeyedListEntryNode> builder = UNKNOWN_SIZE == childSizeHint ?
+ ImmutableUnkeyedListEntryNodeBuilder.create() : ImmutableUnkeyedListEntryNodeBuilder.create(childSizeHint);
+ enter(builder.withNodeIdentifier(name));
}
@Override
- public void startMapNode(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+ public void startMapNode(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
checkDataNodeContainer();
- enter(Builders.mapBuilder().withNodeIdentifier(name));
+
+ final CollectionNodeBuilder<MapEntryNode, MapNode> builder = UNKNOWN_SIZE == childSizeHint ?
+ ImmutableMapNodeBuilder.create() : ImmutableMapNodeBuilder.create(childSizeHint);
+ enter(builder.withNodeIdentifier(name));
}
@Override
- public void startMapEntryNode(final NodeIdentifierWithPredicates identifier,final int childSizeHint) throws IllegalArgumentException {
+ public void startMapEntryNode(final NodeIdentifierWithPredicates identifier, final int childSizeHint) throws IllegalArgumentException {
if(!(getCurrent() instanceof NormalizedNodeResultBuilder)) {
Preconditions.checkArgument(getCurrent() instanceof ImmutableMapNodeBuilder || getCurrent() instanceof ImmutableOrderedMapNodeBuilder);
}
- enter(Builders.mapEntryBuilder().withNodeIdentifier(identifier));
+
+ final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder = UNKNOWN_SIZE == childSizeHint ?
+ ImmutableMapEntryNodeBuilder.create() : ImmutableMapEntryNodeBuilder.create(childSizeHint);
+ enter(builder.withNodeIdentifier(identifier));
}
@Override
- public void startOrderedMapNode(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+ public void startOrderedMapNode(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
checkDataNodeContainer();
- enter(Builders.orderedMapBuilder().withNodeIdentifier(name));
+
+ final CollectionNodeBuilder<MapEntryNode, OrderedMapNode> builder = UNKNOWN_SIZE == childSizeHint ?
+ ImmutableOrderedMapNodeBuilder.create() : ImmutableOrderedMapNodeBuilder.create(childSizeHint);
+ enter(builder.withNodeIdentifier(name));
}
@Override
- public void startChoiceNode(final NodeIdentifier name,final int childSizeHint) throws IllegalArgumentException {
+ public void startChoiceNode(final NodeIdentifier name, final int childSizeHint) throws IllegalArgumentException {
checkDataNodeContainer();
- enter(Builders.choiceBuilder().withNodeIdentifier(name));
+
+ final DataContainerNodeBuilder<NodeIdentifier, ChoiceNode> builder = UNKNOWN_SIZE == childSizeHint ?
+ ImmutableChoiceNodeBuilder.create() : ImmutableChoiceNodeBuilder.create(childSizeHint);
+ enter(builder.withNodeIdentifier(name));
}
+
@Override
public void startAugmentationNode(final AugmentationIdentifier identifier) throws IllegalArgumentException {
checkDataNodeContainer();
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableDataContainerNode;
abstract class AbstractImmutableDataContainerNodeBuilder<I extends YangInstanceIdentifier.PathArgument, R extends DataContainerNode<I>> implements DataContainerNodeBuilder<I, R> {
-
+ private static final int DEFAULT_CAPACITY = 4;
private Map<YangInstanceIdentifier.PathArgument, DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?>> value;
private I nodeIdentifier;
private boolean dirty;
protected AbstractImmutableDataContainerNodeBuilder() {
- this.value = new HashMap<>();
+ this.value = new HashMap<>(DEFAULT_CAPACITY);
this.dirty = false;
}
protected AbstractImmutableDataContainerNodeBuilder(final int sizeHint) {
- this.value = new HashMap<>(sizeHint);
+ this.value = new HashMap<>(DEFAULT_CAPACITY);
this.dirty = false;
}
protected AbstractImmutableDataContainerNodeBuilder(final AbstractImmutableDataContainerNode<I> node) {
this.nodeIdentifier = node.getIdentifier();
+
+ /*
+ * FIXME: BUG-2402: this call is not what we actually want. We are the
+ * only user of getChildren(), and we really want this to be a
+ * zero-copy operation if we happen to not modify the children.
+ * If we do, we want to perform an efficient copy-on-write before
+ * we make the change.
+ *
+ * With this interface we end up creating a lot of short-lived
+ * objects in case we modify the map -- see checkDirty().
+ */
this.value = node.getChildren();
this.dirty = true;
}
private void checkDirty() {
if (dirty) {
+ /*
+ * FIXME: BUG-2402: This is the second part of the above. Note
+ * that value here is usually a read-only view. Invocation
+ * of this constructor will force instantiation of a wrapper
+ * Map.Entry object, just to make sure this read path does
+ * not modify the map.
+ */
value = new HashMap<>(value);
dirty = false;
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
+import com.google.common.base.Preconditions;
import java.util.Map;
-
+import java.util.Objects;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedValueAttrNode;
-import com.google.common.base.Preconditions;
-
public class ImmutableLeafSetEntryNodeBuilder<T> extends AbstractImmutableNormalizedNodeBuilder<YangInstanceIdentifier.NodeWithValue, T, LeafSetEntryNode<T>> {
public static <T> ImmutableLeafSetEntryNodeBuilder<T> create() {
ImmutableLeafSetEntryNode(final YangInstanceIdentifier.NodeWithValue nodeIdentifier, final T value, final Map<QName, String> attributes) {
super(nodeIdentifier, value, attributes);
- Preconditions.checkArgument(nodeIdentifier.getValue().equals(value),
+ Preconditions.checkArgument(Objects.deepEquals(nodeIdentifier.getValue(), value),
"Node identifier contains different value: %s than value itself: %s", nodeIdentifier, value);
}
}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.util.MapAdaptor;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedValueNode;
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
-
public class ImmutableLeafSetNodeBuilder<T> implements ListNodeBuilder<T, LeafSetEntryNode<T>> {
-
+ private static final int DEFAULT_CAPACITY = 4;
private final Map<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<T>> value;
private YangInstanceIdentifier.NodeIdentifier nodeIdentifier;
protected ImmutableLeafSetNodeBuilder() {
- value = new HashMap<>();
+ value = new HashMap<>(DEFAULT_CAPACITY);
+ }
+
+ protected ImmutableLeafSetNodeBuilder(final int sizeHint) {
+ value = new HashMap<>(sizeHint * 4 / 3);
}
protected ImmutableLeafSetNodeBuilder(final ImmutableLeafSetNode<T> node) {
return new ImmutableLeafSetNodeBuilder<>();
}
+ public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> create(final int sizeHint) {
+ return new ImmutableLeafSetNodeBuilder<>(sizeHint);
+ }
+
public static <T> ListNodeBuilder<T, LeafSetEntryNode<T>> create(final LeafSetNode<T> node) {
if (!(node instanceof ImmutableLeafSetNode<?>)) {
throw new UnsupportedOperationException(String.format("Cannot initialize from class %s", node.getClass()));
*/
package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.util.MapAdaptor;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
-import com.google.common.base.Optional;
-import com.google.common.collect.Iterables;
-
-public class ImmutableMapNodeBuilder
- implements CollectionNodeBuilder<MapEntryNode, MapNode> {
-
+public class ImmutableMapNodeBuilder implements CollectionNodeBuilder<MapEntryNode, MapNode> {
+ private static final int DEFAULT_CAPACITY = 4;
private final Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> value;
private YangInstanceIdentifier.NodeIdentifier nodeIdentifier;
protected ImmutableMapNodeBuilder() {
- this.value = new HashMap<>();
+ this.value = new HashMap<>(DEFAULT_CAPACITY);
+ }
+
+ protected ImmutableMapNodeBuilder(final int sizeHint) {
+ this.value = new HashMap<>(DEFAULT_CAPACITY);
}
protected ImmutableMapNodeBuilder(final ImmutableMapNode node) {
return new ImmutableMapNodeBuilder();
}
+ public static CollectionNodeBuilder<MapEntryNode, MapNode> create(final int sizeHint) {
+ return new ImmutableMapNodeBuilder(sizeHint);
+ }
+
public static CollectionNodeBuilder<MapEntryNode, MapNode> create(final MapNode node) {
if (!(node instanceof ImmutableMapNode)) {
throw new UnsupportedOperationException(String.format("Cannot initialize from class %s", node.getClass()));
return Optional.fromNullable(children.get(child));
}
- @Override
- public Iterable<MapEntryNode> getValue() {
- return Iterables.unmodifiableIterable(children.values());
- }
+ @Override
+ public Iterable<MapEntryNode> getValue() {
+ return Iterables.unmodifiableIterable(children.values());
+ }
@Override
protected int valueHashCode() {
import com.google.common.base.Optional;
import com.google.common.collect.Iterables;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeContainerBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ImmutableOrderedMapNodeBuilder
- implements CollectionNodeBuilder<MapEntryNode, OrderedMapNode> {
-
+public class ImmutableOrderedMapNodeBuilder implements CollectionNodeBuilder<MapEntryNode, OrderedMapNode> {
+ private static final int DEFAULT_CAPACITY = 4;
private Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> value;
private YangInstanceIdentifier.NodeIdentifier nodeIdentifier;
- private boolean dirty = false;
+ private boolean dirty;
protected ImmutableOrderedMapNodeBuilder() {
- this.value = new LinkedHashMap<>();
+ this.value = new LinkedHashMap<>(DEFAULT_CAPACITY);
+ this.dirty = false;
+ }
+
+ protected ImmutableOrderedMapNodeBuilder(final int sizeHint) {
+ this.value = new LinkedHashMap<>(DEFAULT_CAPACITY);
this.dirty = false;
}
return new ImmutableOrderedMapNodeBuilder();
}
+ public static CollectionNodeBuilder<MapEntryNode, OrderedMapNode> create(final int sizeHint) {
+ return new ImmutableOrderedMapNodeBuilder(sizeHint);
+ }
+
public static CollectionNodeBuilder<MapEntryNode, OrderedMapNode> create(final MapNode node) {
if (!(node instanceof ImmutableOrderedMapNode)) {
throw new UnsupportedOperationException(String.format("Cannot initialize from class %s", node.getClass()));
return children.size();
}
- @Override
- public Iterable<MapEntryNode> getValue() {
- return Iterables.unmodifiableIterable(children.values());
- }
+ @Override
+ public Iterable<MapEntryNode> getValue() {
+ return Iterables.unmodifiableIterable(children.values());
+ }
}
}
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid.DataValidationException;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import com.google.common.base.Preconditions;
-
public class ImmutableOrderedMapNodeSchemaAwareBuilder extends ImmutableOrderedMapNodeBuilder {
private final ListSchemaNode schema;
*/
package org.opendaylight.yangtools.yang.data.impl.schema.builder.impl;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.nodes.AbstractImmutableNormalizedValueNode;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-
public class ImmutableUnkeyedListNodeBuilder implements CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> {
-
private List<UnkeyedListEntryNode> value;
private YangInstanceIdentifier.NodeIdentifier nodeIdentifier;
- private boolean dirty = false;
+ private boolean dirty;
protected ImmutableUnkeyedListNodeBuilder() {
this.value = new LinkedList<>();
return new ImmutableUnkeyedListNodeBuilder();
}
+ public static CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> create(final int sizeHint) {
+ return new ImmutableUnkeyedListNodeBuilder();
+ }
+
public static CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> create(final UnkeyedListNode node) {
if (!(node instanceof ImmutableUnkeyedListNode)) {
throw new UnsupportedOperationException(String.format("Cannot initialize from class %s", node.getClass()));
@Override
public UnkeyedListNode build() {
dirty = true;
- return new ImmutableUnkeyedListNode(nodeIdentifier, ImmutableList.copyOf(value));
+ if (value.isEmpty()) {
+ return new EmptyImmutableUnkeyedListNode(nodeIdentifier);
+ } else {
+ return new ImmutableUnkeyedListNode(nodeIdentifier, ImmutableList.copyOf(value));
+ }
}
@Override
return withoutChild(key);
}
+ protected static final class EmptyImmutableUnkeyedListNode extends AbstractImmutableNormalizedNode<YangInstanceIdentifier.NodeIdentifier, Iterable<UnkeyedListEntryNode>> implements Immutable, UnkeyedListNode {
+ protected EmptyImmutableUnkeyedListNode(final NodeIdentifier nodeIdentifier) {
+ super(nodeIdentifier);
+ }
+
+ @Override
+ public Iterable<UnkeyedListEntryNode> getValue() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public UnkeyedListEntryNode getChild(final int position) {
+ return null;
+ }
+
+ @Override
+ public int getSize() {
+ return 0;
+ }
+
+ @Override
+ protected boolean valueEquals(final AbstractImmutableNormalizedNode<?, ?> other) {
+ return Collections.EMPTY_LIST.equals(other.getValue());
+ }
+
+ @Override
+ protected int valueHashCode() {
+ return Collections.EMPTY_LIST.hashCode();
+ }
+ }
+
protected static final class ImmutableUnkeyedListNode extends
AbstractImmutableNormalizedValueNode<YangInstanceIdentifier.NodeIdentifier, Iterable<UnkeyedListEntryNode>>
implements Immutable, UnkeyedListNode {
package org.opendaylight.yangtools.yang.data.impl.schema.nodes;
import com.google.common.base.Optional;
-
-import java.util.Collections;
import java.util.Map;
-
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public abstract class AbstractImmutableDataContainerNode<K extends PathArgument> extends AbstractImmutableNormalizedNode<K, Iterable<DataContainerChild<? extends PathArgument, ?>>> implements Immutable, DataContainerNode<K> {
- private static final Logger LOG = LoggerFactory.getLogger(AbstractImmutableDataContainerNode.class);
private final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> children;
public AbstractImmutableDataContainerNode(
final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> children, final K nodeIdentifier) {
super(nodeIdentifier);
- /*
- * There is a code path where AbstractImmutableDataContainerNodeBuilder can reflect
- * the collection acquired via getChildren() back to us. This is typically the case
- * in the datastore where transactions cancel each other out, leaving an unmodified
- * node. In that case we want to skip wrapping the map again (and again and again).
- *
- * In a perfect world, Collection.unmodifiableMap() would be doing the instanceof
- * check which would stop the proliferation. Unfortunately this not the case and the
- * 'unmodifiable' trait is not exposed by anything we can query. Furthermore the API
- * contract there is sufficiently vague so an implementation may actually return a
- * different implementation based on input map -- for example
- * Collections.unmodifiableMap(Collections.emptyMap()) returning the same thing as
- * Collections.emptyMap().
- *
- * This means that we have to perform the instantiation here (as opposed to once at
- * class load time) and then compare the classes.
- */
- final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> pub = Collections.unmodifiableMap(children);
- if (children.getClass().equals(pub.getClass())) {
- LOG.trace("Reusing already-unmodifiable children {}", children);
- this.children = children;
- } else {
- this.children = pub;
- }
+ this.children = UnmodifiableChildrenMap.create(children);
}
@Override
return children.hashCode();
}
+ /**
+ * DO NOT USE THIS METHOD.
+ *
+ * This is an implementation-internal API and no outside users should use it. If you do,
+ * you are asking for trouble, as the returned object is not guaranteed to conform to
+ * java.util.Map interface.
+ *
+ * @return An unmodifiable view if this node's children.
+ */
public final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> getChildren() {
return children;
}
import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper;
import com.google.common.collect.ImmutableMap;
+
+import java.util.Arrays;
import java.util.Map;
+
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@Override
protected boolean valueEquals(final AbstractImmutableNormalizedNode<?, ?> other) {
- // We can not call directly getValue.equals because of Empty Type Definition leaves
- // which allways have NULL value
- if (!Objects.equal(getValue(), other.getValue())) {
+ // We can not call directly getValue.equals because of Empty Type
+ // Definition leaves which allways have NULL value
+
+ if (!java.util.Objects.deepEquals(getValue(), other.getValue())) {
return false;
}
-// FIXME: are attributes part of hashCode/equals?
-// final Set<Entry<QName, String>> tas = getAttributes().entrySet();
-// final Set<Entry<QName, String>> oas = container.getAttributes().entrySet();
-//
-// return tas.containsAll(oas) && oas.containsAll(tas);
+ // FIXME: are attributes part of hashCode/equals?
+ // final Set<Entry<QName, String>> tas = getAttributes().entrySet();
+ // final Set<Entry<QName, String>> oas =
+ // container.getAttributes().entrySet();
+ //
+ // return tas.containsAll(oas) && oas.containsAll(tas);
return true;
}
+
}
--- /dev/null
+/*
+ * Copyright (c) 2014 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.yang.data.impl.schema.nodes;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+
+/**
+ * Internal equivalent of {@link Collections}' unmodifiable Map. It does not retain
+ * keySet/entrySet references, thus lowering the memory overhead.
+ */
+final class UnmodifiableChildrenMap implements Map<PathArgument, DataContainerChild<? extends PathArgument, ?>>, Serializable {
+ private static final long serialVersionUID = 1L;
+ private final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> delegate;
+ private transient Collection<DataContainerChild<? extends PathArgument, ?>> values;
+
+ private UnmodifiableChildrenMap(final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> delegate) {
+ this.delegate = Preconditions.checkNotNull(delegate);
+ }
+
+ /**
+ * Create an unmodifiable view of a particular map. Does not perform unnecessary
+ * encapsulation if the map is known to be already unmodifiable.
+ *
+ * @param map Backing map
+ * @return Unmodifiable view
+ */
+ static Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> create(final Map<PathArgument, DataContainerChild<? extends PathArgument, ?>> map) {
+ if (map instanceof UnmodifiableChildrenMap) {
+ return map;
+ }
+ if (map instanceof ImmutableMap) {
+ return map;
+ }
+ if (map.isEmpty()) {
+ return Collections.emptyMap();
+ }
+
+ return new UnmodifiableChildrenMap(map);
+ }
+
+ @Override
+ public int size() {
+ return delegate.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return delegate.isEmpty();
+ }
+
+ @Override
+ public boolean containsKey(final Object key) {
+ return delegate.containsKey(key);
+ }
+
+ @Override
+ public boolean containsValue(final Object value) {
+ return delegate.containsValue(value);
+ }
+
+ @Override
+ public DataContainerChild<? extends PathArgument, ?> get(final Object key) {
+ return delegate.get(key);
+ }
+
+ @Override
+ public DataContainerChild<? extends PathArgument, ?> put(final PathArgument key,
+ final DataContainerChild<? extends PathArgument, ?> value) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public DataContainerChild<? extends PathArgument, ?> remove(final Object key) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void putAll(final Map<? extends PathArgument, ? extends DataContainerChild<? extends PathArgument, ?>> m) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<PathArgument> keySet() {
+ return Collections.unmodifiableSet(delegate.keySet());
+ }
+
+ @Override
+ public Collection<DataContainerChild<? extends PathArgument, ?>> values() {
+ if (values == null) {
+ values = Collections.unmodifiableCollection(delegate.values());
+ }
+ return values;
+ }
+
+ @Override
+ public Set<Entry<PathArgument, DataContainerChild<? extends PathArgument, ?>>> entrySet() {
+ /*
+ * Okay, this is not as efficient as it could be -- we could save ourselves the
+ * map instantiation. The cost of that would be re-implementation of a read-only
+ * Map.Entry to ensure our delegate is never modified.
+ *
+ * Let's skip that and use whatever the JRE gives us instead.
+ */
+ return Collections.unmodifiableMap(delegate).entrySet();
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ return this == o || delegate.equals(o);
+ }
+
+ @Override
+ public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return delegate.toString();
+ }
+}
*/
package org.opendaylight.yangtools.yang.data.impl.schema.tree;
+import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
+import java.util.Map;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.OrderedLeafSetNode;
import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
import org.opendaylight.yangtools.yang.data.api.schema.tree.ModifiedNodeDoesNotExistException;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MutableTreeNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-import java.util.Map;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
abstract class NormalizedNodeContainerModificationStrategy extends SchemaAwareApplyOperation {
private final Class<? extends NormalizedNode<?, ?>> nodeClass;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
-
import java.util.AbstractMap.SimpleEntry;
import java.util.Iterator;
import java.util.Map;
-
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
nesting++;
}
if(current.isPresent()) {
- final YangInstanceIdentifier currentPath = YangInstanceIdentifier.create(path.getPath().subList(0, nesting));
+ final YangInstanceIdentifier currentPath = YangInstanceIdentifier.create(Iterables.limit(path.getPathArguments(), nesting));
return new SimpleEntry<YangInstanceIdentifier,T>(currentPath,current.get());
}
* present. At any rate we check state just to be on the safe side.
*/
Preconditions.checkState(nesting > 0);
- final YangInstanceIdentifier parentPath = YangInstanceIdentifier.create(path.getPath().subList(0, nesting - 1));
-
+ final YangInstanceIdentifier parentPath = YangInstanceIdentifier.create(Iterables.limit(path.getPathArguments(), nesting - 1));
return new SimpleEntry<YangInstanceIdentifier,T>(parentPath,parent.get());
}
package org.opendaylight.yangtools.yang.data.impl.codec.xml;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.AbstractMap;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
-
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
-
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.data.api.Node;
-import org.opendaylight.yangtools.yang.data.api.SimpleNode;
import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
-import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
-import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.InstanceIdentifierType;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.opendaylight.yangtools.yang.model.util.StringType;
import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.w3c.dom.Document;
public static final XMLOutputFactory XML_OUTPUT_FACTORY = XMLOutputFactory.newFactory();
+ private static SchemaContext schemaContext;
+ private static Module leafRefModule;
+
+ @BeforeClass
+ public static void initialize() throws URISyntaxException {
+ final YangParserImpl yangParser = new YangParserImpl();
+ final File file = new File(XmlStreamUtils.class.getResource("/leafref-test.yang").toURI());
+ schemaContext = yangParser.parseFiles(Arrays.asList(file));
+ assertNotNull(schemaContext);
+ assertEquals(1,schemaContext.getModules().size());
+ leafRefModule = schemaContext.getModules().iterator().next();
+ assertNotNull(leafRefModule);
+ }
+
+
@Test
public void testWriteAttribute() throws Exception {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
assertTrue("Xml differs: " + diff.toString(), identical);
}
+ /**
+ * One leafref reference to other leafref via relative references
+ */
+ @Test
+ public void testLeafRefRelativeChaining() {
+ getTargetNodeForLeafRef("leafname3",StringType.class);
+ }
+
+ @Test
+ public void testLeafRefRelative() {
+ getTargetNodeForLeafRef("pointToStringLeaf",StringType.class);
+ }
+
+ @Test
+ public void testLeafRefAbsoluteWithSameTarget() {
+ getTargetNodeForLeafRef("absname",InstanceIdentifierType.class);
+ }
+
+ /**
+ * Tests relative path with double point inside path (e. g. "../../lf:interface/../lf:cont2/lf:stringleaf")
+ */
+ @Ignore //ignored because this isn't implemented
+ @Test
+ public void testLeafRefWithDoublePointInPath() {
+ getTargetNodeForLeafRef("lf-with-double-point-inside",StringType.class);
+ }
+
+ @Test
+ public void testLeafRefRelativeAndAbsoluteWithSameTarget() {
+ final TypeDefinition<?> targetNodeForAbsname = getTargetNodeForLeafRef("absname",InstanceIdentifierType.class);
+ final TypeDefinition<?> targetNodeForRelname = getTargetNodeForLeafRef("relname",InstanceIdentifierType.class);
+ assertEquals(targetNodeForAbsname, targetNodeForRelname);
+ }
+
+ private TypeDefinition<?> getTargetNodeForLeafRef(final String nodeName, final Class<?> clas) {
+ final LeafSchemaNode schemaNode = findSchemaNodeWithLeafrefType(leafRefModule, nodeName);
+ assertNotNull(schemaNode);
+ final LeafrefTypeDefinition leafrefTypedef = findLeafrefType(schemaNode);
+ assertNotNull(leafrefTypedef);
+ final TypeDefinition<?> targetBaseType = SchemaContextUtil.getBaseTypeForLeafRef(leafrefTypedef, schemaContext, schemaNode);
+ assertEquals("Wrong class found.", clas, targetBaseType.getClass());
+ return targetBaseType;
+ }
+
@Test
public void testEmptyNodeWithAttribute() throws Exception {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
return QName.create(namespace, revision, localName);
}
}
-}
+
+ private LeafSchemaNode findSchemaNodeWithLeafrefType(final DataNodeContainer module, final String nodeName) {
+ for (final DataSchemaNode childNode : module.getChildNodes()) {
+ if (childNode instanceof DataNodeContainer) {
+ LeafSchemaNode leafrefFromRecursion = findSchemaNodeWithLeafrefType((DataNodeContainer)childNode, nodeName);
+ if (leafrefFromRecursion != null) {
+ return leafrefFromRecursion;
+ }
+ } else if (childNode.getQName().getLocalName().equals(nodeName) && childNode instanceof LeafSchemaNode) {
+ final TypeDefinition<?> leafSchemaNodeType = ((LeafSchemaNode)childNode).getType();
+ if (leafSchemaNodeType instanceof LeafrefTypeDefinition) {
+ return (LeafSchemaNode)childNode;
+ }
+ }
+ }
+ return null;
+ }
+
+ private LeafrefTypeDefinition findLeafrefType(final LeafSchemaNode schemaNode) {
+ final TypeDefinition<?> type = schemaNode.getType();
+ if (type instanceof LeafrefTypeDefinition) {
+ return (LeafrefTypeDefinition)type;
+ }
+ return null;
+ }
+}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ */
+package org.opendaylight.yangtools.yang.data.impl.schema.nodes;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+
+public class AbstractImmutableNormalizedValueAttrNodeTest {
+
+ private static QName ROOT_QNAME = QName.create("urn:test", "2014-03-13",
+ "root");
+ private static QName LEAF_QNAME = QName.create(ROOT_QNAME, "my-leaf");
+ private static QName SAME_LEAF_QNAME = QName.create(ROOT_QNAME, "my-leaf");
+ private static QName OTHER_LEAF_QNAME = QName.create(ROOT_QNAME,
+ "my-other-leaf");
+
+ @Test
+ public void equalsByteTest() {
+
+ byte[] valueNull = null;
+ byte[] equalValueNull = null;
+
+ LeafNode<byte[]> leafNodeNull = ImmutableNodes.leafNode(LEAF_QNAME,
+ valueNull);
+ LeafNode<byte[]> equalLeafNodeNull = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValueNull);
+
+ assertTrue(leafNodeNull.equals(leafNodeNull));
+ assertTrue(leafNodeNull.equals(equalLeafNodeNull));
+ assertTrue(equalLeafNodeNull.equals(leafNodeNull));
+
+ byte[] value = "test".getBytes();
+ byte[] equalValue = "test".getBytes();
+
+ LeafNode<byte[]> leafNode = ImmutableNodes.leafNode(LEAF_QNAME, value);
+ LeafNode<byte[]> equalLeafNode = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue);
+
+ assertTrue(leafNode.equals(leafNode));
+ assertTrue(leafNode.equals(equalLeafNode));
+ assertTrue(equalLeafNode.equals(leafNode));
+
+ Byte[] value2 = new Byte[] { new Byte("1"), new Byte("2") };
+ Byte[] equalValue2 = new Byte[] { new Byte("1"), new Byte("2") };
+
+ LeafNode<Byte[]> leafNode2 = ImmutableNodes
+ .leafNode(LEAF_QNAME, value2);
+ LeafNode<Byte[]> equalLeafNode2 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue2);
+
+ assertTrue(leafNode2.equals(leafNode2));
+ assertTrue(leafNode2.equals(equalLeafNode2));
+ assertTrue(equalLeafNode2.equals(leafNode2));
+
+ byte[][] value3 = new byte[][] { "test".getBytes(), "test2".getBytes() };
+ byte[][] equalValue3 = new byte[][] { "test".getBytes(),
+ "test2".getBytes() };
+
+ LeafNode<byte[][]> leafNode3 = ImmutableNodes.leafNode(LEAF_QNAME,
+ value3);
+ LeafNode<byte[][]> equalLeafNode3 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue3);
+
+ assertTrue(leafNode3.equals(leafNode3));
+ assertTrue(leafNode3.equals(equalLeafNode3));
+ assertTrue(equalLeafNode3.equals(leafNode3));
+
+ Byte[][] value4 = new Byte[][] {
+ new Byte[] { new Byte("1"), new Byte("2") },
+ new Byte[] { new Byte("3"), new Byte("4") } };
+ Byte[][] equalValue4 = new Byte[][] {
+ new Byte[] { new Byte("1"), new Byte("2") },
+ new Byte[] { new Byte("3"), new Byte("4") } };
+
+ LeafNode<Byte[][]> leafNode4 = ImmutableNodes.leafNode(LEAF_QNAME,
+ value4);
+ LeafNode<Byte[][]> equalLeafNode4 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue4);
+
+ assertTrue(leafNode4.equals(leafNode4));
+ assertTrue(leafNode4.equals(equalLeafNode4));
+ assertTrue(equalLeafNode4.equals(leafNode4));
+
+ Byte value6 = new Byte("1");
+ Byte equalValue6 = new Byte("1");
+
+ LeafNode<Byte> leafNode6 = ImmutableNodes.leafNode(LEAF_QNAME, value6);
+ LeafNode<Byte> equalLeafNode6 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue6);
+
+ assertTrue(leafNode6.equals(leafNode6));
+ assertTrue(leafNode6.equals(equalLeafNode6));
+ assertTrue(equalLeafNode6.equals(leafNode6));
+
+ String value5 = new String("test");
+ String equalValue5 = new String("test");
+
+ LeafNode<String> leafNode5 = ImmutableNodes
+ .leafNode(LEAF_QNAME, value5);
+ LeafNode<String> equalLeafNode5 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue5);
+
+ assertTrue(leafNode5.equals(leafNode5));
+ assertTrue(leafNode5.equals(equalLeafNode5));
+ assertTrue(equalLeafNode5.equals(leafNode5));
+
+ }
+
+ @Test
+ public void notEqualByteTest() {
+
+ byte[] value = "test".getBytes();
+ byte[] equalValue = "test".getBytes();
+
+ LeafNode<byte[]> leafNode = ImmutableNodes.leafNode(LEAF_QNAME, value);
+ LeafNode<byte[]> otherLeafNode = ImmutableNodes.leafNode(
+ OTHER_LEAF_QNAME, equalValue);
+
+ assertFalse(leafNode.equals(null));
+ assertFalse(leafNode.equals(new Object()));
+ assertFalse(leafNode.equals(otherLeafNode));
+ assertFalse(otherLeafNode.equals(leafNode));
+
+ byte[] value1 = "test".getBytes();
+ byte[] otherValue1 = "test1".getBytes();
+
+ LeafNode<byte[]> leafNode1 = ImmutableNodes
+ .leafNode(LEAF_QNAME, value1);
+ LeafNode<byte[]> otherLeafNode1 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, otherValue1);
+
+ assertFalse(leafNode1.equals(otherLeafNode1));
+ assertFalse(otherLeafNode1.equals(leafNode1));
+
+ Byte[] value2 = new Byte[] { new Byte("1"), new Byte("1") };
+ Byte[] otherValue2 = new Byte[] { new Byte("1"), new Byte("2") };
+
+ LeafNode<Byte[]> leafNode2 = ImmutableNodes
+ .leafNode(LEAF_QNAME, value2);
+ LeafNode<Byte[]> otherLeafNode2 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, otherValue2);
+
+ assertFalse(leafNode2.equals(otherLeafNode2));
+ assertFalse(otherLeafNode2.equals(leafNode2));
+
+ byte[][] value3 = new byte[][] { "test".getBytes(), "test2".getBytes() };
+ byte[][] otherValue3 = new byte[][] { "test".getBytes(),
+ "test3".getBytes() };
+
+ LeafNode<byte[][]> leafNode3 = ImmutableNodes.leafNode(LEAF_QNAME,
+ value3);
+ LeafNode<byte[][]> otherLeafNode3 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, otherValue3);
+
+ assertFalse(leafNode3.equals(otherLeafNode3));
+ assertFalse(otherLeafNode3.equals(leafNode3));
+
+ Byte[][] value4 = new Byte[][] {
+ new Byte[] { new Byte("1"), new Byte("2") },
+ new Byte[] { new Byte("3"), new Byte("4") } };
+ Byte[][] otherValue4 = new Byte[][] {
+ new Byte[] { new Byte("1"), new Byte("2") },
+ new Byte[] { new Byte("3"), new Byte("5") } };
+
+ LeafNode<Byte[][]> leafNode4 = ImmutableNodes.leafNode(LEAF_QNAME,
+ value4);
+ LeafNode<Byte[][]> otherLeafNode4 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, otherValue4);
+
+ assertFalse(leafNode4.equals(otherLeafNode4));
+ assertFalse(otherLeafNode4.equals(leafNode4));
+
+ Byte value6 = new Byte("1");
+ Byte otherValue6 = new Byte("2");
+
+ LeafNode<Byte> leafNode6 = ImmutableNodes.leafNode(LEAF_QNAME, value6);
+ LeafNode<Byte> otherLeafNode6 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, otherValue6);
+
+ assertFalse(leafNode6.equals(otherLeafNode6));
+ assertFalse(otherLeafNode6.equals(leafNode6));
+
+ String value5 = new String("test");
+ String otherValue5 = new String("test2");
+
+ LeafNode<String> leafNode5 = ImmutableNodes
+ .leafNode(LEAF_QNAME, value5);
+ LeafNode<String> otherLeafNode5 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, otherValue5);
+
+ assertFalse(leafNode5.equals(otherLeafNode5));
+ assertFalse(otherLeafNode5.equals(leafNode5));
+ assertFalse(leafNode5.equals(leafNode));
+ assertFalse(leafNode5.equals(leafNode1));
+ assertFalse(leafNode5.equals(leafNode2));
+ assertFalse(leafNode5.equals(leafNode3));
+ assertFalse(leafNode5.equals(leafNode4));
+ assertFalse(leafNode5.equals(leafNode6));
+ assertFalse(leafNode.equals(leafNode5));
+ assertFalse(leafNode1.equals(leafNode5));
+ assertFalse(leafNode2.equals(leafNode5));
+ assertFalse(leafNode3.equals(leafNode5));
+ assertFalse(leafNode4.equals(leafNode5));
+ assertFalse(leafNode6.equals(leafNode5));
+
+ byte[] valueNull = null;
+
+ LeafNode<byte[]> leafNodeNull = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, valueNull);
+ assertFalse(leafNodeNull.equals(leafNode));
+ assertFalse(leafNode.equals(leafNodeNull));
+
+ byte[] byteValue = new byte[] { new Byte("1").byteValue(),
+ new Byte("1").byteValue() };
+
+ LeafNode<byte[]> byteLeafNode = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, byteValue);
+ assertFalse(byteLeafNode.equals(leafNode2));
+ assertFalse(leafNode2.equals(byteLeafNode));
+
+ }
+
+ @Test
+ public void equalsOtherTypesTest() {
+
+ char[] valueChar = "test".toCharArray();
+ char[] equalValueChar = "test".toCharArray();
+
+ LeafNode<char[]> leafNodeChar = ImmutableNodes.leafNode(LEAF_QNAME,
+ valueChar);
+ LeafNode<char[]> equalLeafNodeChar = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValueChar);
+
+ assertTrue(leafNodeChar.equals(leafNodeChar));
+ assertTrue(leafNodeChar.equals(equalLeafNodeChar));
+ assertTrue(equalLeafNodeChar.equals(leafNodeChar));
+
+ boolean[] value = new boolean[] { true, false };
+ boolean[] equalValue = new boolean[] { true, false };
+
+ LeafNode<boolean[]> leafNode = ImmutableNodes.leafNode(LEAF_QNAME,
+ value);
+ LeafNode<boolean[]> equalLeafNode = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue);
+
+ assertTrue(leafNode.equals(leafNode));
+ assertTrue(leafNode.equals(equalLeafNode));
+ assertTrue(equalLeafNode.equals(leafNode));
+
+ int[] value2 = new int[] { 1, 2 };
+ int[] equalValue2 = new int[] { 1, 2 };
+
+ LeafNode<int[]> leafNode2 = ImmutableNodes.leafNode(LEAF_QNAME, value2);
+ LeafNode<int[]> equalLeafNode2 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue2);
+
+ assertTrue(leafNode2.equals(leafNode2));
+ assertTrue(leafNode2.equals(equalLeafNode2));
+ assertTrue(equalLeafNode2.equals(leafNode2));
+
+ short[] value3 = new short[] { 1, 2 };
+ short[] equalValue3 = new short[] { 1, 2 };
+
+ LeafNode<short[]> leafNode3 = ImmutableNodes.leafNode(LEAF_QNAME,
+ value3);
+ LeafNode<short[]> equalLeafNode3 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue3);
+
+ assertTrue(leafNode3.equals(leafNode3));
+ assertTrue(leafNode3.equals(equalLeafNode3));
+ assertTrue(equalLeafNode3.equals(leafNode3));
+
+ long[] value4 = new long[] { 1, 2 };
+ long[] equalValue4 = new long[] { 1, 2 };
+
+ LeafNode<long[]> leafNode4 = ImmutableNodes
+ .leafNode(LEAF_QNAME, value4);
+ LeafNode<long[]> equalLeafNode4 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue4);
+
+ assertTrue(leafNode4.equals(leafNode4));
+ assertTrue(leafNode4.equals(equalLeafNode4));
+ assertTrue(equalLeafNode4.equals(leafNode4));
+
+ double[] value6 = new double[] { 1, 2 };
+ double[] equalValue6 = new double[] { 1, 2 };
+
+ LeafNode<double[]> leafNode6 = ImmutableNodes.leafNode(LEAF_QNAME,
+ value6);
+ LeafNode<double[]> equalLeafNode6 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue6);
+
+ assertTrue(leafNode6.equals(leafNode6));
+ assertTrue(leafNode6.equals(equalLeafNode6));
+ assertTrue(equalLeafNode6.equals(leafNode6));
+
+ float[] value5 = new float[] { 1, 2 };
+ float[] equalValue5 = new float[] { 1, 2 };
+
+ LeafNode<float[]> leafNode5 = ImmutableNodes.leafNode(LEAF_QNAME,
+ value5);
+ LeafNode<float[]> equalLeafNode5 = ImmutableNodes.leafNode(
+ SAME_LEAF_QNAME, equalValue5);
+
+ assertTrue(leafNode5.equals(leafNode5));
+ assertTrue(leafNode5.equals(equalLeafNode5));
+ assertTrue(equalLeafNode5.equals(leafNode5));
+
+ assertFalse(leafNode.equals(leafNode5));
+ assertFalse(leafNode2.equals(leafNode5));
+ assertFalse(leafNode3.equals(leafNode5));
+ assertFalse(leafNode4.equals(leafNode5));
+ assertFalse(leafNodeChar.equals(leafNode5));
+ assertFalse(leafNode6.equals(leafNode5));
+
+ assertFalse(leafNode5.equals(leafNode));
+ assertFalse(leafNode5.equals(leafNode2));
+ assertFalse(leafNode5.equals(leafNode3));
+ assertFalse(leafNode5.equals(leafNode4));
+ assertFalse(leafNode5.equals(leafNodeChar));
+ assertFalse(leafNode5.equals(leafNode6));
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 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
+ */
+module leafref-test {
+ yang-version 1;
+ namespace "urn:opendaylight:yangtools:leafref:test";
+ prefix "lt";
+
+ revision 2014-11-04 {
+ description "Test deserialization value of leafref type.";
+ }
+
+ container interface {
+ leaf simpleValue {
+ type instance-identifier;
+ }
+ }
+
+ container cont2 {
+ container cont3 {
+ leaf leafname3 {
+ type leafref {
+ path "../../pointToStringLeaf";
+ }
+ }
+ }
+ leaf pointToStringLeaf {
+ type leafref {
+ path "../stringleaf";
+ }
+ }
+ leaf stringleaf {
+ type string;
+ }
+ leaf absname {
+ type leafref {
+ path "/lt:interface/lt:simpleValue";
+ }
+ }
+ leaf relname {
+ type leafref {
+ path "../../lt:interface/lt:simpleValue";
+ }
+ }
+
+ leaf lf-with-double-point-inside {
+ type leafref {
+ path "../../lt:interface/../lt:cont2/lt:stringleaf";
+ }
+ }
+ }
+}
\ No newline at end of file
detectedCase = detectedCaseForChild.get();
}
- if (detectedCase == null)
+ if (detectedCase == null) {
return childrenToProcess;
+ }
// Filter out child nodes that do not belong to detected case =
// Nodes from other cases present in actual
}
private Optional<LeafSetNode<?>> build(LeafListSchemaNode schemaNode, List<LeafSetEntryNode<?>> resultNodes) {
- if(resultNodes.isEmpty())
+ if(resultNodes.isEmpty()) {
return Optional.absent();
+ }
ListNodeBuilder<Object, LeafSetEntryNode<Object>> b = Builders.leafSetBuilder(schemaNode);
for (LeafSetEntryNode<?> resultNode : resultNodes) {
Optional<MapNode> modification, OperationStack operationStack) throws DataModificationException {
// Merge or None operation on parent, leaving actual if modification not present
- if (!modification.isPresent())
+ if (!modification.isPresent()) {
return actual;
+ }
Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> resultNodes = Maps.newLinkedHashMap();
- if(actual.isPresent())
+ if(actual.isPresent()) {
resultNodes.putAll(mapEntries(actual.get()));
+ }
// TODO implement ordering for modification nodes
}
private Optional<MapNode> build(ListSchemaNode schema, Map<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> resultNodes) {
- if(resultNodes.isEmpty())
+ if(resultNodes.isEmpty()) {
return Optional.absent();
+ }
CollectionNodeBuilder<MapEntryNode, MapNode> b = Builders.mapBuilder(schema);
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+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.opendaylight.yangtools.yang.model.api.ModuleImport;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Preconditions.checkArgument(module != null, "Failed to resolve xpath: no module found for prefix %s in module %s",
modulePrefix, parentModule.getName());
- // FIXME: Module should have a QNameModule handle
- return QName.create(module.getNamespace(), module.getRevision(), prefixedName.next());
+ return QName.create(module.getQNameModule(), prefixedName.next());
} else {
return QName.create(parentModule.getNamespace(), parentModule.getRevision(), prefixedPathPart);
}
* Yang Module
* @param relativeXPath
* Non conditional Revision Aware Relative XPath
- * @param leafrefSchemaPath
- * Schema Path for Leafref
+ * @param actualSchemaNode
+ * actual schema node
* @return list of QName
*/
private static Iterable<QName> resolveRelativeXPath(final SchemaContext context, final Module module,
- final RevisionAwareXPath relativeXPath, final SchemaNode leafrefParentNode) {
+ final RevisionAwareXPath relativeXPath, final SchemaNode actualSchemaNode) {
Preconditions.checkArgument(context != null, "Schema Context reference cannot be NULL");
Preconditions.checkArgument(module != null, "Module reference cannot be NULL");
Preconditions.checkArgument(relativeXPath != null, "Non Conditional Revision Aware XPath cannot be NULL");
Preconditions.checkState(!relativeXPath.isAbsolute(),
"Revision Aware XPath MUST be relative i.e. MUST contains ../, "
+ "for non relative Revision Aware XPath use findDataSchemaNode method");
- Preconditions.checkState(leafrefParentNode.getPath() != null,
+ Preconditions.checkState(actualSchemaNode.getPath() != null,
"Schema Path reference for Leafref cannot be NULL");
final Iterable<String> xpaths = SLASH_SPLITTER.split(relativeXPath.toString());
// Find out how many "parent" components there are
// FIXME: is .contains() the right check here?
+ // FIXME: case ../../node1/node2/../node3/../node4
int colCount = 0;
for (Iterator<String> it = xpaths.iterator(); it.hasNext() && it.next().contains(".."); ) {
++colCount;
}
- final Iterable<QName> parent = leafrefParentNode.getPath().getPathFromRoot();
- return Iterables.concat(Iterables.limit(parent, Iterables.size(parent) - colCount),
+ final Iterable<QName> schemaNodePath = actualSchemaNode.getPath().getPathFromRoot();
+
+ if (Iterables.size(schemaNodePath) - colCount >= 0) {
+ return Iterables.concat(Iterables.limit(schemaNodePath, Iterables.size(schemaNodePath) - colCount),
+ Iterables.transform(Iterables.skip(xpaths, colCount), new Function<String, QName>() {
+ @Override
+ public QName apply(final String input) {
+ return stringPathPartToQName(context, module, input);
+ }
+ }));
+ }
+ return Iterables.concat(schemaNodePath,
Iterables.transform(Iterables.skip(xpaths, colCount), new Function<String, QName>() {
@Override
public QName apply(final String input) {
}
}));
}
+
+ /**
+ * Extracts the base type of node on which schema node points to. If target node is again of type LeafrefTypeDefinition, methods will be call recursively until it reach concrete
+ * type definition.
+ *
+ * @param typeDefinition
+ * type of node which will be extracted
+ * @param schemaContext
+ * Schema Context
+ * @param schema
+ * Schema Node
+ * @return recursively found type definition this leafref is pointing to or null if the xpath is incorrect (null is there to preserve backwards compatibility)
+ */
+ public static TypeDefinition<?> getBaseTypeForLeafRef(final LeafrefTypeDefinition typeDefinition, final SchemaContext schemaContext, final SchemaNode schema) {
+ RevisionAwareXPath pathStatement = typeDefinition.getPathStatement();
+ pathStatement = new RevisionAwareXPathImpl(stripConditionsFromXPathString(pathStatement), pathStatement.isAbsolute());
+
+ final Module parentModule = SchemaContextUtil.findParentModule(schemaContext, schema);
+
+ final DataSchemaNode dataSchemaNode;
+ if(pathStatement.isAbsolute()) {
+ dataSchemaNode = (DataSchemaNode) SchemaContextUtil.findDataSchemaNode(schemaContext, parentModule, pathStatement);
+ } else {
+ dataSchemaNode = (DataSchemaNode) SchemaContextUtil.findDataSchemaNodeForRelativeXPath(schemaContext, parentModule, schema, pathStatement);
+ }
+
+ // FIXME this is just to preserve backwards compatibility since yangtools do not mind wrong leafref xpaths
+ // and current expected behaviour for such cases is to just use pure string
+ // This should throw an exception about incorrect XPath in leafref
+ if(dataSchemaNode == null) {
+ return null;
+ }
+
+ final TypeDefinition<?> targetTypeDefinition = typeDefinition(dataSchemaNode);
+
+ if(targetTypeDefinition instanceof LeafrefTypeDefinition) {
+ return getBaseTypeForLeafRef(((LeafrefTypeDefinition) targetTypeDefinition), schemaContext, dataSchemaNode);
+ } else {
+ return targetTypeDefinition;
+ }
+ }
+
+ /**
+ * Removes conditions from xPath pointed to target node.
+ *
+ * @param pathStatement
+ * xPath to target node
+ * @return string representation of xPath without conditions
+ *
+ */
+ private static String stripConditionsFromXPathString(final RevisionAwareXPath pathStatement) {
+ return pathStatement.toString().replaceAll("\\[.*\\]", "");
+ }
+
+ /**
+ * Extracts the base type of leaf schema node until it reach concrete type of TypeDefinition.
+ *
+ * @param node
+ * a node representing LeafSchemaNode
+ * @return concrete type definition of node value
+ */
+ private static TypeDefinition<? extends Object> typeDefinition(final LeafSchemaNode node) {
+ TypeDefinition<?> baseType = node.getType();
+ while (baseType.getBaseType() != null) {
+ baseType = baseType.getBaseType();
+ }
+ return baseType;
+ }
+
+ /**
+ * Extracts the base type of leaf schema node until it reach concrete type of TypeDefinition.
+ *
+ * @param node
+ * a node representing LeafListSchemaNode
+ * @return concrete type definition of node value
+ */
+ private static TypeDefinition<? extends Object> typeDefinition(final LeafListSchemaNode node) {
+ TypeDefinition<?> baseType = node.getType();
+ while (baseType.getBaseType() != null) {
+ baseType = baseType.getBaseType();
+ }
+ return baseType;
+ }
+
+ /**
+ * Gets the base type of DataSchemaNode value.
+ *
+ * @param node
+ * a node representing DataSchemaNode
+ * @return concrete type definition of node value
+ */
+ private static TypeDefinition<? extends Object> typeDefinition(final DataSchemaNode node) {
+ if (node instanceof LeafListSchemaNode) {
+ return typeDefinition((LeafListSchemaNode) node);
+ } else if (node instanceof LeafSchemaNode) {
+ return typeDefinition((LeafSchemaNode) node);
+ } else {
+ throw new IllegalArgumentException("Unhandled parameter types: " + Arrays.<Object> asList(node).toString());
+ }
+ }
}
END_IDENTIFIER_SEMICOLON : ';' -> type(SEMICOLON),popMode;
END_IDENTIFIER_LEFT_BRACE : '{' ->type(LEFT_BRACE), popMode;
-
+
+START_INNER_BLOCK_COMMENT : '/*' ->pushMode(BLOCK_COMMENT_MODE), skip ;
+
fragment SUB_STRING : ('"' (ESC | ~["])*'"') | ('\'' (ESC | ~['])*'\'') ;
STRING: ((~( '\r' | '\n' | '\t' | ' ' | ';' | '{' | '"' | '\'')~( '\r' | '\n' | '\t' | ' ' | ';' | '{' )* ) | SUB_STRING ) ->popMode;// IDENTIFIER ;
DataSchemaNodeBuilder, AugmentationTargetBuilder {
private ListSchemaNodeImpl instance;
private boolean userOrdered;
- private List<String> keys;
+ private Set<String> keys;
private List<QName> keyDefinition;
// SchemaNode args
private SchemaPath schemaPath;
return augmentationBuilders;
}
- public List<String> getKeys() {
+ public Set<String> getKeys() {
return keys;
}
- public void setKeys(final List<String> keys) {
+ public void setKeys(final Set<String> keys) {
this.keys = keys;
}
import com.google.common.base.CharMatcher;
import com.google.common.base.Optional;
import com.google.common.base.Splitter;
-import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.antlr.v4.runtime.ParserRuleContext;
}
/**
- * Create java.util.List of key node names.
+ * Create java.util.LinkedHashSet of key node names.
*
* @param ctx
* Key_stmtContext context
- * @return YANG list key as java.util.List of key node names
+ * @return YANG list key as java.util.LinkedHashSet of key node names
*/
- public static List<String> createListKey(final Key_stmtContext ctx) {
- String keyDefinition = stringFromNode(ctx);
- return Lists.newArrayList(KEYDEF_SPLITTER.split(keyDefinition));
+ public static Set<String> createListKey(final Key_stmtContext ctx) {
+ final String keyDefinition = stringFromNode(ctx);
+ return Sets.<String>newLinkedHashSet(KEYDEF_SPLITTER.split(keyDefinition));
}
/**
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.TreeMap;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
public void enterBelongs_to_stmt(final YangParser.Belongs_to_stmtContext ctx) {
final String belongsTo = stringFromNode(ctx);
TreeMap<Date, URI> context = namespaceContext.get(belongsTo);
- Map.Entry<Date, URI> entry = context.firstEntry();
+ final Map.Entry<Date, URI> entry = context.firstEntry();
// TODO
// Submodule will contain namespace and revision from module to which it
// belongs. If there are multiple modules with same name and different
public void enterMeta_stmts(final YangParser.Meta_stmtsContext ctx) {
enterLog("meta_stmt", "", ctx.getStart().getLine());
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Organization_stmtContext) {
final String organization = stringFromNode(child);
moduleBuilder.setOrganization(organization);
Date includeRevision = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree treeNode = ctx.getChild(i);
+ final ParseTree treeNode = ctx.getChild(i);
if (treeNode instanceof Revision_date_stmtContext) {
- String importRevisionStr = stringFromNode(treeNode);
+ final String importRevisionStr = stringFromNode(treeNode);
try {
includeRevision = SIMPLE_DATE_FORMAT.parse(importRevisionStr);
} catch (ParseException e) {
enterLog(AUGMENT_STR, augmentPath, line);
stack.push();
- SchemaPath targetPath = parseXPathString(augmentPath, line);
- AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
+ final SchemaPath targetPath = parseXPathString(augmentPath, line);
+ final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
for (int i = 0; i < ctx.getChildCount(); i++) {
ParseTree child = ctx.getChild(i);
final int line = ctx.getStart().getLine();
final String extName = stringFromNode(ctx);
enterLog("extension", extName, line);
- QName qname = QName.create(moduleQName, extName);
- SchemaPath path = stack.addNodeToPath(qname);
+ final QName qname = QName.create(moduleQName, extName);
+ final SchemaPath path = stack.addNodeToPath(qname);
- ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
+ final ExtensionBuilder builder = moduleBuilder.addExtension(qname, line, path);
parseSchemaNodeArgs(ctx, builder);
String argument = null;
boolean yin = false;
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Argument_stmtContext) {
argument = stringFromNode(child);
yin = parseYinValue((Argument_stmtContext) child);
final int line = ctx.getStart().getLine();
final String typedefName = stringFromNode(ctx);
enterLog("typedef", typedefName, line);
- QName typedefQName = QName.create(moduleQName, typedefName);
- SchemaPath path = stack.addNodeToPath(typedefQName);
+ final QName typedefQName = QName.create(moduleQName, typedefName);
+ final SchemaPath path = stack.addNodeToPath(typedefQName);
- TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
+ final TypeDefinitionBuilder builder = moduleBuilder.addTypedef(line, typedefQName, path);
parseSchemaNodeArgs(ctx, builder);
builder.setUnits(parseUnits(ctx));
builder.setDefaultValue(parseDefault(ctx));
case "union":
qname = BaseTypes.UNION_QNAME;
stack.addNodeToPath(qname);
- UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
- Builder parent = moduleBuilder.getActualNode();
+ final UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(line, moduleQName.getModule());
+ final Builder parent = moduleBuilder.getActualNode();
unionBuilder.setParent(parent);
moduleBuilder.enterNode(unionBuilder);
break;
case "identityref":
qname = BaseTypes.IDENTITYREF_QNAME;
- SchemaPath path = stack.addNodeToPath(qname);
+ final SchemaPath path = stack.addNodeToPath(qname);
moduleBuilder.addIdentityrefType(line, path, getIdentityrefBase(typeBody));
break;
default:
}
}
} else {
- TypeAwareBuilder parent = (TypeAwareBuilder) moduleBuilder.getActualNode();
+ final TypeAwareBuilder parent = (TypeAwareBuilder) moduleBuilder.getActualNode();
if (typeBody == null) {
parent.setTypeQName(typeQName);
moduleBuilder.markActualNodeDirty();
if (prefix.equals(moduleBuilder.getPrefix())) {
qname = QName.create(moduleQName, name);
} else {
- ModuleImport imp = moduleBuilder.getImport(prefix);
+ final ModuleImport imp = moduleBuilder.getImport(prefix);
if (imp == null) {
LOG.debug("Error in module {} at line {}: No import found with prefix {}", moduleName, line, prefix);
throw new YangParseException(moduleName, line, "Error in module " + moduleName
final int line = ctx.getStart().getLine();
final String groupName = stringFromNode(ctx);
enterLog("grouping", groupName, line);
- QName groupQName = QName.create(moduleQName, groupName);
- SchemaPath path = stack.addNodeToPath(groupQName);
+ final QName groupQName = QName.create(moduleQName, groupName);
+ final SchemaPath path = stack.addNodeToPath(groupQName);
- GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
+ final GroupingBuilder builder = moduleBuilder.addGrouping(ctx.getStart().getLine(), groupQName, path);
parseSchemaNodeArgs(ctx, builder);
moduleBuilder.enterNode(builder);
final String containerName = stringFromNode(ctx);
enterLog("container", containerName, line);
- QName containerQName = QName.create(moduleQName, containerName);
- SchemaPath path = stack.addNodeToPath(containerQName);
+ final QName containerQName = QName.create(moduleQName, containerName);
+ final SchemaPath path = stack.addNodeToPath(containerQName);
- ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
+ final ContainerSchemaNodeBuilder builder = moduleBuilder.addContainerNode(line, containerQName, path);
parseSchemaNodeArgs(ctx, builder);
parseConstraints(ctx, builder.getConstraints());
builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
final String leafName = stringFromNode(ctx);
enterLog("leaf", leafName, line);
- QName leafQName = QName.create(moduleQName, leafName);
- SchemaPath path = stack.addNodeToPath(leafQName);
+ final QName leafQName = QName.create(moduleQName, leafName);
+ final SchemaPath path = stack.addNodeToPath(leafQName);
- LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
+ final LeafSchemaNodeBuilder builder = moduleBuilder.addLeafNode(line, leafQName, path);
parseSchemaNodeArgs(ctx, builder);
parseConstraints(ctx, builder.getConstraints());
builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
String defaultStr = null;
String unitsStr = null;
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Default_stmtContext) {
defaultStr = stringFromNode(child);
} else if (child instanceof Units_stmtContext) {
final SchemaPath groupingPath = parseXPathString(groupingPathStr, line);
enterLog("uses", groupingPathStr, line);
- UsesNodeBuilder builder = moduleBuilder.addUsesNode(line, groupingPath);
+ final UsesNodeBuilder builder = moduleBuilder.addUsesNode(line, groupingPath);
moduleBuilder.enterNode(builder);
}
enterLog(AUGMENT_STR, augmentPath, line);
stack.push();
- SchemaPath targetPath = parseXPathString(augmentPath, line);
- AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
+ final SchemaPath targetPath = parseXPathString(augmentPath, line);
+ final AugmentationSchemaBuilder builder = moduleBuilder.addAugment(line, augmentPath, targetPath, augmentOrder++);
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Description_stmtContext) {
builder.setDescription(stringFromNode(child));
} else if (child instanceof Reference_stmtContext) {
final String refineString = stringFromNode(ctx);
enterLog("refine", refineString, ctx.getStart().getLine());
- RefineHolderImpl refine = parseRefine(ctx, moduleName);
+ final RefineHolderImpl refine = parseRefine(ctx, moduleName);
moduleBuilder.addRefine(refine);
moduleBuilder.enterNode(refine);
}
final int line = ctx.getStart().getLine();
final String leafListName = stringFromNode(ctx);
enterLog("leaf-list", leafListName, line);
- QName leafListQName = QName.create(moduleQName, leafListName);
- SchemaPath path = stack.addNodeToPath(leafListQName);
+ final QName leafListQName = QName.create(moduleQName, leafListName);
+ final SchemaPath path = stack.addNodeToPath(leafListQName);
- LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
+ final LeafListSchemaNodeBuilder builder = moduleBuilder.addLeafListNode(line, leafListQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
final String listName = stringFromNode(ctx);
enterLog("list", listName, line);
- QName listQName = QName.create(moduleQName, listName);
- SchemaPath path = stack.addNodeToPath(listQName);
+ final QName listQName = QName.create(moduleQName, listName);
+ final SchemaPath path = stack.addNodeToPath(listQName);
- ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
+ final ListSchemaNodeBuilder builder = moduleBuilder.addListNode(line, listQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
builder.setConfiguration(getConfig(ctx, builder, moduleName, line));
for (int i = 0; i < ctx.getChildCount(); ++i) {
- ParseTree childNode = ctx.getChild(i);
+ final ParseTree childNode = ctx.getChild(i);
if (childNode instanceof Ordered_by_stmtContext) {
final Ordered_by_stmtContext orderedBy = (Ordered_by_stmtContext) childNode;
final boolean userOrdered = parseUserOrdered(orderedBy);
builder.setUserOrdered(userOrdered);
} else if (childNode instanceof Key_stmtContext) {
- List<String> key = createListKey((Key_stmtContext) childNode);
+ final Set<String> key = createListKey((Key_stmtContext) childNode);
builder.setKeys(key);
}
}
final String anyXmlName = stringFromNode(ctx);
enterLog("anyxml", anyXmlName, line);
- QName anyXmlQName = QName.create(moduleQName, anyXmlName);
- SchemaPath path = stack.addNodeToPath(anyXmlQName);
+ final QName anyXmlQName = QName.create(moduleQName, anyXmlName);
+ final SchemaPath path = stack.addNodeToPath(anyXmlQName);
- AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
+ final AnyXmlBuilder builder = moduleBuilder.addAnyXml(line, anyXmlQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
final String choiceName = stringFromNode(ctx);
enterLog("choice", choiceName, line);
- QName choiceQName = QName.create(moduleQName, choiceName);
- SchemaPath path = stack.addNodeToPath(choiceQName);
+ final QName choiceQName = QName.create(moduleQName, choiceName);
+ final SchemaPath path = stack.addNodeToPath(choiceQName);
- ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
+ final ChoiceBuilder builder = moduleBuilder.addChoice(line, choiceQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
// set 'default' case
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Default_stmtContext) {
- String defaultCase = stringFromNode(child);
+ final String defaultCase = stringFromNode(child);
builder.setDefaultCase(defaultCase);
break;
}
final String caseName = stringFromNode(ctx);
enterLog("case", caseName, line);
- QName caseQName = QName.create(moduleQName, caseName);
- SchemaPath path = stack.addNodeToPath(caseQName);
+ final QName caseQName = QName.create(moduleQName, caseName);
+ final SchemaPath path = stack.addNodeToPath(caseQName);
- ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
+ final ChoiceCaseBuilder builder = moduleBuilder.addCase(line, caseQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
final String notificationName = stringFromNode(ctx);
enterLog("notification", notificationName, line);
- QName notificationQName = QName.create(moduleQName, notificationName);
- SchemaPath path = stack.addNodeToPath(notificationQName);
+ final QName notificationQName = QName.create(moduleQName, notificationName);
+ final SchemaPath path = stack.addNodeToPath(notificationQName);
- NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
+ final NotificationBuilder builder = moduleBuilder.addNotification(line, notificationQName, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
final String rpcName = stringFromNode(ctx);
enterLog("rpc", rpcName, line);
- QName rpcQName = QName.create(moduleQName, rpcName);
- SchemaPath path = stack.addNodeToPath(rpcQName);
+ final QName rpcQName = QName.create(moduleQName, rpcName);
+ final SchemaPath path = stack.addNodeToPath(rpcQName);
- RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
+ final RpcDefinitionBuilder rpcBuilder = moduleBuilder.addRpc(line, rpcQName, path);
moduleBuilder.enterNode(rpcBuilder);
-
parseSchemaNodeArgs(ctx, rpcBuilder);
}
final String input = "input";
enterLog(input, input, line);
- QName rpcQName = QName.create(moduleQName, input);
- SchemaPath path = stack.addNodeToPath(rpcQName);
+ final QName rpcQName = QName.create(moduleQName, input);
+ final SchemaPath path = stack.addNodeToPath(rpcQName);
- ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
+ final ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcInput(line, rpcQName, path);
moduleBuilder.enterNode(builder);
builder.setConfiguration(true);
final String output = "output";
enterLog(output, output, line);
- QName rpcQName = QName.create(moduleQName, output);
- SchemaPath path = stack.addNodeToPath(rpcQName);
+ final QName rpcQName = QName.create(moduleQName, output);
+ final SchemaPath path = stack.addNodeToPath(rpcQName);
- ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
+ final ContainerSchemaNodeBuilder builder = moduleBuilder.addRpcOutput(path, rpcQName, line);
moduleBuilder.enterNode(builder);
builder.setConfiguration(true);
final String featureName = stringFromNode(ctx);
enterLog("feature", featureName, line);
- QName featureQName = QName.create(moduleQName, featureName);
- SchemaPath path = stack.addNodeToPath(featureQName);
+ final QName featureQName = QName.create(moduleQName, featureName);
+ final SchemaPath path = stack.addNodeToPath(featureQName);
- FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
+ final FeatureBuilder featureBuilder = moduleBuilder.addFeature(line, featureQName, path);
moduleBuilder.enterNode(featureBuilder);
parseSchemaNodeArgs(ctx, featureBuilder);
String reference = null;
String deviate = null;
- SchemaPath targetPath = parseXPathString(targetPathStr, line);
- DeviationBuilder builder = moduleBuilder.addDeviation(line, targetPath);
+ final SchemaPath targetPath = parseXPathString(targetPathStr, line);
+ final DeviationBuilder builder = moduleBuilder.addDeviation(line, targetPath);
moduleBuilder.enterNode(builder);
for (int i = 0; i < ctx.getChildCount(); i++) {
enterLog("identity", identityName, line);
final QName identityQName = QName.create(moduleQName, identityName);
- SchemaPath path = stack.addNodeToPath(identityQName);
+ final SchemaPath path = stack.addNodeToPath(identityQName);
- IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
+ final IdentitySchemaNodeBuilder builder = moduleBuilder.addIdentity(identityQName, line, path);
moduleBuilder.enterNode(builder);
parseSchemaNodeArgs(ctx, builder);
for (int i = 0; i < ctx.getChildCount(); i++) {
- ParseTree child = ctx.getChild(i);
+ final ParseTree child = ctx.getChild(i);
if (child instanceof Base_stmtContext) {
String baseIdentityName = stringFromNode(child);
builder.setBaseIdentityName(baseIdentityName);
enterLog("unknown-node", nodeParameter, line);
final String nodeTypeStr = ctx.getChild(0).getText();
- QName nodeType = parseQName(nodeTypeStr, line);
+ final QName nodeType = parseQName(nodeTypeStr, line);
QName qname = null;
try {
qname = nodeType;
}
- SchemaPath path = stack.addNodeToPath(qname);
+ final SchemaPath path = stack.addNodeToPath(qname);
- UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
+ final UnknownSchemaNodeBuilderImpl builder = moduleBuilder.addUnknownSchemaNode(line, qname, path);
builder.setNodeType(nodeType);
builder.setNodeParameter(nodeParameter);
return repository.getSchemaSource(input, ASTSchemaSource.class);
}
};
- private final Cache<Collection<SourceIdentifier>, SchemaContext> cache = CacheBuilder.newBuilder().softValues().build();
+ private final Cache<Collection<SourceIdentifier>, SchemaContext> cache = CacheBuilder.newBuilder().weakValues().build();
private final AsyncFunction<List<ASTSchemaSource>, SchemaContext> assembleSources = new AsyncFunction<List<ASTSchemaSource>, SchemaContext>() {
@Override