Merge "BUG-1382: eliminate QName.getPrefix()"
authorTony Tkacik <ttkacik@cisco.com>
Wed, 7 Jan 2015 09:36:26 +0000 (09:36 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 7 Jan 2015 09:36:26 +0000 (09:36 +0000)
27 files changed:
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/BindingCodecContext.java
code-generator/binding-data-codec/src/main/java/org/opendaylight/yangtools/binding/data/codec/impl/SchemaRootCodecContext.java
code-generator/binding-generator-impl/pom.xml
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/GeneratedClassLoadingStrategy.java
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/TransformerGenerator.xtend
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/util/BindingRuntimeContext.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/Bug1276Test.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/Bug532Test.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/EndodingInJavaDocTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/NestedGroupingCompilationTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java
code-generator/binding-parent/pom.xml
common/artifacts/pom.xml
common/features/pom.xml
common/features/src/main/feature/features.xml
common/parent/pom.xml
integration-test/bundle-test/pom.xml
integration-test/bundle-test/src/test/java/org/opendaylight/yangtools/bundle/test/BundleStartTest.java
third-party/pom.xml
third-party/xtend-lib-osgi/pom.xml [deleted file]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/NodeModification.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/OperationWithModification.java

index 11f8d3f5bae2c0e9ead199655c2ee052bd0e5ee8..0ecb622367bd7e29ddee09742725e279d673a76a 100644 (file)
@@ -59,19 +59,20 @@ import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-class BindingCodecContext implements CodecContextFactory, Immutable {
+final class BindingCodecContext implements CodecContextFactory, Immutable {
     private static final Logger LOG = LoggerFactory.getLogger(BindingCodecContext.class);
     private static final String GETTER_PREFIX = "get";
 
-    private final SchemaRootCodecContext root;
-    private final BindingRuntimeContext context;
     private final Codec<YangInstanceIdentifier, InstanceIdentifier<?>> instanceIdentifierCodec =
             new InstanceIdentifierCodec();
-    private final Codec<QName, Class<?>> identityCodec = new IdentityCodec();
+    private final Codec<QName, Class<?>> identityCodec;
+    private final BindingRuntimeContext context;
+    private final SchemaRootCodecContext root;
 
     public BindingCodecContext(final BindingRuntimeContext context) {
         this.context = Preconditions.checkNotNull(context, "Binding Runtime Context is required.");
         this.root = SchemaRootCodecContext.create(this);
+        this.identityCodec = new IdentityCodec(context);
     }
 
     @Override
@@ -315,7 +316,12 @@ class BindingCodecContext implements CodecContextFactory, Immutable {
         }
     }
 
-    private class IdentityCodec implements Codec<QName, Class<?>> {
+    private static class IdentityCodec implements Codec<QName, Class<?>> {
+        private final BindingRuntimeContext context;
+
+        IdentityCodec(final BindingRuntimeContext context) {
+            this.context = Preconditions.checkNotNull(context);
+        }
 
         @Override
         public Class<?> deserialize(final QName input) {
index be328ca199ddd388df298159df847e3d90b6f46d..1fafb40ac4a1408a3d0c2656c934b8bde16a1b92 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.yangtools.yang.binding.ChildOf;
 import org.opendaylight.yangtools.yang.binding.DataRoot;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
-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.NormalizedNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
 import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
@@ -26,7 +26,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
 class SchemaRootCodecContext extends DataContainerCodecContext<SchemaContext> {
 
-    private final LoadingCache<Class<?>, DataContainerCodecContext<?>> children = CacheBuilder.newBuilder().build(
+    private final LoadingCache<Class<?>, DataContainerCodecContext<?>> childrenByClass = CacheBuilder.newBuilder().build(
             new CacheLoader<Class<?>, DataContainerCodecContext<?>>() {
                 @Override
                 public DataContainerCodecContext<?> load(final Class<?> key) {
@@ -38,6 +38,22 @@ class SchemaRootCodecContext extends DataContainerCodecContext<SchemaContext> {
                 }
             });
 
+    private final LoadingCache<QName, DataContainerCodecContext<?>> childrenByQName = CacheBuilder.newBuilder().build(
+        new CacheLoader<QName, DataContainerCodecContext<?>>() {
+            @Override
+            public DataContainerCodecContext<?> load(final QName qname) {
+                final DataSchemaNode childSchema = schema().getDataChildByName(qname);
+                Preconditions.checkArgument(childSchema != null, "Argument %s is not valid child of %s", qname, schema());
+
+                if (childSchema instanceof DataNodeContainer || childSchema instanceof ChoiceNode) {
+                    final Class<?> childCls = factory().getRuntimeContext().getClassForSchema(childSchema);
+                    return getStreamChild(childCls);
+                } else {
+                    throw new UnsupportedOperationException("Unsupported child type " + childSchema.getClass());
+                }
+            }
+        });
+
     private SchemaRootCodecContext(final DataContainerCodecPrototype<SchemaContext> dataPrototype) {
         super(dataPrototype);
     }
@@ -56,7 +72,7 @@ class SchemaRootCodecContext extends DataContainerCodecContext<SchemaContext> {
 
     @Override
     protected DataContainerCodecContext<?> getStreamChild(final Class<?> childClass) {
-        return children.getUnchecked(childClass);
+        return childrenByClass.getUnchecked(childClass);
     }
 
     @Override
@@ -65,23 +81,13 @@ class SchemaRootCodecContext extends DataContainerCodecContext<SchemaContext> {
     }
 
     @Override
-    protected YangInstanceIdentifier.PathArgument getDomPathArgument() {
+    protected PathArgument getDomPathArgument() {
         throw new UnsupportedOperationException();
     }
 
     @Override
-    protected NodeCodecContext getYangIdentifierChild(final YangInstanceIdentifier.PathArgument arg) {
-        // FIXME: Optimize this
-        QName childQName = arg.getNodeType();
-        DataSchemaNode childSchema = schema().getDataChildByName(childQName);
-        Preconditions.checkArgument(childSchema != null, "Argument %s is not valid child of %s", arg, schema());
-        if (childSchema instanceof DataNodeContainer || childSchema instanceof ChoiceNode) {
-            Class<?> childCls = factory().getRuntimeContext().getClassForSchema(childSchema);
-            DataContainerCodecContext<?> childNode = getStreamChild(childCls);
-            return childNode;
-        } else {
-            throw new UnsupportedOperationException();
-        }
+    protected NodeCodecContext getYangIdentifierChild(final PathArgument arg) {
+        return childrenByQName.getUnchecked(arg.getNodeType());
     }
 
     @Override
index 774a8446da9e6e26ca8e847cf36aff559bf82062..c5ed3cfdb6e8028c117216799a60177ead59d70b 100644 (file)
@@ -17,6 +17,7 @@
 
     <modelVersion>4.0.0</modelVersion>
     <artifactId>binding-generator-impl</artifactId>
+    <packaging>bundle</packaging>
 
     <dependencies>
         <dependency>
@@ -73,9 +74,6 @@
 
     <build>
         <plugins>
-            <plugin>
-                <artifactId>maven-jar-plugin</artifactId>
-            </plugin>
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-bundle-plugin</artifactId>
                             org.opendaylight.yangtools.sal.binding.generator.impl.*,
                             org.opendaylight.yangtools.sal.binding.generator.util.*
                         </Export-Package>
+                        <Embed-Dependency>
+                            org.eclipse.xtend.lib;inline=true,
+                            org.eclipse.xtend.lib.macro;inline=true,
+                            org.eclipse.xtext.xbase.lib;inline=true,
+                        </Embed-Dependency>
+                        <Embed-Transitive>true</Embed-Transitive>
                     </instructions>
                 </configuration>
             </plugin>
index 5440e0151141d8e744abdf428b9d2ecb3ec21b1b..d8f3b737980f4fa2d744094883dd870ed33f8703 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.yangtools.sal.binding.generator.impl;
 
 import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
-import org.opendaylight.yangtools.yang.binding.util.ClassLoaderUtils;
+import org.opendaylight.yangtools.util.ClassLoaderUtils;
 
 public abstract class GeneratedClassLoadingStrategy implements ClassLoadingStrategy {
 
index 6c557aca4388d7fff3f35a51487ff765c1653e9f..3937e0bb01f7bbc2aeb699a3af17f853c341da8f 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.yangtools.sal.binding.generator.impl
 
 import com.google.common.base.Joiner
+import com.google.common.base.Supplier
 import java.io.File
 import java.security.ProtectionDomain
 import java.util.AbstractMap.SimpleEntry
@@ -195,38 +196,38 @@ class TransformerGenerator extends AbstractTransformerGenerator {
         if (cl === null) {
             cl = Thread.currentThread.contextClassLoader
         }
-        ClassLoaderUtils.withClassLoader(cl,
-            [ |
-                if (!(node instanceof DataNodeContainer)) {
-                    return null
-                }
-                var InstanceIdentifier<?> bindingId = getBindingIdentifierByPath(node.path)
-                if (bindingId != null) {
-                    return null
-                }
-                val ref = Types.typeForClass(inputType)
-                var typeSpecBuilder = getDefinition(ref)
-                if (typeSpecBuilder == null) {
-                    typeSpecBuilder = getTypeBuilder(node.path);
-                }
-                checkState(typeSpecBuilder !== null, "Could not find type definition for %s, $s", inputType.name, node);
-                val typeSpec = typeSpecBuilder.toInstance();
-                var InstanceIdentifier<?> parent
-                if (parentId == null) {
-                    bindingId = InstanceIdentifier.create(inputType as Class)
-                    parent = bindingId
-                    putPathToBindingIdentifier(node.path, bindingId)
-                } else {
-                    parent = putPathToBindingIdentifier(node.path, parentId, inputType)
-                }
-                val Map<String, Type> properties = typeSpec.allProperties
-                if (node instanceof DataNodeContainer) {
-                    mappingForNodes((node as DataNodeContainer).childNodes, properties, parent)
-                } else if (node instanceof ChoiceNode) {
-                    mappingForNodes((node as ChoiceNode).cases, properties, parent)
-                }
-                return null;
-            ])
+
+        val Supplier<?> sup = [ |
+            if (!(node instanceof DataNodeContainer)) {
+                return null
+            }
+            var InstanceIdentifier<?> bindingId = getBindingIdentifierByPath(node.path)
+            if (bindingId != null) {
+                return null
+            }
+            val ref = Types.typeForClass(inputType)
+            var typeSpecBuilder = getDefinition(ref)
+            if (typeSpecBuilder == null) {
+                typeSpecBuilder = getTypeBuilder(node.path);
+            }
+            checkState(typeSpecBuilder !== null, "Could not find type definition for %s, $s", inputType.name, node);
+            val typeSpec = typeSpecBuilder.toInstance();
+            var InstanceIdentifier<?> parent
+            if (parentId == null) {
+                bindingId = InstanceIdentifier.create(inputType as Class)
+                parent = bindingId
+                putPathToBindingIdentifier(node.path, bindingId)
+            } else {
+                parent = putPathToBindingIdentifier(node.path, parentId, inputType)
+            }
+            val Map<String, Type> properties = typeSpec.allProperties
+            if (node instanceof DataNodeContainer) {
+                mappingForNodes((node as DataNodeContainer).childNodes, properties, parent)
+            } else if (node instanceof ChoiceNode) {
+                mappingForNodes((node as ChoiceNode).cases, properties, parent)
+            }
+            return null ]
+        ClassLoaderUtils.withClassLoader(cl, sup)
     }
 
     private def void mappingForNodes(Collection<? extends DataSchemaNode> childNodes, Map<String, Type> properties,
index 4a3d760172a379497a3e0d5408178285317abbe4..fe2510857f89911223c90a539e326c6e25f5e740 100644 (file)
@@ -9,6 +9,9 @@ package org.opendaylight.yangtools.sal.binding.generator.util;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.HashBiMap;
@@ -79,6 +82,20 @@ public class BindingRuntimeContext implements Immutable {
     private final Multimap<Type, Type> choiceToCases = HashMultimap.create();
     private final Map<QName, Type> identities = new HashMap<>();
 
+    private final LoadingCache<QName, Class<?>> identityClasses = CacheBuilder.newBuilder().weakValues().build(
+        new CacheLoader<QName, Class<?>>() {
+            @Override
+            public Class<?> load(final QName key) {
+                final Type identityType = identities.get(key);
+                Preconditions.checkArgument(identityType != null, "Supplied QName %s is not a valid identity", key);
+                try {
+                    return strategy.loadClass(identityType);
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalArgumentException("Required class " + identityType + "was not found.", e);
+                }
+            }
+        });
+
     private BindingRuntimeContext(final ClassLoadingStrategy strategy, final SchemaContext schema) {
         this.strategy = strategy;
         this.schemaContext = schema;
@@ -367,13 +384,6 @@ public class BindingRuntimeContext implements Immutable {
     }
 
     public Class<?> getIdentityClass(final QName input) {
-        Type identityType = identities.get(input);
-        Preconditions.checkArgument(identityType != null, "Supplied QName %s is not a valid identity", input);
-        try {
-            return strategy.loadClass(identityType);
-        } catch (ClassNotFoundException e) {
-            throw new IllegalArgumentException("Required class " + identityType + "was not found.",e);
-        }
+        return identityClasses.getUnchecked(input);
     }
-
 }
index da17a504ea9d42a353fce373296b99e71ea24c6f..41521a73e750915186866f0e173d96a80b5354fa 100644 (file)
@@ -21,11 +21,10 @@ import static org.opendaylight.yangtools.sal.java.api.generator.test.Compilation
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.getSourceFiles;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.testAugmentation;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.testCompilation;
-
+import com.google.common.collect.ImmutableSet;
 import java.io.File;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.HashSet;
 import java.util.List;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -44,7 +43,7 @@ public class AugmentToUsesInAugmentCompilationTest extends BaseCompilationTest {
         final List<File> sourceFiles = getSourceFiles("/compilation/augment-uses-to-augment");
         final SchemaContext context = parser.parseFiles(sourceFiles);
         final List<Type> types = bindingGenerator.generateTypes(context);
-        final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
         generator.generateToFile(sourcesOutputDir);
 
         // Test if all sources are generated from 'module foo'
index d2653f22528711cfa0a71604c8cf7567a12fc0d3..9e2bfb610de8c0eb8e309c8d04eeced2a1facb97 100644 (file)
@@ -16,14 +16,13 @@ import static org.opendaylight.yangtools.sal.java.api.generator.test.Compilation
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.cleanUp;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.getSourceFiles;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.testCompilation;
-
+import com.google.common.collect.ImmutableSet;
 import java.io.File;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.Arrays;
-import java.util.HashSet;
 import java.util.List;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -94,11 +93,11 @@ public class Bug1276Test extends BaseCompilationTest {
         cleanUp(sourcesOutputDir, compiledOutputDir);
     }
 
-    private void generateTestSources(String resourceDirPath, File sourcesOutputDir) throws Exception {
+    private void generateTestSources(final String resourceDirPath, final File sourcesOutputDir) throws Exception {
         final List<File> sourceFiles = getSourceFiles(resourceDirPath);
         final SchemaContext context = parser.parseFiles(sourceFiles);
         final List<Type> types = bindingGenerator.generateTypes(context);
-        final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
         generator.generateToFile(sourcesOutputDir);
     }
 
index e816a6882a9bac51b563ec5b9593bbcda9244b92..df865df7d38c0202652622a6facd6178b2d6da08 100644 (file)
@@ -17,13 +17,12 @@ import static org.opendaylight.yangtools.sal.java.api.generator.test.Compilation
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.cleanUp;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.getSourceFiles;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.testCompilation;
-
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import java.io.File;
 import java.lang.reflect.Constructor;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.HashSet;
 import java.util.List;
 import org.junit.Test;
 import org.mockito.Mockito;
@@ -107,11 +106,11 @@ public class Bug532Test extends BaseCompilationTest {
         cleanUp(sourcesOutputDir, compiledOutputDir);
     }
 
-    private void generateTestSources(String resourceDirPath, File sourcesOutputDir) throws Exception {
+    private void generateTestSources(final String resourceDirPath, final File sourcesOutputDir) throws Exception {
         final List<File> sourceFiles = getSourceFiles(resourceDirPath);
         final SchemaContext context = parser.parseFiles(sourceFiles);
         final List<Type> types = bindingGenerator.generateTypes(context);
-        final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
         generator.generateToFile(sourcesOutputDir);
     }
 
index 58d213cbbbec98dc682582a2e0fe022162ffb70b..004bfc7473665160bb259953cf7d7328601bda45 100644 (file)
@@ -23,13 +23,12 @@ import static org.opendaylight.yangtools.sal.java.api.generator.test.Compilation
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.cleanUp;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.getSourceFiles;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.testCompilation;
-
+import com.google.common.collect.ImmutableSet;
 import java.io.File;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.HashSet;
 import java.util.List;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -48,7 +47,7 @@ public class CascadeUsesCompilationTest extends BaseCompilationTest {
         final List<File> sourceFiles = getSourceFiles("/compilation/cascade-uses");
         final SchemaContext context = parser.parseFiles(sourceFiles);
         final List<Type> types = bindingGenerator.generateTypes(context);
-        final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
         generator.generateToFile(sourcesOutputDir);
 
         // Test if all sources are generated from module foo
index 635b3f3447b42eda4b79922f97df6c390500b5f4..073f6a9d775aacc8de7e05350fe5f6550777f0ed 100644 (file)
@@ -27,12 +27,15 @@ import static org.opendaylight.yangtools.sal.java.api.generator.test.Compilation
 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.base.Predicate;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Range;
 import java.io.File;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.WildcardType;
 import java.math.BigDecimal;
@@ -40,7 +43,10 @@ import java.math.BigInteger;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -55,6 +61,21 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
  */
 public class CompilationTest extends BaseCompilationTest {
 
+    /*
+     * Java 8 allows JaCoCo to hook onto interfaces, as well as
+     * generating a default implementation. We only want to check
+     * abstract methods.
+     */
+    private static Collection<Method> abstractMethods(final Class<?> clazz) {
+        // Filter out
+        return Collections2.filter(Arrays.asList(clazz.getDeclaredMethods()), new Predicate<Method>() {
+            @Override
+            public boolean apply(final Method input) {
+                return Modifier.isAbstract(input.getModifiers());
+            }
+        });
+    }
+
     @Test
     public void testListGeneration() throws Exception {
         final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "list-gen");
@@ -105,15 +126,15 @@ public class CompilationTest extends BaseCompilationTest {
 
         // Test generated 'grouping key-args'
         assertTrue(keyArgsClass.isInterface());
-        assertEquals(2, keyArgsClass.getDeclaredMethods().length);
         assertContainsMethod(keyArgsClass, String.class, "getName");
         assertContainsMethod(keyArgsClass, Integer.class, "getSize");
+        assertEquals(2, abstractMethods(keyArgsClass).size());
 
         // Test generated 'list links'
         assertTrue(linksClass.isInterface());
-        // TODO: anyxml
-        assertEquals(6, linksClass.getDeclaredMethods().length);
         assertImplementsIfc(linksClass, keyArgsClass);
+        // TODO: anyxml
+        assertEquals(6, abstractMethods(linksClass).size());
 
         // Test list key constructor arguments ordering
         assertContainsConstructor(linksKeyClass, Byte.class, String.class, Integer.class);
@@ -578,15 +599,21 @@ public class CompilationTest extends BaseCompilationTest {
         cleanUp(sourcesOutputDir, compiledOutputDir);
     }
 
-    private void generateTestSources(String resourceDirPath, File sourcesOutputDir) throws Exception {
+    private void generateTestSources(final String resourceDirPath, final File sourcesOutputDir) throws Exception {
         final List<File> sourceFiles = getSourceFiles(resourceDirPath);
         final SchemaContext context = parser.parseFiles(sourceFiles);
         final List<Type> types = bindingGenerator.generateTypes(context);
-        final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+        Collections.sort(types, new Comparator<Type>() {
+            @Override
+            public int compare(final Type o1, final Type o2) {
+                return o2.getName().compareTo(o1.getName());
+            }
+        });
+        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
         generator.generateToFile(sourcesOutputDir);
     }
 
-    private void testReturnTypeIdentityref(Class<?> clazz, String methodName, String returnTypeStr) throws Exception {
+    private void testReturnTypeIdentityref(final Class<?> clazz, final String methodName, final String returnTypeStr) throws Exception {
         Method method;
         java.lang.reflect.Type returnType;
         try {
@@ -606,7 +633,7 @@ public class CompilationTest extends BaseCompilationTest {
         }
     }
 
-    private void testReturnTypeInstanceIdentitifer(ClassLoader loader, Class<?> clazz, String methodName)
+    private void testReturnTypeInstanceIdentitifer(final ClassLoader loader, final Class<?> clazz, final String methodName)
             throws Exception {
         Method method;
         Class<?> rawReturnType;
index 921aaf0d7dfbbadd5fc0cb2c34a86e3467fd1161..6c607dab10c520e6112f857d630acb4fa1487451 100644 (file)
@@ -381,7 +381,7 @@ public class CompilationTestUtils {
         Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
         Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
         boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
-        assertTrue(compiled);
+        assertTrue("Compilation failed", compiled);
     }
 
     /**
index 80b073fb915c3022660bc753a8bd517b4bab51ce..330b28e46201e3aeb1afacc7d2f962bf442ed4db 100644 (file)
@@ -7,9 +7,8 @@ import static org.opendaylight.yangtools.sal.java.api.generator.test.Compilation
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.cleanUp;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.getSourceFiles;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.testCompilation;
-
+import com.google.common.collect.ImmutableSet;
 import java.io.File;
-import java.util.HashSet;
 import java.util.List;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -32,7 +31,7 @@ public class EndodingInJavaDocTest extends BaseCompilationTest {
         final List<File> sourceFiles = getSourceFiles("/compilation/encoding-javadoc");
         final SchemaContext context = parser.parseFiles(sourceFiles);
         final List<Type> types = bindingGenerator.generateTypes(context);
-        final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
         generator.generateToFile(sourcesOutputDir);
 
         // Test if sources are compilable
index 62190fc4982dcc3aa63638e576b4fcc00e92ea4a..d2fb5a8d50fb8b5a70a2847becb965e194126d77 100644 (file)
@@ -18,11 +18,10 @@ import static org.opendaylight.yangtools.sal.java.api.generator.test.Compilation
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.cleanUp;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.getSourceFiles;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.testCompilation;
-
+import com.google.common.collect.ImmutableSet;
 import java.io.File;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.util.HashSet;
 import java.util.List;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -75,11 +74,11 @@ public class NestedGroupingCompilationTest extends BaseCompilationTest {
         cleanUp(sourcesOutputDir, compiledOutputDir);
     }
 
-    private void generateTestSources(String resourceDirPath, File sourcesOutputDir) throws Exception {
+    private void generateTestSources(final String resourceDirPath, final File sourcesOutputDir) throws Exception {
         final List<File> sourceFiles = getSourceFiles(resourceDirPath);
         final SchemaContext context = parser.parseFiles(sourceFiles);
         final List<Type> types = bindingGenerator.generateTypes(context);
-        final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
         generator.generateToFile(sourcesOutputDir);
     }
 
index 929f8ead287f23bc2c0360bdb50330037dbfc116..86e16edbfaaab34cba193b66a9c6207b8bcc93ad 100644 (file)
@@ -26,6 +26,7 @@ import static org.opendaylight.yangtools.sal.java.api.generator.test.Compilation
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.cleanUp;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.getSourceFiles;
 import static org.opendaylight.yangtools.sal.java.api.generator.test.CompilationTestUtils.testCompilation;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Range;
 import java.io.File;
 import java.lang.reflect.Constructor;
@@ -34,7 +35,6 @@ import java.math.BigDecimal;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 import org.junit.Test;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -62,7 +62,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         final List<File> sourceFiles = getSourceFiles("/compilation/typedef");
         final SchemaContext context = parser.parseFiles(sourceFiles);
         final List<Type> types = bindingGenerator.generateTypes(context);
-        final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
+        final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
         generator.generateToFile(sourcesOutputDir);
 
         File parent = new File(sourcesOutputDir, NS_FOO);
index 2ff3b31375b68767084864428cc93496f45c2e90..d274762ca989790e94fdc23364e8163dfeb36ccc 100644 (file)
@@ -44,6 +44,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
                     </dependency>
                 </dependencies>
             </dependencyManagement>
+            <dependencies>
+              <dependency>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-binding</artifactId>
+              </dependency>
+            </dependencies>
             <build>
                 <pluginManagement>
                     <plugins>
index a58b44767471d86e365420d78147412f46a09a13..ef3f8c7a26ee9241e939c58e7bcdc8fbab2deb06 100644 (file)
                 <artifactId>antlr4-runtime-osgi-nohead</artifactId>
                 <version>4.0</version>
             </dependency>
-            <dependency>
-                <groupId>org.opendaylight.yangtools.thirdparty</groupId>
-                <artifactId>xtend-lib-osgi</artifactId>
-                <version>2.4.3</version>
-            </dependency>
             <dependency>
                 <groupId>org.opendaylight.yangtools</groupId>
                 <artifactId>concepts</artifactId>
index 9910970400f63ba59fec35f09498aa1e2c33a087..dbf95156e7ee86a1fee7419e863edf9167ebd6ca 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>binding-data-codec</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools.thirdparty</groupId>
-            <artifactId>xtend-lib-osgi</artifactId>
-            <scope>compile</scope>
-        </dependency>
         <dependency>
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>
index ba174b1678e90836bcc91264195b3def57cf7d70..673c7bced9c22e87bec86988dd0442ccb674f07f 100644 (file)
@@ -79,7 +79,6 @@
         <bundle>mvn:org.opendaylight.yangtools/binding-model-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/binding-type-provider/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/binding-data-codec/{{VERSION}}</bundle>
-        <bundle>mvn:org.opendaylight.yangtools.thirdparty/xtend-lib-osgi/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/yang-model-api/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/yang-model-util/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/yang-parser-api/{{VERSION}}</bundle>
index 7a213959341bd941e4f29f6a3d045d521fed8f3f..f045623fcc30aec64a3f2bab535b537259b45df0 100644 (file)
             <dependency>
                 <groupId>org.eclipse.xtend</groupId>
                 <artifactId>org.eclipse.xtend.lib</artifactId>
-                <version>2.4.3</version>
+                <version>2.7.3</version>
             </dependency>
             <dependency>
                 <groupId>org.osgi</groupId>
                 <plugin>
                     <groupId>org.eclipse.xtend</groupId>
                     <artifactId>xtend-maven-plugin</artifactId>
-                    <version>${xtend.version}</version>
+                    <version>2.7.3</version>
                     <executions>
                         <execution>
                             <goals>
index 4fde8986ea2d7ece186c3cb3ac40836b24232f3f..63de755288a069f5c5548348daca887848b6c388 100644 (file)
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-classic</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.sonatype.plexus</groupId>
-            <artifactId>plexus-build-api</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.codehaus.plexus</groupId>
             <artifactId>plexus-slf4j-logging</artifactId>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
-            <artifactId>maven-sal-api-gen-plugin</artifactId>
+            <artifactId>binding-generator-impl</artifactId>
         </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools.thirdparty</groupId>
             <artifactId>antlr4-runtime-osgi-nohead</artifactId>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.opendaylight.yangtools.thirdparty</groupId>
-            <artifactId>xtend-lib-osgi</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
 
     <build>
index 1b5e1d85483f4222e557d5d6dacf62f5e0189f38..932ed416bbf3bddf33528ba7290eb88b09d4e914 100644 (file)
@@ -42,9 +42,6 @@ public class BundleStartTest {
         options.add(mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject());
         options.add(mavenBundle("org.opendaylight.yangtools.thirdparty", "antlr4-runtime-osgi-nohead")
                 .versionAsInProject());
-        options.add(mavenBundle("org.opendaylight.yangtools.thirdparty", "xtend-lib-osgi").versionAsInProject());
-        options.add(mavenBundle("org.sonatype.plexus", "plexus-build-api").versionAsInProject());
-        options.add(mavenBundle("org.codehaus.plexus", "plexus-slf4j-logging").versionAsInProject());
         options.add(mavenBundle("org.javassist", "javassist").versionAsInProject());
 
         options.add(mavenBundle(GROUP, "concepts").versionAsInProject());
@@ -64,10 +61,8 @@ public class BundleStartTest {
         options.add(mavenBundle(GROUP, "binding-generator-impl").versionAsInProject());
         options.add(mavenBundle(GROUP, "binding-generator-spi").versionAsInProject());
         options.add(mavenBundle(GROUP, "binding-generator-util").versionAsInProject());
-        options.add(mavenBundle(GROUP, "binding-java-api-generator").versionAsInProject());
         options.add(mavenBundle(GROUP, "binding-model-api").versionAsInProject());
         options.add(mavenBundle(GROUP, "binding-type-provider").versionAsInProject());
-        options.add(mavenBundle(GROUP, "maven-sal-api-gen-plugin").versionAsInProject());
 
         options.add(junitBundles());
         return options;
@@ -96,9 +91,7 @@ public class BundleStartTest {
         testBundle("binding-generator-spi");
         testBundle("binding-generator-util");
         testBundle("binding-model-api");
-        testBundle("binding-java-api-generator");
         testBundle("binding-type-provider");
-        testBundle("maven-sal-api-gen-plugin");
     }
 
     private void testBundle(String name) throws BundleException {
index 0d2c3fc18efe09c82e6771699c4703a023947cb8..c22c469cc2f12640b191530b351e5e98d44ab405 100644 (file)
@@ -24,7 +24,6 @@
     <packaging>pom</packaging>
 
     <modules>
-        <module>xtend-lib-osgi</module>
         <module>antlr4-runtime-osgi</module>
     </modules>
 
diff --git a/third-party/xtend-lib-osgi/pom.xml b/third-party/xtend-lib-osgi/pom.xml
deleted file mode 100644 (file)
index ca98a46..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?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">
-    <modelVersion>4.0.0</modelVersion>
-    <parent>
-        <groupId>org.opendaylight.yangtools</groupId>
-        <artifactId>third-party-parent</artifactId>
-        <version>0.7.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <artifactId>xtend-lib-osgi</artifactId>
-    <version>2.4.3</version>
-    <packaging>bundle</packaging>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <extensions>true</extensions>
-                <configuration>
-                    <instructions>
-                       <Bundle-Name>Xtend Runtime Library</Bundle-Name>
-                        <Bundle-SymbolicName>org.eclipse.xtend.lib</Bundle-SymbolicName>
-                        <Import-Package>
-                        com.google.common.base;version="[10.0.1,16)",
-                        com.google.common.collect;version="[10.0.1,16)",
-                        com.google.common.primitives;version="[10.0.1,16)"
-                        </Import-Package>
-                    </instructions>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.eclipse.xtend</groupId>
-            <artifactId>org.eclipse.xtend.lib</artifactId>
-            <version>2.4.3</version>
-        </dependency>
-        <dependency>
-            <groupId>org.eclipse.xtext</groupId>
-            <artifactId>org.eclipse.xtext.xbase.lib</artifactId>
-            <version>2.4.3</version>
-        </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <version>[10.0.1,15.0)</version>
-            <scope>provided</scope>
-        </dependency>
-    </dependencies>
-</project>
index ecda366de034c91513cbe452c8841e121c055179..cfece17b886c8616c222790bd7e996d270fc0486 100644 (file)
@@ -33,7 +33,7 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
  * and {@link StoreMetadataNode} which represents original state {@link #getOriginal()}.
  */
 @NotThreadSafe
-final class ModifiedNode implements StoreTreeNode<ModifiedNode>, Identifiable<PathArgument>, NodeModification {
+final class ModifiedNode extends NodeModification implements StoreTreeNode<ModifiedNode> {
 
     public static final Predicate<ModifiedNode> IS_TERMINAL_PREDICATE = new Predicate<ModifiedNode>() {
         @Override
@@ -91,7 +91,7 @@ final class ModifiedNode implements StoreTreeNode<ModifiedNode>, Identifiable<Pa
      * @return original store metadata
      */
     @Override
-    public Optional<TreeNode> getOriginal() {
+    Optional<TreeNode> getOriginal() {
         return original;
     }
 
@@ -101,7 +101,7 @@ final class ModifiedNode implements StoreTreeNode<ModifiedNode>, Identifiable<Pa
      * @return modification type
      */
     @Override
-    public ModificationType getType() {
+    ModificationType getType() {
         return modificationType;
     }
 
@@ -160,7 +160,7 @@ final class ModifiedNode implements StoreTreeNode<ModifiedNode>, Identifiable<Pa
      * @return all recorded direct child modifications
      */
     @Override
-    public Iterable<ModifiedNode> getChildren() {
+    Iterable<ModifiedNode> getChildren() {
         return children.values();
     }
 
@@ -270,6 +270,19 @@ final class ModifiedNode implements StoreTreeNode<ModifiedNode>, Identifiable<Pa
                 + modificationType + ", childModification=" + children + "]";
     }
 
+    /**
+     * Create a node which will reflect the state of this node, except it will behave as newly-written
+     * value. This is useful only for merge validation.
+     *
+     * @param value Value associated with the node
+     * @return An isolated node. This node should never reach a datatree.
+     */
+    ModifiedNode asNewlyWritten(final NormalizedNode<?, ?> value) {
+        final ModifiedNode ret = new ModifiedNode(getIdentifier(), Optional.<TreeNode>absent(), false);
+        ret.write(value);
+        return ret;
+    }
+
     public static ModifiedNode createUnmodified(final TreeNode metadataTree, final boolean isOrdered) {
         return new ModifiedNode(metadataTree.getIdentifier(), Optional.of(metadataTree), isOrdered);
     }
index 409a713d4904498f71137802482046486990795c..8e92ff1f22af9a54444033d8af1a18f4f04cdfe6 100644 (file)
@@ -19,13 +19,13 @@ import org.opendaylight.yangtools.yang.data.api.schema.tree.spi.TreeNode;
  * It is used by the validation code to allow for a read-only view of the
  * modification tree as we should never modify that during validation.
  */
-interface NodeModification extends Identifiable<PathArgument> {
+abstract class NodeModification implements Identifiable<PathArgument> {
     /**
      * Get the type of modification.
      *
      * @return Modification type.
      */
-    ModificationType getType();
+    abstract ModificationType getType();
 
     /**
      * Get the original tree node to which the modification is to be applied.
@@ -33,12 +33,12 @@ interface NodeModification extends Identifiable<PathArgument> {
      * @return The original node, or {@link Optional#absent()} if the node is
      *         a new node.
      */
-    Optional<TreeNode> getOriginal();
+    abstract Optional<TreeNode> getOriginal();
 
     /**
      * Get a read-only view of children nodes.
      *
      * @return Iterable of all children nodes.
      */
-    Iterable<? extends NodeModification> getChildren();
+    abstract Iterable<? extends NodeModification> getChildren();
 }
index bcf2101ff07d49572d3cbdb8a92cc3e849dbfc45..3293a05b066edea7cc77a9e51796794063fd4c4c 100644 (file)
@@ -31,13 +31,13 @@ final class OperationWithModification {
         applyOperation.verifyStructure(modification);
     }
 
-    private void mergeImpl(final NormalizedNode<?,?> data) {
+    private void recursiveMerge(final NormalizedNode<?,?> data) {
         if (data instanceof NormalizedNodeContainer<?,?,?>) {
             @SuppressWarnings({ "rawtypes", "unchecked" })
             NormalizedNodeContainer<?,?,NormalizedNode<PathArgument, ?>> dataContainer = (NormalizedNodeContainer) data;
             for (NormalizedNode<PathArgument, ?> child : dataContainer.getValue()) {
                 PathArgument childId = child.getIdentifier();
-                forChild(childId).mergeImpl(child);
+                forChild(childId).recursiveMerge(child);
             }
         }
 
@@ -45,8 +45,16 @@ final class OperationWithModification {
     }
 
     void merge(final NormalizedNode<?, ?> data) {
-        mergeImpl(data);
-        applyOperation.verifyStructure(modification);
+        /*
+         * A merge operation will end up overwriting parts of the tree, retaining others.
+         * We want to make sure we do not validate the complete resulting structure, but
+         * rather just what was written. In order to do that, we first pretend the data
+         * was written, run verification and then perform the merge -- with the explicit
+         * assumption that adding the newly-validated data with the previously-validated
+         * data will not result in invalid data.
+         */
+        applyOperation.verifyStructure(modification.asNewlyWritten(data));
+        recursiveMerge(data);
     }
 
     void delete() {