Merge "Checkstyle enforcer"
authorMadhu Venugopal <vmadhu@cisco.com>
Wed, 12 Jun 2013 16:49:08 +0000 (16:49 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 12 Jun 2013 16:49:08 +0000 (16:49 +0000)
25 files changed:
opendaylight/sal/yang-prototype/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/controller/maven/sal/api/gen/plugin/CodeGeneratorImpl.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/java/org/opendaylight/controller/yang2sources/plugin/it/YangToSourcesPluginTestIT.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin-it/src/test/resources/AdditionalConfig/pom.xml
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/ConfigArg.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/Util.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesMojo.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/main/java/org/opendaylight/controller/yang2sources/plugin/YangToSourcesProcessor.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/GenerateSourcesTest.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/java/org/opendaylight/controller/yang2sources/plugin/UtilTest.java
opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/yang/mock.yang [moved from opendaylight/sal/yang-prototype/code-generator/maven-yang-plugin/src/test/resources/mock.yang with 100% similarity]
opendaylight/sal/yang-prototype/code-generator/maven-yang/pom.xml
opendaylight/sal/yang-prototype/code-generator/maven-yang/src/main/java/org/opendaylight/controller/yang2sources/spi/CodeGenerator.java
opendaylight/sal/yang-prototype/code-generator/maven-yang/src/test/java/org/opendaylight/controller/yang2sources/spi/CodeGeneratorTestImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/TypeDefinitionBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/TypeConstraints.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TestUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/TypesResolutionTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserNegativeTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java
opendaylight/sal/yang-prototype/yang/yang-model-api/src/main/java/org/opendaylight/controller/yang/model/api/LeafSchemaNode.java

index 1876c689c0e5a10b44f554f51905e4f9b4a6ad0f..491cef6bcc3caf99bfb61e83f10d1aa678cc7332 100644 (file)
@@ -16,6 +16,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.controller.sal.binding.generator.impl.BindingGeneratorImpl;
 import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;
@@ -30,8 +31,7 @@ public class CodeGeneratorImpl implements CodeGenerator {
 
     @Override
     public Collection<File> generateSources(SchemaContext context,
-            File outputBaseDir, Set<Module> yangModules, File projectBaseDir)
-            throws IOException {
+            File outputBaseDir, Set<Module> yangModules) throws IOException {
 
         final BindingGenerator bindingGenerator = new BindingGeneratorImpl();
         final List<Type> types = bindingGenerator.generateTypes(context);
@@ -49,9 +49,7 @@ public class CodeGeneratorImpl implements CodeGenerator {
         final GeneratorJavaFile generator = new GeneratorJavaFile(
                 typesToGenerate, tosToGenerate);
 
-        return generator.generateToFile(outputBaseDir.getPath().startsWith(
-                projectBaseDir.getPath()) ? outputBaseDir : new File(
-                projectBaseDir, outputBaseDir.getPath()));
+        return generator.generateToFile(outputBaseDir);
     }
 
     @Override
@@ -65,4 +63,14 @@ public class CodeGeneratorImpl implements CodeGenerator {
         // no additional config utilized
     }
 
+    @Override
+    public void setResourceBaseDir(File resourceBaseDir) {
+        // no resource processing necessary
+    }
+
+    @Override
+    public void setMavenProject(MavenProject project) {
+        // no additional information needed
+    }
+
 }
index 9535468ed52fefedaa58fb0aca0860337aa9d74e..280284bcba38d9378a54c225d53a69f7ad02dc5a 100644 (file)
@@ -45,8 +45,10 @@ public class YangToSourcesPluginTestIT {
     @Test
     public void testAdditionalConfiguration() throws VerificationException {
         Verifier v = setUp("AdditionalConfig/", false);
-        v.verifyTextInLog("[INFO] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {nm1=abcd=a.b.c.d, nm2=abcd2=a.b.c.d.2}");
-        v.verifyTextInLog("[INFO] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {c1=config}");
+        v.verifyTextInLog("[DEBUG] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {nm1=abcd=a.b.c.d, nm2=abcd2=a.b.c.d.2}");
+        v.verifyTextInLog("[DEBUG] yang-to-sources: Additional configuration picked up for : org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl: {c1=config}");
+        v.verifyTextInLog("../files marked as resources: META-INF/yang");
+        v.verifyTextInLog("target/generated-resources marked as resources for generator: org.opendaylight.controller.yang2sources.spi.CodeGeneratorTestImpl");
     }
 
     @Test
@@ -106,6 +108,7 @@ public class YangToSourcesPluginTestIT {
                 + project).getAbsolutePath());
         if (ignoreF)
             verifier.addCliOption("-fn");
+        verifier.setMavenDebug(true);
         verifier.executeGoal("generate-sources");
         return verifier;
     }
index b7baa743388986fcac742805d54f0ff256b09f3c..8bd2289b116e37f0523f993028525e293113031c 100644 (file)
@@ -37,6 +37,7 @@
                                         <nm1>abcd=a.b.c.d</nm1>
                                         <nm2>abcd2=a.b.c.d.2</nm2>
                                     </additionalConfiguration>
+                                    <resourceBaseDir>/target/resourcesGenerated</resourceBaseDir>
                                 </generator>
                                 <generator>
                                     <codeGeneratorClass>
index aaf7080a6234c8e6a4155b42ec8dc20d3c7cc58f..0df9a6345ee9384b316f3d71093fa19a9796a658 100644 (file)
@@ -42,7 +42,10 @@ public abstract class ConfigArg {
     public static final class CodeGeneratorArg extends ConfigArg {
         private static final String CODE_GEN_DEFAULT_DIR = "target"
                 + File.separator + "generated-sources";
+        private static final String CODE_GEN_DEFAULT_RESOURCE_DIR = "target"
+                + File.separator + "generated-resources";
         private String codeGeneratorClass;
+        private File resourceBaseDir = new File(CODE_GEN_DEFAULT_RESOURCE_DIR);
 
         private Map<String, String> additionalConfiguration = Maps.newHashMap();
 
@@ -59,6 +62,13 @@ public abstract class ConfigArg {
             this.codeGeneratorClass = codeGeneratorClass;
         }
 
+        public CodeGeneratorArg(String codeGeneratorClass,
+                String outputBaseDir, String resourceBaseDir) {
+            super(outputBaseDir);
+            this.codeGeneratorClass = codeGeneratorClass;
+            this.resourceBaseDir = new File(resourceBaseDir);
+        }
+
         @Override
         public void check() {
             Preconditions.checkNotNull(codeGeneratorClass,
@@ -69,6 +79,14 @@ public abstract class ConfigArg {
             return codeGeneratorClass;
         }
 
+        public File getResourceBaseDir(MavenProject project) {
+            if (resourceBaseDir.isAbsolute()) {
+                return resourceBaseDir;
+            } else {
+                return new File(project.getBasedir(), resourceBaseDir.getPath());
+            }
+        }
+
         public Map<String, String> getAdditionalConfiguration() {
             return additionalConfiguration;
         }
index 653c0bff6d5b6c1fca52c9ff891df60be1385ba2..7b83af42428d9e6ebbda79b301e80f1672c114fd 100644 (file)
@@ -7,21 +7,31 @@
  */
 package org.opendaylight.controller.yang2sources.plugin;
 
+import java.io.Closeable;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Enumeration;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
+import org.opendaylight.controller.yang.model.api.Module;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
 
-import com.google.common.base.Function;
-import com.google.common.collect.Collections2;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
@@ -81,23 +91,6 @@ final class Util {
         }
     }
 
-    static String[] listFilesAsArrayOfPaths(File rootDir)
-            throws FileNotFoundException {
-        String[] filesArray = new String[] {};
-        Collection<File> yangFiles = listFiles(rootDir);
-
-        // If collection is empty, return empty array [] rather then [null]
-        // array, that is created by default
-        return yangFiles.isEmpty() ? filesArray : Collections2.transform(
-                yangFiles, new Function<File, String>() {
-
-                    @Override
-                    public String apply(File input) {
-                        return input.getPath();
-                    }
-                }).toArray(filesArray);
-    }
-
     private static void toCache(final File rootDir,
             final Collection<File> yangFiles) {
         cache.put(rootDir, yangFiles);
@@ -137,7 +130,7 @@ final class Util {
         return String.format("%s %s", logPrefix, innerMessage);
     }
 
-    public static List<File> getClassPath(MavenProject project) {
+    static List<File> getClassPath(MavenProject project) {
         List<File> dependencies = Lists.newArrayList();
         for (Artifact element : project.getArtifacts()) {
             File asFile = element.getFile();
@@ -155,13 +148,117 @@ final class Util {
                 : false;
     }
 
-    public static boolean acceptedFilter(String name, List<String> filter) {
-        for (String f : filter) {
-            if (name.endsWith(f)) {
-                return true;
+    static <T> T checkNotNull(T obj, String paramName) {
+        return Preconditions.checkNotNull(obj, "Parameter " + paramName
+                + " is null");
+    }
+
+    final static class YangsInZipsResult implements Closeable {
+        final List<InputStream> yangStreams;
+        private final List<Closeable> zipInputStreams;
+
+        private YangsInZipsResult(List<InputStream> yangStreams,
+                List<Closeable> zipInputStreams) {
+            this.yangStreams = yangStreams;
+            this.zipInputStreams = zipInputStreams;
+        }
+
+        @Override
+        public void close() throws IOException {
+            for (InputStream is : yangStreams) {
+                is.close();
+            }
+            for (Closeable is : zipInputStreams) {
+                is.close();
             }
         }
-        return false;
+    }
+
+    static YangsInZipsResult findYangFilesInDependenciesAsStream(Log log,
+            MavenProject project)
+            throws MojoFailureException {
+        List<InputStream> yangsFromDependencies = new ArrayList<>();
+        List<Closeable> zips = new ArrayList<>();
+        try {
+            List<File> filesOnCp = Util.getClassPath(project);
+            log.info(Util.message(
+                    "Searching for yang files in following dependencies: %s",
+                    YangToSourcesProcessor.LOG_PREFIX, filesOnCp));
+
+            for (File file : filesOnCp) {
+                List<String> foundFilesForReporting = new ArrayList<>();
+                // is it jar file or directory?
+                if (file.isDirectory()) {
+                    File yangDir = new File(file,
+                            YangToSourcesProcessor.META_INF_YANG_STRING);
+                    if (yangDir.exists() && yangDir.isDirectory()) {
+                        File[] yangFiles = yangDir
+                                .listFiles(new FilenameFilter() {
+                                    @Override
+                                    public boolean accept(File dir, String name) {
+                                        return name.endsWith(".yang")
+                                                && new File(dir, name).isFile();
+                                    }
+                                });
+                        for (File yangFile : yangFiles) {
+                            yangsFromDependencies.add(new NamedFileInputStream(
+                                    yangFile));
+                        }
+                    }
+
+                } else {
+                    ZipFile zip = new ZipFile(file);
+                    zips.add(zip);
+
+                    Enumeration<? extends ZipEntry> entries = zip.entries();
+                    while (entries.hasMoreElements()) {
+                        ZipEntry entry = entries.nextElement();
+                        String entryName = entry.getName();
+
+                        if (entryName
+                                .startsWith(YangToSourcesProcessor.META_INF_YANG_STRING)) {
+                            if (entry.isDirectory() == false
+                                    && entryName.endsWith(".yang")) {
+                                foundFilesForReporting.add(entryName);
+                                // This will be closed after all strams are
+                                // parsed.
+                                InputStream entryStream = zip
+                                        .getInputStream(entry);
+                                yangsFromDependencies.add(entryStream);
+                            }
+                        }
+                    }
+                }
+                if (foundFilesForReporting.size() > 0) {
+                    log.info(Util.message("Found %d yang files in %s: %s",
+                            YangToSourcesProcessor.LOG_PREFIX,
+                            foundFilesForReporting.size(), file,
+                            foundFilesForReporting));
+                }
+
+            }
+        } catch (Exception e) {
+            throw new MojoFailureException(e.getMessage(), e);
+        }
+        return new YangsInZipsResult(yangsFromDependencies, zips);
+    }
+
+    final static class ContextHolder {
+        private final SchemaContext context;
+        private final Set<Module> yangModules;
+
+        ContextHolder(SchemaContext context, Set<Module> yangModules) {
+            this.context = context;
+            this.yangModules = yangModules;
+        }
+
+        SchemaContext getContext() {
+            return context;
+        }
+
+        Set<Module> getYangModules() {
+            return yangModules;
+        }
     }
 
 }
index 7dbd8568240b802d0c105a309eaca270ab5d1eae..6e43b306cd44d82b1cdcaa32b5b54c976fc41a71 100644 (file)
@@ -64,41 +64,58 @@ public final class YangToSourcesMojo extends AbstractMojo {
     @Parameter(property = "inspectDependencies", required = true, readonly = true)
     private boolean inspectDependencies;
 
+    private YangToSourcesProcessor yangToSourcesProcessor;
+
     public YangToSourcesMojo() {
 
     }
 
     @VisibleForTesting
-    YangToSourcesMojo(CodeGeneratorArg[] codeGeneratorArgs,
-            String yangFilesRootDir) {
-        this.codeGenerators = codeGeneratorArgs;
-        this.yangFilesRootDir = yangFilesRootDir;
+    YangToSourcesMojo(YangToSourcesProcessor processor) {
+        this.yangToSourcesProcessor = processor;
     }
 
     @Override
     public void execute() throws MojoExecutionException, MojoFailureException {
+        if (yangToSourcesProcessor == null) {
+            List<CodeGeneratorArg> codeGeneratorArgs = processCodeGenerators(codeGenerators);
+
+            // defaults to ${basedir}/src/main/yang
+            File yangFilesRootFile = processYangFilesRootDir(yangFilesRootDir,
+                    project.getBasedir());
+
+            yangToSourcesProcessor = new YangToSourcesProcessor(getLog(),
+                    yangFilesRootFile, codeGeneratorArgs, project,
+                    inspectDependencies);
+        }
+        yangToSourcesProcessor.execute();
+    }
+
+    private static List<CodeGeneratorArg> processCodeGenerators(
+            CodeGeneratorArg[] codeGenerators) {
         List<CodeGeneratorArg> codeGeneratorArgs;
         if (codeGenerators == null) {
             codeGeneratorArgs = Collections.emptyList();
         } else {
             codeGeneratorArgs = Arrays.asList(codeGenerators);
         }
+        return codeGeneratorArgs;
+    }
 
-        // defaults to ${basedir}/src/main/yang
+    private static File processYangFilesRootDir(String yangFilesRootDir,
+            File baseDir) {
         File yangFilesRootFile;
         if (yangFilesRootDir == null) {
-            yangFilesRootFile = new File(project.getBasedir(), "src"
-                    + File.separator + "main" + File.separator + "yang");
+            yangFilesRootFile = new File(baseDir, "src" + File.separator
+                    + "main" + File.separator + "yang");
         } else {
             File file = new File(yangFilesRootDir);
             if (file.isAbsolute()) {
                 yangFilesRootFile = file;
             } else {
-                yangFilesRootFile = new File(project.getBasedir(),
-                        file.getPath());
+                yangFilesRootFile = new File(baseDir, file.getPath());
             }
         }
-        new YangToSourcesProcessor(getLog(), yangFilesRootFile,
-                codeGeneratorArgs, project, inspectDependencies).execute();
+        return yangFilesRootFile;
     }
 }
index be92af0126cb07aed0027a831287767091ad1c25..770eeee964895bd0714cdc00eb0e08d7850923cf 100644 (file)
@@ -9,19 +9,15 @@ package org.opendaylight.controller.yang2sources.plugin;
 
 import java.io.Closeable;
 import java.io.File;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Enumeration;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 
 import org.apache.maven.model.Resource;
 import org.apache.maven.plugin.MojoExecutionException;
@@ -33,46 +29,51 @@ import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.SchemaContext;
 import org.opendaylight.controller.yang.parser.impl.YangParserImpl;
 import org.opendaylight.controller.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
-import org.opendaylight.controller.yang2sources.plugin.Util.NamedFileInputStream;
+import org.opendaylight.controller.yang2sources.plugin.Util.ContextHolder;
+import org.opendaylight.controller.yang2sources.plugin.Util.YangsInZipsResult;
 import org.opendaylight.controller.yang2sources.spi.CodeGenerator;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Maps;
 
 class YangToSourcesProcessor {
-    private static final String LOG_PREFIX = "yang-to-sources:";
-    private static final String META_INF_YANG_STRING = "META-INF"
-            + File.separator + "yang";
-    private static final File META_INF_YANG_DIR = new File(META_INF_YANG_STRING);
+    static final String LOG_PREFIX = "yang-to-sources:";
+    static final String META_INF_YANG_STRING = "META-INF" + File.separator
+            + "yang";
+    static final File META_INF_YANG_DIR = new File(META_INF_YANG_STRING);
 
     private final Log log;
     private final File yangFilesRootDir;
     private final List<CodeGeneratorArg> codeGenerators;
     private final MavenProject project;
     private final boolean inspectDependencies;
+    private YangProvider yangProvider;
 
+    @VisibleForTesting
     YangToSourcesProcessor(Log log, File yangFilesRootDir,
             List<CodeGeneratorArg> codeGenerators, MavenProject project,
-            boolean inspectDependencies) {
-        this.log = checkNotNull(log, "log");
-        this.yangFilesRootDir = checkNotNull(yangFilesRootDir,
+            boolean inspectDependencies, YangProvider yangProvider) {
+        this.log = Util.checkNotNull(log, "log");
+        this.yangFilesRootDir = Util.checkNotNull(yangFilesRootDir,
                 "yangFilesRootDir");
-        this.codeGenerators = Collections.unmodifiableList(checkNotNull(
+        this.codeGenerators = Collections.unmodifiableList(Util.checkNotNull(
                 codeGenerators, "codeGenerators"));
-        this.project = checkNotNull(project, "project");
+        this.project = Util.checkNotNull(project, "project");
         this.inspectDependencies = inspectDependencies;
+        this.yangProvider = yangProvider;
     }
 
-    private static <T> T checkNotNull(T obj, String paramName) {
-        if (obj == null)
-            throw new NullPointerException("Parameter '" + paramName
-                    + "' is null");
-        return obj;
+    YangToSourcesProcessor(Log log, File yangFilesRootDir,
+            List<CodeGeneratorArg> codeGenerators, MavenProject project,
+            boolean inspectDependencies) {
+        this(log, yangFilesRootDir, codeGenerators, project,
+                inspectDependencies, new YangProvider());
     }
 
     public void execute() throws MojoExecutionException, MojoFailureException {
         ContextHolder context = processYang();
         generateSources(context);
-        addYangsToMETA_INF();
+        yangProvider.addYangsToMETA_INF(log, project, yangFilesRootDir);
     }
 
     private ContextHolder processYang() throws MojoExecutionException {
@@ -88,7 +89,8 @@ class YangToSourcesProcessor {
             Set<Module> projectYangModules;
             try {
                 if (inspectDependencies) {
-                    YangsInZipsResult dependentYangResult = findYangFilesInDependenciesAsStream();
+                    YangsInZipsResult dependentYangResult = Util
+                            .findYangFilesInDependenciesAsStream(log, project);
                     Closeable dependentYangResult1 = dependentYangResult;
                     closeables.add(dependentYangResult1);
                     all.addAll(dependentYangResult.yangStreams);
@@ -124,20 +126,38 @@ class YangToSourcesProcessor {
         }
     }
 
-    private void addYangsToMETA_INF() throws MojoFailureException {
-        Resource res = new Resource();
+    static class YangProvider {
 
-        File targetYangDir = new File(project.getBasedir(), "target"
-                + File.separator + "yang");
-        res.setDirectory(targetYangDir.getPath());
+        private static final String yangResourceDir = "target" + File.separator
+                + "yang";
 
-        res.setTargetPath(META_INF_YANG_DIR.getPath());
-        try {
-            FileUtils.copyDirectory(yangFilesRootDir, targetYangDir);
-        } catch (IOException e) {
-            throw new MojoFailureException(e.getMessage(), e);
+        void addYangsToMETA_INF(Log log, MavenProject project,
+                File yangFilesRootDir) throws MojoFailureException {
+            File targetYangDir = new File(project.getBasedir(), yangResourceDir);
+
+            try {
+                FileUtils.copyDirectory(yangFilesRootDir, targetYangDir);
+            } catch (IOException e) {
+                String message = "Unable to copy yang files into resource folder";
+                log.warn(message, e);
+                throw new MojoFailureException(message, e);
+            }
+
+            setResource(targetYangDir, META_INF_YANG_DIR.getPath(), project);
+
+            log.debug(Util.message(
+                    "Yang files from: %s marked as resources: %s", LOG_PREFIX,
+                    yangFilesRootDir, META_INF_YANG_DIR.getPath()));
+        }
+
+        private static void setResource(File targetYangDir, String targetPath,
+                MavenProject project) {
+            Resource res = new Resource();
+            res.setDirectory(targetYangDir.getPath());
+            if (targetPath != null)
+                res.setTargetPath(targetPath);
+            project.addResource(res);
         }
-        project.addResource(res);
     }
 
     /**
@@ -192,122 +212,30 @@ class YangToSourcesProcessor {
 
         log.info(Util.message("Sources will be generated to %s", LOG_PREFIX,
                 outputDir));
-        log.info(Util.message("Project root dir is %s", LOG_PREFIX,
+        log.debug(Util.message("Project root dir is %s", LOG_PREFIX,
                 project.getBasedir()));
-        log.info(Util.message(
+        log.debug(Util.message(
                 "Additional configuration picked up for : %s: %s", LOG_PREFIX,
                 codeGeneratorCfg.getCodeGeneratorClass(),
                 codeGeneratorCfg.getAdditionalConfiguration()));
+
         project.addCompileSourceRoot(outputDir.getAbsolutePath());
         g.setLog(log);
+        g.setMavenProject(project);
         g.setAdditionalConfig(codeGeneratorCfg.getAdditionalConfiguration());
-        Collection<File> generated = g.generateSources(context.getContext(),
-                outputDir, context.getYangModules(), project.getBasedir());
-        log.info(Util.message("Sources generated by %s: %s", LOG_PREFIX,
-                codeGeneratorCfg.getCodeGeneratorClass(), generated));
-    }
-
-    private class YangsInZipsResult implements Closeable {
-        private final List<InputStream> yangStreams;
-        private final List<Closeable> zipInputStreams;
+        File resourceBaseDir = codeGeneratorCfg.getResourceBaseDir(project);
 
-        private YangsInZipsResult(List<InputStream> yangStreams,
-                List<Closeable> zipInputStreams) {
-            this.yangStreams = yangStreams;
-            this.zipInputStreams = zipInputStreams;
-        }
+        YangProvider.setResource(resourceBaseDir, null, project);
+        g.setResourceBaseDir(resourceBaseDir);
+        log.debug(Util.message(
+                "Folder: %s marked as resources for generator: %s", LOG_PREFIX,
+                resourceBaseDir, codeGeneratorCfg.getCodeGeneratorClass()));
 
-        @Override
-        public void close() throws IOException {
-            for (InputStream is : yangStreams) {
-                is.close();
-            }
-            for (Closeable is : zipInputStreams) {
-                is.close();
-            }
-        }
-    }
-
-    private YangsInZipsResult findYangFilesInDependenciesAsStream()
-            throws MojoFailureException {
-        List<InputStream> yangsFromDependencies = new ArrayList<>();
-        List<Closeable> zips = new ArrayList<>();
-        try {
-            List<File> filesOnCp = Util.getClassPath(project);
-            log.info(Util.message(
-                    "Searching for yang files in following dependencies: %s",
-                    LOG_PREFIX, filesOnCp));
-
-            for (File file : filesOnCp) {
-                List<String> foundFilesForReporting = new ArrayList<>();
-                // is it jar file or directory?
-                if (file.isDirectory()) {
-                    File yangDir = new File(file, META_INF_YANG_STRING);
-                    if (yangDir.exists() && yangDir.isDirectory()) {
-                        File[] yangFiles = yangDir
-                                .listFiles(new FilenameFilter() {
-                                    @Override
-                                    public boolean accept(File dir, String name) {
-                                        return name.endsWith(".yang")
-                                                && new File(dir, name).isFile();
-                                    }
-                                });
-                        for (File yangFile : yangFiles) {
-                            yangsFromDependencies.add(new NamedFileInputStream(
-                                    yangFile));
-                        }
-                    }
-
-                } else {
-                    ZipFile zip = new ZipFile(file);
-                    zips.add(zip);
-
-                    Enumeration<? extends ZipEntry> entries = zip.entries();
-                    while (entries.hasMoreElements()) {
-                        ZipEntry entry = entries.nextElement();
-                        String entryName = entry.getName();
-
-                        if (entryName.startsWith(META_INF_YANG_STRING)) {
-                            if (entry.isDirectory() == false
-                                    && entryName.endsWith(".yang")) {
-                                foundFilesForReporting.add(entryName);
-                                // This will be closed after all strams are
-                                // parsed.
-                                InputStream entryStream = zip
-                                        .getInputStream(entry);
-                                yangsFromDependencies.add(entryStream);
-                            }
-                        }
-                    }
-                }
-                if (foundFilesForReporting.size() > 0) {
-                    log.info(Util.message("Found %d yang files in %s: %s",
-                            LOG_PREFIX, foundFilesForReporting.size(), file,
-                            foundFilesForReporting));
-                }
+        Collection<File> generated = g.generateSources(context.getContext(),
+                outputDir, context.getYangModules());
 
-            }
-        } catch (Exception e) {
-            throw new MojoFailureException(e.getMessage(), e);
-        }
-        return new YangsInZipsResult(yangsFromDependencies, zips);
+        log.info(Util.message("Sources generated by %s: %s", LOG_PREFIX,
+                codeGeneratorCfg.getCodeGeneratorClass(), generated));
     }
 
-    private class ContextHolder {
-        private final SchemaContext context;
-        private final Set<Module> yangModules;
-
-        private ContextHolder(SchemaContext context, Set<Module> yangModules) {
-            this.context = context;
-            this.yangModules = yangModules;
-        }
-
-        public SchemaContext getContext() {
-            return context;
-        }
-
-        public Set<Module> getYangModules() {
-            return yangModules;
-        }
-    }
 }
index 1bfe9d4d0c01e0522fb48799d38c2a947cdc1a07..14e9d34b2aeec672c4f3ff15b26ec2a57b8bd5d0 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.controller.yang2sources.plugin;
 
-import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.Is.*;
 import static org.junit.Assert.*;
-import static org.mockito.Mockito.doReturn;
+import static org.junit.matchers.JUnitMatchers.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
 
 import java.io.File;
 import java.io.IOException;
@@ -17,16 +19,17 @@ import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.SchemaContext;
 import org.opendaylight.controller.yang2sources.plugin.ConfigArg.CodeGeneratorArg;
+import org.opendaylight.controller.yang2sources.plugin.YangToSourcesProcessor.YangProvider;
 import org.opendaylight.controller.yang2sources.spi.CodeGenerator;
 
 import com.google.common.collect.Lists;
@@ -40,27 +43,37 @@ public class GenerateSourcesTest {
     private MavenProject project;
 
     @Before
-    public void setUp() {
+    public void setUp() throws MojoFailureException {
         MockitoAnnotations.initMocks(this);
 
-        yang = new File(getClass().getResource("/mock.yang").getFile())
+        yang = new File(getClass().getResource("/yang/mock.yang").getFile())
                 .getParent();
         outDir = new File("/outputDir");
-        mojo = new YangToSourcesMojo(
-                new CodeGeneratorArg[] { new CodeGeneratorArg(
-                        GeneratorMock.class.getName(), "outputDir") }, yang);
+        YangProvider mock = mock(YangProvider.class);
+        doNothing().when(mock).addYangsToMETA_INF(any(Log.class),
+                any(MavenProject.class), any(File.class));
+
+        YangToSourcesProcessor processor = new YangToSourcesProcessor(
+                mock(Log.class), new File(yang),
+                Lists.newArrayList(new CodeGeneratorArg(GeneratorMock.class
+                        .getName(), "outputDir")), project, false,
+                mock);
+        mojo = new YangToSourcesMojo(processor);
         doReturn(new File("")).when(project).getBasedir();
         mojo.project = project;
     }
 
-    @Ignore
     @Test
     public void test() throws Exception {
         mojo.execute();
         assertThat(GeneratorMock.called, is(1));
         assertThat(GeneratorMock.outputDir, is(outDir));
+        assertThat(GeneratorMock.project, is(project));
         assertNotNull(GeneratorMock.log);
         assertTrue(GeneratorMock.additionalCfg.isEmpty());
+        assertThat(GeneratorMock.resourceBaseDir.toString(),
+                containsString("target" + File.separator
+                        + "generated-resources"));
     }
 
     public static class GeneratorMock implements CodeGenerator {
@@ -69,11 +82,13 @@ public class GenerateSourcesTest {
         private static File outputDir;
         private static Log log;
         private static Map<String, String> additionalCfg;
+        private static File resourceBaseDir;
+        private static MavenProject project;
 
         @Override
         public Collection<File> generateSources(SchemaContext context,
-                File outputBaseDir, Set<Module> currentModules,
-                File projectBaseDir) throws IOException {
+                File outputBaseDir, Set<Module> currentModules)
+                throws IOException {
             called++;
             outputDir = outputBaseDir;
             return Lists.newArrayList();
@@ -81,13 +96,24 @@ public class GenerateSourcesTest {
 
         @Override
         public void setLog(Log log) {
-            this.log = log;
+            GeneratorMock.log = log;
         }
 
         @Override
         public void setAdditionalConfig(
                 Map<String, String> additionalConfiguration) {
-            this.additionalCfg = additionalConfiguration;
+            GeneratorMock.additionalCfg = additionalConfiguration;
+        }
+
+        @Override
+        public void setResourceBaseDir(File resourceBaseDir) {
+            GeneratorMock.resourceBaseDir = resourceBaseDir;
+
+        }
+
+        @Override
+        public void setMavenProject(MavenProject project) {
+            GeneratorMock.project = project;
         }
     }
 
index 96a4d57a00d97f3a8ec9e36b0bccd84e13c551f0..240825409fcc8459209c1d3a407aea4a0acd6e1a 100644 (file)
@@ -7,19 +7,20 @@
  */
 package org.opendaylight.controller.yang2sources.plugin;
 
-import org.junit.Test;
+import static org.junit.Assert.*;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.Collection;
 
-import static org.junit.Assert.assertTrue;
+import org.junit.Test;
 
 public class UtilTest {
 
     @Test
     public void testCache() throws FileNotFoundException {
-        String yang = new File(getClass().getResource("/mock.yang").getFile())
+        String yang = new File(getClass().getResource("/yang/mock.yang")
+                .getFile())
                 .getParent();
         Collection<File> files = Util.listFiles(new File(yang));
         Collection<File> files2 = Util.listFiles(new File(yang));
index 9c4475cd40b966f3ab4ba3596c464d8bddbafac4..ae24c1848e5de587089796141056178da0d8b5af 100644 (file)
             <artifactId>maven-plugin-api</artifactId>
             <version>3.0.5</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.maven</groupId>
+            <artifactId>maven-core</artifactId>
+            <version>3.0.5</version>
+        </dependency>
     </dependencies>
 
     <build>
index df33d4c5919e81070c8947d2d30b01182fd85a3a..09dcd3e8e9ca2cafc18d5745bcafb6016c64eedb 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
 import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.SchemaContext;
 
@@ -39,10 +40,36 @@ public interface CodeGenerator {
      * @throws IOException
      */
     Collection<File> generateSources(SchemaContext context, File outputBaseDir,
-            Set<Module> currentModules, File projectBaseDir)
-            throws IOException;
+            Set<Module> currentModules) throws IOException;
 
+    /**
+     * Utilize maven logging if necessary
+     *
+     * @param log
+     */
     void setLog(Log log);
 
+    /**
+     * Provided map contains all configuration that was set in pom for code
+     * generator in additionalConfiguration tag
+     *
+     * @param additionalConfiguration
+     */
     void setAdditionalConfig(Map<String, String> additionalConfiguration);
+
+    /**
+     * Provided folder is marked as resources and its content will be packaged
+     * in resulting jar. Feel free to add necessary resources
+     *
+     * @param resourceBaseDir
+     */
+    void setResourceBaseDir(File resourceBaseDir);
+
+    /**
+     * Provided maven project object. Any additional information about current
+     * maven project can be accessed from it.
+     *
+     * @param resourceBaseDir
+     */
+    void setMavenProject(MavenProject project);
 }
index 172a2f25b67dcd03ed540bda966593e68bd0d367..3103042f9970c4d2d24ab606f709322f8daa85e4 100644 (file)
@@ -13,27 +13,55 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
 import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.SchemaContext;
 
 public class CodeGeneratorTestImpl implements CodeGenerator {
 
+    private Log log;
+
     @Override
     public Collection<File> generateSources(SchemaContext context,
-            File outputBaseDir, Set<Module> currentModuleBuilders,
-            File projectMainDir) {
-        // no-op
+            File outputBaseDir, Set<Module> currentModuleBuilders) {
+        if (log != null) {
+            log.debug(getClass().getCanonicalName()
+                    + " generateSources:context: " + context);
+            log.debug(getClass().getCanonicalName()
+                    + " generateSources:outputBaseDir: " + outputBaseDir);
+            log.debug(getClass().getCanonicalName()
+                    + " generateSources:currentModuleBuilders: "
+                    + currentModuleBuilders);
+
+        }
         return null;
     }
 
     @Override
     public void setLog(Log log) {
-        // no-op
+        this.log = log;
     }
 
     @Override
     public void setAdditionalConfig(Map<String, String> additionalConfiguration) {
-        // no-op
+        if (log != null)
+            log.debug(getClass().getCanonicalName() + " additionalConfig: "
+                    + additionalConfiguration);
+    }
+
+
+    @Override
+    public void setResourceBaseDir(File resourceBaseDir) {
+        if (log != null)
+            log.debug(getClass().getCanonicalName() + " resourceBaseDir: "
+                    + resourceBaseDir);
+    }
+
+    @Override
+    public void setMavenProject(MavenProject project) {
+        if (log != null)
+            log.debug(getClass().getCanonicalName() + " maven project: "
+                    + project);
     }
 
 }
index 6940e91e382247b384157f715d02fe4f948411fb..67e4c6fb72cef7e1e1dd5d566a72992fb31dea6e 100644 (file)
@@ -71,7 +71,6 @@ public class ModuleBuilder implements Builder {
     private final Map<List<String>, GroupingBuilder> addedGroupings = new HashMap<List<String>, GroupingBuilder>();
     private final List<AugmentationSchemaBuilder> addedAugments = new ArrayList<AugmentationSchemaBuilder>();
     private final Map<List<String>, UsesNodeBuilder> addedUsesNodes = new HashMap<List<String>, UsesNodeBuilder>();
-    //private final Map<List<String>, RefineHolder> addedRefines = new HashMap<List<String>, RefineHolder>();
     private final Map<List<String>, RpcDefinitionBuilder> addedRpcs = new HashMap<List<String>, RpcDefinitionBuilder>();
     private final Set<NotificationBuilder> addedNotifications = new HashSet<NotificationBuilder>();
     private final Set<IdentitySchemaNodeBuilder> addedIdentities = new HashSet<IdentitySchemaNodeBuilder>();
@@ -177,6 +176,14 @@ public class ModuleBuilder implements Builder {
         actualPath.pop();
     }
 
+    public Builder getActualNode() {
+        if (actualPath.isEmpty()) {
+            return null;
+        } else {
+            return actualPath.get(0);
+        }
+    }
+
     public Builder getModuleNode(final List<String> path) {
         return childNodes.get(path);
     }
@@ -756,6 +763,11 @@ public class ModuleBuilder implements Builder {
         return builder;
     }
 
+    @Override
+    public String toString() {
+        return ModuleBuilder.class.getSimpleName() + "[" + name + "]";
+    }
+
     private final class ModuleImpl implements Module {
         private URI namespace;
         private final String name;
@@ -1101,8 +1113,7 @@ public class ModuleBuilder implements Builder {
                 if (parent instanceof AugmentationSchemaBuilder) {
                     nodeBuilder.setAugmenting(true);
                 }
-                ((DataNodeContainerBuilder) parent)
-                        .addChildNode(nodeBuilder);
+                ((DataNodeContainerBuilder) parent).addChildNode(nodeBuilder);
             } else if (parent instanceof ChoiceBuilder) {
                 ((ChoiceBuilder) parent).addChildNode(nodeBuilder);
             } else {
index d60dbbb615c71449bd74adfb3e9f3c391b2eb027..a8628eae72dab5e38af177b8a0942f50e867e8a9 100644 (file)
@@ -32,6 +32,7 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder
     private SchemaPath schemaPath;
 
     private final List<UnknownSchemaNodeBuilder> addedUnknownNodes = new ArrayList<UnknownSchemaNodeBuilder>();
+    private List<UnknownSchemaNode> unknownNodes;
     private List<RangeConstraint> ranges = Collections.emptyList();
     private List<LengthConstraint> lengths = Collections.emptyList();
     private List<PatternConstraint> patterns = Collections.emptyList();
@@ -73,9 +74,11 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder
         typeBuilder.fractionDigits(fractionDigits);
 
         // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
+        if (unknownNodes == null) {
+            unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
         }
         typeBuilder.unknownSchemaNodes(unknownNodes);
         result = typeBuilder.build();
@@ -164,6 +167,10 @@ public final class TypeDefinitionBuilderImpl extends AbstractTypeAwareBuilder
         addedUnknownNodes.add(unknownNode);
     }
 
+    public void setUnknownNodes(List<UnknownSchemaNode> unknownNodes) {
+        this.unknownNodes = unknownNodes;
+    }
+
     @Override
     public List<RangeConstraint> getRanges() {
         return ranges;
index 401189b1d1efbb11a79801c9837fb1053f1f226d..95b52a0a4a130bc0bc404a198c7f29fe8c0b6b0f 100644 (file)
@@ -41,15 +41,11 @@ import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.DecimalTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition;
-import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
-import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
-import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
 import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition;
 import org.opendaylight.controller.yang.model.parser.api.YangModelParser;
 import org.opendaylight.controller.yang.model.util.ExtendedType;
 import org.opendaylight.controller.yang.model.util.IdentityrefType;
 import org.opendaylight.controller.yang.model.util.UnknownType;
-import org.opendaylight.controller.yang.model.util.YangTypesConverter;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationTargetBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.Builder;
@@ -297,222 +293,116 @@ public final class YangParserImpl implements YangModelParser {
         if (!dirtyNodes.isEmpty()) {
             for (Map.Entry<List<String>, TypeAwareBuilder> entry : dirtyNodes
                     .entrySet()) {
-
                 final TypeAwareBuilder nodeToResolve = entry.getValue();
-                // different handling for union types
+
                 if (nodeToResolve instanceof UnionTypeBuilder) {
-                    final UnionTypeBuilder union = (UnionTypeBuilder) nodeToResolve;
-                    final List<TypeDefinition<?>> unionTypes = union.getTypes();
-                    final List<UnknownType> toRemove = new ArrayList<UnknownType>();
-                    for (TypeDefinition<?> td : unionTypes) {
-                        if (td instanceof UnknownType) {
-                            final UnknownType unknownType = (UnknownType) td;
-                            final TypeDefinitionBuilder resolvedType = resolveTypeUnion(
-                                    nodeToResolve, unknownType, modules, module);
-                            union.setTypedef(resolvedType);
-                            toRemove.add(unknownType);
-                        }
-                    }
-                    unionTypes.removeAll(toRemove);
+                    // special handling for union types
+                    resolveTypeUnion((UnionTypeBuilder) nodeToResolve, modules,
+                            module);
                 } else if (nodeToResolve.getTypedef() instanceof IdentityrefTypeBuilder) {
-                    // different handling for identityref types
+                    // special handling for identityref types
                     IdentityrefTypeBuilder idref = (IdentityrefTypeBuilder) nodeToResolve
                             .getTypedef();
                     nodeToResolve.setType(new IdentityrefType(findFullQName(
                             modules, module, idref), idref.getPath()));
                 } else {
-                    final TypeDefinitionBuilder resolvedType = resolveType(
-                            nodeToResolve, modules, module);
-                    nodeToResolve.setTypedef(resolvedType);
+                    resolveType(nodeToResolve, modules, module);
                 }
             }
         }
     }
 
-    private TypeDefinitionBuilder resolveType(
-            final TypeAwareBuilder nodeToResolve,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder builder) {
-        final TypeConstraints constraints = new TypeConstraints();
-
-        final TypeDefinitionBuilder targetTypeBuilder = getTypeDefinitionBuilderFromDirtyNode(
-                nodeToResolve, modules, builder);
-        final TypeConstraints tConstraints = findConstraints(nodeToResolve,
-                constraints, modules, builder);
-        targetTypeBuilder.setRanges(tConstraints.getRange());
-        targetTypeBuilder.setLengths(tConstraints.getLength());
-        targetTypeBuilder.setPatterns(tConstraints.getPatterns());
-        targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits());
-
-        return targetTypeBuilder;
-    }
-
-    private TypeDefinitionBuilder resolveTypeUnion(
-            final TypeAwareBuilder typeToResolve,
-            final UnknownType unknownType,
+    private void resolveType(final TypeAwareBuilder nodeToResolve,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder builder) {
-        final TypeConstraints constraints = new TypeConstraints();
-
-        final TypeDefinitionBuilder targetTypeBuilder = getUnionBuilder(
-                typeToResolve, unknownType, modules, builder);
-        final TypeConstraints tConstraints = findConstraints(typeToResolve,
-                constraints, modules, builder);
-        targetTypeBuilder.setRanges(tConstraints.getRange());
-        targetTypeBuilder.setLengths(tConstraints.getLength());
-        targetTypeBuilder.setPatterns(tConstraints.getPatterns());
-        targetTypeBuilder.setFractionDigits(tConstraints.getFractionDigits());
-
-        return targetTypeBuilder;
-    }
-
-    private TypeDefinitionBuilder getTypeDefinitionBuilderFromDirtyNode(
-            final TypeAwareBuilder nodeToResolve,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module) {
-
-        final UnknownType unknownType = (UnknownType) nodeToResolve.getType();
-        final QName unknownTypeQName = unknownType.getQName();
-
-        // search for module which contains referenced typedef
+        TypeDefinitionBuilder resolvedType = null;
+        final int line = nodeToResolve.getLine();
+        final TypeDefinition<?> typedefType = nodeToResolve.getType();
+        final QName unknownTypeQName = typedefType.getBaseType().getQName();
         final ModuleBuilder dependentModule = findDependentModule(modules,
-                module, unknownTypeQName.getPrefix(), nodeToResolve.getLine());
-
-        final TypeDefinitionBuilder lookedUpBuilder = findTypeDefinitionBuilder(
-                nodeToResolve.getPath(), dependentModule,
-                unknownTypeQName.getLocalName(), module.getName(),
-                nodeToResolve.getLine());
-
-        final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
-                lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder);
-        final TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
-                lookedUpBuilderCopy, modules, dependentModule);
-        return resolvedCopy;
-    }
-
-    private TypeDefinitionBuilder getUnionBuilder(
-            final TypeAwareBuilder nodeToResolve,
-            final UnknownType unknownType,
-            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
-            final ModuleBuilder module) {
-
-        final TypeDefinition<?> baseTypeToResolve = nodeToResolve.getType();
-        if (baseTypeToResolve != null
-                && !(baseTypeToResolve instanceof UnknownType)) {
-            return (TypeDefinitionBuilder) nodeToResolve;
-        }
+                builder, unknownTypeQName.getPrefix(), line);
 
-        final QName unknownTypeQName = unknownType.getQName();
-        // search for module which contains referenced typedef
-        final ModuleBuilder dependentModule = findDependentModule(modules,
-                module, unknownTypeQName.getPrefix(), nodeToResolve.getLine());
-        final TypeDefinitionBuilder lookedUpBuilder = findTypeDefinitionBuilder(
+        final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(
                 nodeToResolve.getPath(), dependentModule,
-                unknownTypeQName.getLocalName(), module.getName(),
-                nodeToResolve.getLine());
-
-        final TypeDefinitionBuilder lookedUpBuilderCopy = copyTypedefBuilder(
-                lookedUpBuilder, nodeToResolve instanceof TypeDefinitionBuilder);
-        final TypeDefinitionBuilder resolvedCopy = resolveCopiedBuilder(
-                lookedUpBuilderCopy, modules, dependentModule);
-        return resolvedCopy;
-    }
+                unknownTypeQName.getLocalName(), builder.getName(), line);
 
-    private TypeDefinitionBuilder copyTypedefBuilder(
-            final TypeDefinitionBuilder old, final boolean seekByTypedefBuilder) {
-        if (old instanceof UnionTypeBuilder) {
-            final UnionTypeBuilder oldUnion = (UnionTypeBuilder) old;
-            final UnionTypeBuilder newUnion = new UnionTypeBuilder(
-                    old.getLine());
-            for (TypeDefinition<?> td : oldUnion.getTypes()) {
-                newUnion.setType(td);
-            }
-            for (TypeDefinitionBuilder tdb : oldUnion.getTypedefs()) {
-                newUnion.setTypedef(copyTypedefBuilder(tdb, true));
-            }
-            newUnion.setPath(old.getPath());
-            return newUnion;
-        }
-
-        final QName oldName = old.getQName();
-        final QName newName = new QName(oldName.getNamespace(),
-                oldName.getRevision(), oldName.getPrefix(),
-                oldName.getLocalName());
-        final TypeDefinitionBuilder tdb = new TypeDefinitionBuilderImpl(
-                newName, old.getLine());
-
-        tdb.setRanges(old.getRanges());
-        tdb.setLengths(old.getLengths());
-        tdb.setPatterns(old.getPatterns());
-        tdb.setFractionDigits(old.getFractionDigits());
-        tdb.setPath(old.getPath());
-
-        final TypeDefinition<?> oldType = old.getType();
-        if (oldType == null) {
-            tdb.setTypedef(old.getTypedef());
+        if (typedefType instanceof ExtendedType) {
+            final ExtendedType extType = (ExtendedType) typedefType;
+            final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(
+                    nodeToResolve, targetTypeBuilder, extType, modules, builder);
+            resolvedType = newType;
         } else {
-            tdb.setType(oldType);
+            resolvedType = targetTypeBuilder;
         }
-
-        if (!seekByTypedefBuilder) {
-            tdb.setDescription(old.getDescription());
-            tdb.setReference(old.getReference());
-            tdb.setStatus(old.getStatus());
-            tdb.setDefaultValue(old.getDefaultValue());
-            tdb.setUnits(old.getUnits());
-        }
-        return tdb;
+        nodeToResolve.setTypedef(resolvedType);
     }
 
-    private TypeDefinitionBuilder resolveCopiedBuilder(
-            final TypeDefinitionBuilder copy,
+    private void resolveTypeUnion(final UnionTypeBuilder union,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder builder) {
 
-        if (copy instanceof UnionTypeBuilder) {
-            final UnionTypeBuilder union = (UnionTypeBuilder) copy;
-            final List<TypeDefinition<?>> unionTypes = union.getTypes();
-            final List<UnknownType> toRemove = new ArrayList<UnknownType>();
-            for (TypeDefinition<?> td : unionTypes) {
-                if (td instanceof UnknownType) {
-                    final UnknownType unknownType = (UnknownType) td;
-                    final TypeDefinitionBuilder resolvedType = resolveTypeUnion(
-                            union, unknownType, modules, builder);
-                    union.setTypedef(resolvedType);
-                    toRemove.add(unknownType);
+        final List<TypeDefinition<?>> unionTypes = union.getTypes();
+        final List<TypeDefinition<?>> toRemove = new ArrayList<TypeDefinition<?>>();
+        for (TypeDefinition<?> unionType : unionTypes) {
+            if (unionType instanceof UnknownType) {
+                final UnknownType ut = (UnknownType) unionType;
+                final ModuleBuilder dependentModule = findDependentModule(
+                        modules, builder, ut.getQName().getPrefix(),
+                        union.getLine());
+                final TypeDefinitionBuilder resolvedType = findTypeDefinitionBuilder(
+                        union.getPath(), dependentModule, ut.getQName()
+                                .getLocalName(), builder.getName(),
+                        union.getLine());
+                union.setTypedef(resolvedType);
+                toRemove.add(ut);
+            } else if (unionType instanceof ExtendedType) {
+                final ExtendedType extType = (ExtendedType) unionType;
+                TypeDefinition<?> extTypeBase = extType.getBaseType();
+                if (extTypeBase instanceof UnknownType) {
+                    final UnknownType ut = (UnknownType) extTypeBase;
+                    final ModuleBuilder dependentModule = findDependentModule(
+                            modules, builder, ut.getQName().getPrefix(),
+                            union.getLine());
+                    final TypeDefinitionBuilder targetTypeBuilder = findTypeDefinitionBuilder(
+                            union.getPath(), dependentModule, ut.getQName()
+                                    .getLocalName(), builder.getName(),
+                            union.getLine());
+
+                    final TypeDefinitionBuilder newType = extendedTypeWithNewBaseType(
+                            targetTypeBuilder, targetTypeBuilder, extType,
+                            modules, builder);
+
+                    union.setTypedef(newType);
+                    toRemove.add(extType);
                 }
             }
-            unionTypes.removeAll(toRemove);
-
-            return union;
         }
+        unionTypes.removeAll(toRemove);
+    }
 
-        final TypeDefinition<?> base = copy.getType();
-        final TypeDefinitionBuilder baseTdb = copy.getTypedef();
-        if (base != null && !(base instanceof UnknownType)) {
-            return copy;
-        } else if (base instanceof UnknownType) {
-            final UnknownType unknownType = (UnknownType) base;
-            final QName unknownTypeQName = unknownType.getQName();
-            final String unknownTypePrefix = unknownTypeQName.getPrefix();
-            final ModuleBuilder dependentModule = findDependentModule(modules,
-                    builder, unknownTypePrefix, copy.getLine());
-            final TypeDefinitionBuilder utBuilder = getTypeDefinitionBuilderFromDirtyNode(
-                    copy, modules, dependentModule);
-            copy.setTypedef(utBuilder);
-            return copy;
-        } else if (base == null && baseTdb != null) {
-            // make a copy of baseTypeDef and call again
-            final TypeDefinitionBuilder baseTdbCopy = copyTypedefBuilder(
-                    baseTdb, true);
-            final TypeDefinitionBuilder baseTdbCopyResolved = resolveCopiedBuilder(
-                    baseTdbCopy, modules, builder);
-            copy.setTypedef(baseTdbCopyResolved);
-            return copy;
-        } else {
-            throw new YangParseException(copy.getLine(),
-                    "Failed to resolve type " + copy.getQName().getLocalName());
-        }
+    private TypeDefinitionBuilder extendedTypeWithNewBaseType(
+            final TypeAwareBuilder nodeToResolve,
+            final TypeDefinitionBuilder newBaseType,
+            final ExtendedType oldExtendedType,
+            final Map<String, TreeMap<Date, ModuleBuilder>> modules,
+            final ModuleBuilder builder) {
+        final TypeConstraints constraints = findConstraints(nodeToResolve,
+                new TypeConstraints(), modules, builder);
+        final TypeDefinitionBuilderImpl newType = new TypeDefinitionBuilderImpl(
+                oldExtendedType.getQName(), nodeToResolve.getLine());
+        newType.setTypedef(newBaseType);
+        newType.setPath(oldExtendedType.getPath());
+        newType.setDescription(oldExtendedType.getDescription());
+        newType.setReference(oldExtendedType.getReference());
+        newType.setStatus(oldExtendedType.getStatus());
+        newType.setLengths(constraints.getLength());
+        newType.setPatterns(constraints.getPatterns());
+        newType.setRanges(constraints.getRange());
+        newType.setFractionDigits(constraints.getFractionDigits());
+        newType.setUnits(oldExtendedType.getUnits());
+        newType.setDefaultValue(oldExtendedType.getDefaultValue());
+        newType.setUnknownNodes(oldExtendedType.getUnknownSchemaNodes());
+        return newType;
     }
 
     private TypeConstraints findConstraints(
@@ -520,77 +410,63 @@ public final class YangParserImpl implements YangModelParser {
             final TypeConstraints constraints,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder builder) {
+
         // union type cannot be restricted
         if (nodeToResolve instanceof UnionTypeBuilder) {
             return constraints;
         }
 
-        // if referenced type is UnknownType again, search recursively with
-        // current constraints
-        final TypeDefinition<?> referencedType = nodeToResolve.getType();
-        List<RangeConstraint> ranges = Collections.emptyList();
-        List<LengthConstraint> lengths = Collections.emptyList();
-        List<PatternConstraint> patterns = Collections.emptyList();
-        Integer fractionDigits = null;
-        if (referencedType == null) {
-            final TypeDefinitionBuilder tdb = nodeToResolve.getTypedef();
-            ranges = tdb.getRanges();
-            constraints.addRanges(ranges);
-            lengths = tdb.getLengths();
-            constraints.addLengths(lengths);
-            patterns = tdb.getPatterns();
-            constraints.addPatterns(patterns);
-            fractionDigits = tdb.getFractionDigits();
-            constraints.setFractionDigits(fractionDigits);
-            return constraints;
-        } else if (referencedType instanceof ExtendedType) {
-            final ExtendedType ext = (ExtendedType) referencedType;
-            ranges = ext.getRanges();
-            constraints.addRanges(ranges);
-            lengths = ext.getLengths();
-            constraints.addLengths(lengths);
-            patterns = ext.getPatterns();
-            constraints.addPatterns(patterns);
-            fractionDigits = ext.getFractionDigits();
-            constraints.setFractionDigits(fractionDigits);
-            if(YangTypesConverter.isBaseYangType(ext.getBaseType().getQName().getLocalName())) {
-                mergeConstraints(ext.getBaseType(), constraints);
-                return constraints;
+        if (nodeToResolve instanceof TypeDefinitionBuilder) {
+            TypeDefinitionBuilder typedefToResolve = (TypeDefinitionBuilder) nodeToResolve;
+            constraints.addFractionDigits(typedefToResolve.getFractionDigits());
+            constraints.addLengths(typedefToResolve.getLengths());
+            constraints.addPatterns(typedefToResolve.getPatterns());
+            constraints.addRanges(typedefToResolve.getRanges());
+        }
+
+        TypeDefinition<?> type = nodeToResolve.getType();
+        if (type == null) {
+            return findConstraints(nodeToResolve.getTypedef(), constraints,
+                    modules, builder);
+        } else {
+            if (type instanceof UnknownType) {
+                ModuleBuilder dependentModule = findDependentModule(modules,
+                        builder, type.getQName().getPrefix(),
+                        nodeToResolve.getLine());
+                TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(
+                        nodeToResolve.getPath(), dependentModule, type
+                                .getQName().getLocalName(), builder.getName(),
+                        nodeToResolve.getLine());
+                return findConstraints(tdb, constraints, modules,
+                        dependentModule);
+            } else if (type instanceof ExtendedType) {
+                ExtendedType extType = (ExtendedType) type;
+                constraints.addFractionDigits(extType.getFractionDigits());
+                constraints.addLengths(extType.getLengths());
+                constraints.addPatterns(extType.getPatterns());
+                constraints.addRanges(extType.getRanges());
+
+                TypeDefinition<?> base = extType.getBaseType();
+                if (base instanceof UnknownType) {
+                    ModuleBuilder dependentModule = findDependentModule(
+                            modules, builder, base.getQName().getPrefix(),
+                            nodeToResolve.getLine());
+                    TypeDefinitionBuilder tdb = findTypeDefinitionBuilder(
+                            nodeToResolve.getPath(), dependentModule, base
+                                    .getQName().getLocalName(),
+                            builder.getName(), nodeToResolve.getLine());
+                    return findConstraints(tdb, constraints, modules,
+                            dependentModule);
+                } else {
+                    // it has to be base yang type
+                    mergeConstraints(type, constraints);
+                    return constraints;
+                }
             } else {
-                return findConstraints(
-                        findTypeDefinitionBuilder(nodeToResolve.getPath(), builder,
-                                ext.getQName().getLocalName(), builder.getName(),
-                                nodeToResolve.getLine()), constraints, modules,
-                        builder);
-            }
-        } else if (referencedType instanceof UnknownType) {
-            final UnknownType unknown = (UnknownType) referencedType;
-            ranges = unknown.getRangeStatements();
-            constraints.addRanges(ranges);
-            lengths = unknown.getLengthStatements();
-            constraints.addLengths(lengths);
-            patterns = unknown.getPatterns();
-            constraints.addPatterns(patterns);
-            fractionDigits = unknown.getFractionDigits();
-            constraints.setFractionDigits(fractionDigits);
-
-            String unknownTypePrefix = unknown.getQName().getPrefix();
-            if (unknownTypePrefix == null || "".equals(unknownTypePrefix)) {
-                unknownTypePrefix = builder.getPrefix();
+                // it is base yang type
+                mergeConstraints(type, constraints);
+                return constraints;
             }
-            final ModuleBuilder dependentModule = findDependentModule(modules,
-                    builder, unknown.getQName().getPrefix(),
-                    nodeToResolve.getLine());
-            final TypeDefinitionBuilder utBuilder = findTypeDefinitionBuilder(
-                    nodeToResolve.getPath(), dependentModule, unknown
-                            .getQName().getLocalName(), builder.getName(),
-                    nodeToResolve.getLine());
-            return findConstraints(utBuilder, constraints, modules,
-                    dependentModule);
-        } else {
-            // HANDLE BASE YANG TYPE
-            mergeConstraints(referencedType, constraints);
-            return constraints;
         }
     }
 
@@ -677,7 +553,7 @@ public final class YangParserImpl implements YangModelParser {
             constraints.addRanges(((DecimalTypeDefinition) referencedType)
                     .getRangeStatements());
             constraints
-                    .setFractionDigits(((DecimalTypeDefinition) referencedType)
+                    .addFractionDigits(((DecimalTypeDefinition) referencedType)
                             .getFractionDigits());
         } else if (referencedType instanceof IntegerTypeDefinition) {
             constraints.addRanges(((IntegerTypeDefinition) referencedType)
index d7394e62291db2ca98e6be896cc551a4b800e08e..40a3289745f10a4010df3cd1797bb081f034c714 100644 (file)
@@ -342,7 +342,6 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                 if ("union".equals(typeName)) {
                     List<String> typePath = new ArrayList<String>(actualPath);
                     typePath.add(typeName);
-
                     SchemaPath p = createActualSchemaPath(typePath, namespace,
                             revision, yangModelPrefix);
                     UnionTypeBuilder unionBuilder = moduleBuilder.addUnionType(
@@ -357,12 +356,15 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
                             line);
                 } else {
                     type = parseTypeBody(typeName, typeBody, actualPath,
-                            namespace, revision, yangModelPrefix);
+                            namespace, revision, yangModelPrefix,
+                            moduleBuilder.getActualNode());
                     moduleBuilder.setType(type, actualPath);
                 }
             }
         } else {
-            type = parseUnknownTypeBody(typeQName, typeBody);
+            type = parseUnknownTypeBody(typeQName, typeBody, actualPath,
+                    namespace, revision, yangModelPrefix,
+                    moduleBuilder.getActualNode(), moduleBuilder);
             // mark parent node of this type statement as dirty
             moduleBuilder.addDirtyNode(actualPath);
             moduleBuilder.setType(type, actualPath);
index e95a162de763811d1d9ead81d32df43aeb599827..7d11db273b8a77d29e4b8eb3d263ebafa8b94f69 100644 (file)
@@ -36,6 +36,7 @@ import org.opendaylight.controller.yang.model.util.BooleanType;
 import org.opendaylight.controller.yang.model.util.Decimal64;
 import org.opendaylight.controller.yang.model.util.EmptyType;
 import org.opendaylight.controller.yang.model.util.EnumerationType;
+import org.opendaylight.controller.yang.model.util.ExtendedType;
 import org.opendaylight.controller.yang.model.util.IdentityrefType;
 import org.opendaylight.controller.yang.model.util.InstanceIdentifier;
 import org.opendaylight.controller.yang.model.util.Int16;
@@ -253,11 +254,32 @@ public final class ParserUtils {
                 newSchemaPath = createNewSchemaPath(parentSchemaPath,
                         nodeQName, unionType.getQName());
                 return new UnionType(newSchemaPath, unionType.getTypes());
+            } else if(nodeType instanceof ExtendedType) {
+                ExtendedType extType = (ExtendedType)nodeType;
+                newSchemaPath = createNewSchemaPath(parentSchemaPath,
+                        nodeQName, extType.getQName());
+                result = createNewExtendedType(newSchemaPath, extType);
             }
         }
         return result;
     }
 
+    private static TypeDefinition<?> createNewExtendedType(
+            SchemaPath newSchemaPath, ExtendedType oldExtendedType) {
+        QName qname = oldExtendedType.getQName();
+        TypeDefinition<?> baseType = oldExtendedType.getBaseType();
+        String desc = oldExtendedType.getDescription();
+        String ref = oldExtendedType.getReference();
+        ExtendedType.Builder builder = new ExtendedType.Builder(qname, baseType, desc, ref, newSchemaPath);
+        builder.status(oldExtendedType.getStatus());
+        builder.lengths(oldExtendedType.getLengths());
+        builder.patterns(oldExtendedType.getPatterns());
+        builder.ranges(oldExtendedType.getRanges());
+        builder.fractionDigits(oldExtendedType.getFractionDigits());
+        builder.unknownSchemaNodes(oldExtendedType.getUnknownSchemaNodes());
+        return builder.build();
+    }
+
     private static TypeDefinition<?> createNewStringType(SchemaPath schemaPath,
             QName nodeQName, StringTypeDefinition nodeType) {
         List<QName> path = schemaPath.getPath();
index 18e4c31ab93856826251748abde40e73e30bf33e..670c1d573c9b46de1df4f3085b39716a63695818 100644 (file)
@@ -23,14 +23,14 @@ public final class TypeConstraints {
     private final List<List<RangeConstraint>> ranges = new ArrayList<List<RangeConstraint>>();
     private final List<List<LengthConstraint>> lengths = new ArrayList<List<LengthConstraint>>();
     private final List<PatternConstraint> patterns = new ArrayList<PatternConstraint>();
-    private Integer fractionDigits;
+    private final List<Integer> fractionDigits = new ArrayList<Integer>();
 
     List<List<RangeConstraint>> getAllRanges() {
         return ranges;
     }
 
     public List<RangeConstraint> getRange() {
-        if(ranges.isEmpty()) {
+        if (ranges.isEmpty()) {
             return Collections.emptyList();
         }
 
@@ -108,7 +108,7 @@ public final class TypeConstraints {
     }
 
     public List<LengthConstraint> getLength() {
-        if(lengths.isEmpty()) {
+        if (lengths.isEmpty()) {
             return Collections.emptyList();
         }
 
@@ -190,13 +190,14 @@ public final class TypeConstraints {
     }
 
     public Integer getFractionDigits() {
-        return fractionDigits;
+        if (fractionDigits.isEmpty()) {
+            return null;
+        }
+        return fractionDigits.get(0);
     }
 
-    public void setFractionDigits(final Integer fractionDigits) {
-        if (this.fractionDigits == null) {
-            this.fractionDigits = fractionDigits;
-        }
+    public void addFractionDigits(final Integer fractionDigits) {
+        this.fractionDigits.add(fractionDigits);
     }
 
 }
index f58ee740cfe4a274840098716be91a430265e70d..1e55b2444919fd67f5f46dd2114e8610e3d9e07f 100644 (file)
@@ -76,13 +76,17 @@ import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.controller.yang.model.api.type.BinaryTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit;
 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
+import org.opendaylight.controller.yang.model.api.type.IntegerTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
 import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
 import org.opendaylight.controller.yang.model.api.type.RangeConstraint;
+import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition;
+import org.opendaylight.controller.yang.model.api.type.UnsignedIntegerTypeDefinition;
 import org.opendaylight.controller.yang.model.util.BaseConstraints;
 import org.opendaylight.controller.yang.model.util.BaseTypes;
 import org.opendaylight.controller.yang.model.util.BinaryType;
@@ -103,8 +107,12 @@ import org.opendaylight.controller.yang.model.util.Uint32;
 import org.opendaylight.controller.yang.model.util.Uint64;
 import org.opendaylight.controller.yang.model.util.Uint8;
 import org.opendaylight.controller.yang.model.util.UnknownType;
+import org.opendaylight.controller.yang.parser.builder.api.Builder;
 import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.impl.ConstraintsBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.ModuleBuilder;
+import org.opendaylight.controller.yang.parser.builder.impl.UnionTypeBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -964,19 +972,48 @@ public final class YangModelBuilderUtil {
      * @return UnknownType object with constraints from parsed type body
      */
     public static TypeDefinition<?> parseUnknownTypeBody(QName typedefQName,
-            Type_body_stmtsContext ctx) {
+            Type_body_stmtsContext ctx, final List<String> actualPath,
+            final URI namespace, final Date revision, final String prefix,
+            Builder parent, ModuleBuilder moduleBuilder) {
+        String typeName = typedefQName.getLocalName();
+
         UnknownType.Builder unknownType = new UnknownType.Builder(typedefQName);
+
         if (ctx != null) {
             List<RangeConstraint> rangeStatements = getRangeConstraints(ctx);
             List<LengthConstraint> lengthStatements = getLengthConstraints(ctx);
             List<PatternConstraint> patternStatements = getPatternConstraint(ctx);
             Integer fractionDigits = getFractionDigits(ctx);
 
-            unknownType.rangeStatements(rangeStatements);
-            unknownType.lengthStatements(lengthStatements);
-            unknownType.patterns(patternStatements);
-            unknownType.fractionDigits(fractionDigits);
+            if (parent instanceof TypeDefinitionBuilder) {
+                TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent;
+                typedef.setRanges(rangeStatements);
+                typedef.setLengths(lengthStatements);
+                typedef.setPatterns(patternStatements);
+                typedef.setFractionDigits(fractionDigits);
+                return unknownType.build();
+            } else {
+                TypeDefinition<?> baseType = unknownType.build();
+                TypeDefinition<?> result = null;
+                QName qname = new QName(namespace, revision, prefix, typeName);
+                ExtendedType.Builder typeBuilder = null;
+
+                SchemaPath schemaPath = createTypeSchemaPath(actualPath,
+                        namespace, revision, prefix, typeName, false, false);
+                typeBuilder = new ExtendedType.Builder(qname, baseType, "", "",
+                        schemaPath);
+
+                typeBuilder.ranges(rangeStatements);
+                typeBuilder.lengths(lengthStatements);
+                typeBuilder.patterns(patternStatements);
+                typeBuilder.fractionDigits(fractionDigits);
+
+                result = typeBuilder.build();
+
+                return result;
+            }
         }
+
         return unknownType.build();
     }
 
@@ -1000,7 +1037,7 @@ public final class YangModelBuilderUtil {
     public static TypeDefinition<?> parseTypeBody(final String typeName,
             final Type_body_stmtsContext typeBody,
             final List<String> actualPath, final URI namespace,
-            final Date revision, final String prefix) {
+            final Date revision, final String prefix, Builder parent) {
         TypeDefinition<?> baseType = null;
 
         List<RangeConstraint> rangeStatements = getRangeConstraints(typeBody);
@@ -1010,40 +1047,56 @@ public final class YangModelBuilderUtil {
         List<EnumTypeDefinition.EnumPair> enumConstants = getEnumConstants(
                 typeBody, actualPath, namespace, revision, prefix);
 
+        TypeConstraints constraints = new TypeConstraints();
+        constraints.addFractionDigits(fractionDigits);
+        constraints.addLengths(lengthStatements);
+        constraints.addPatterns(patternStatements);
+        constraints.addRanges(rangeStatements);
+
         SchemaPath baseTypePathFinal = createTypeSchemaPath(actualPath,
                 namespace, revision, prefix, typeName, true, true);
-        SchemaPath baseTypePath = createTypeSchemaPath(actualPath,
-                namespace, revision, prefix, typeName, true, false);
+        SchemaPath baseTypePath = createTypeSchemaPath(actualPath, namespace,
+                revision, prefix, typeName, true, false);
 
         if ("decimal64".equals(typeName)) {
             if (rangeStatements.isEmpty()) {
                 return new Decimal64(baseTypePathFinal, fractionDigits);
             }
-            baseType = new Decimal64(baseTypePath, fractionDigits);
+            Decimal64 decimalType = new Decimal64(baseTypePath, fractionDigits);
+            constraints.addRanges(decimalType.getRangeStatements());
+            baseType = decimalType;
         } else if (typeName.startsWith("int")) {
+            IntegerTypeDefinition intType = null;
             if ("int8".equals(typeName)) {
-                baseType = new Int8(baseTypePath);
+                intType = new Int8(baseTypePath);
             } else if ("int16".equals(typeName)) {
-                baseType = new Int16(baseTypePath);
+                intType = new Int16(baseTypePath);
             } else if ("int32".equals(typeName)) {
-                baseType = new Int32(baseTypePath);
+                intType = new Int32(baseTypePath);
             } else if ("int64".equals(typeName)) {
-                baseType = new Int64(baseTypePath);
+                intType = new Int64(baseTypePath);
             }
+            constraints.addRanges(intType.getRangeStatements());
+            baseType = intType;
         } else if (typeName.startsWith("uint")) {
+            UnsignedIntegerTypeDefinition uintType = null;
             if ("uint8".equals(typeName)) {
-                baseType = new Uint8(baseTypePath);
+                uintType = new Uint8(baseTypePath);
             } else if ("uint16".equals(typeName)) {
-                baseType = new Uint16(baseTypePath);
+                uintType = new Uint16(baseTypePath);
             } else if ("uint32".equals(typeName)) {
-                baseType = new Uint32(baseTypePath);
+                uintType = new Uint32(baseTypePath);
             } else if ("uint64".equals(typeName)) {
-                baseType = new Uint64(baseTypePath);
+                uintType = new Uint64(baseTypePath);
             }
+            constraints.addRanges(uintType.getRangeStatements());
+            baseType = uintType;
         } else if ("enumeration".equals(typeName)) {
             return new EnumerationType(baseTypePathFinal, enumConstants);
         } else if ("string".equals(typeName)) {
-            baseType = new StringType(baseTypePath);
+            StringTypeDefinition stringType = new StringType(baseTypePath);
+            constraints.addLengths(stringType.getLengthStatements());
+            baseType = stringType;
         } else if ("bits".equals(typeName)) {
             return new BitsType(baseTypePathFinal, getBits(typeBody,
                     actualPath, namespace, revision, prefix));
@@ -1054,13 +1107,25 @@ public final class YangModelBuilderUtil {
                     absolute);
             return new Leafref(baseTypePathFinal, xpath);
         } else if ("binary".equals(typeName)) {
-            baseType = new BinaryType(baseTypePath);
+            BinaryTypeDefinition binaryType = new BinaryType(baseTypePath);
+            constraints.addLengths(binaryType.getLengthConstraints());
+            baseType = binaryType;
         } else if ("instance-identifier".equals(typeName)) {
             boolean requireInstance = isRequireInstance(typeBody);
             baseType = new InstanceIdentifier(baseTypePath, null,
                     requireInstance);
         }
 
+        if (parent instanceof TypeDefinitionBuilder
+                && !(parent instanceof UnionTypeBuilder)) {
+            TypeDefinitionBuilder typedef = (TypeDefinitionBuilder) parent;
+            typedef.setRanges(constraints.getRange());
+            typedef.setLengths(constraints.getLength());
+            typedef.setPatterns(constraints.getPatterns());
+            typedef.setFractionDigits(constraints.getFractionDigits());
+            return baseType;
+        }
+
         TypeDefinition<?> result = null;
         QName qname = new QName(namespace, revision, prefix, typeName);
         ExtendedType.Builder typeBuilder = null;
@@ -1070,10 +1135,10 @@ public final class YangModelBuilderUtil {
         typeBuilder = new ExtendedType.Builder(qname, baseType, "", "",
                 schemaPath);
 
-        typeBuilder.ranges(rangeStatements);
-        typeBuilder.lengths(lengthStatements);
-        typeBuilder.patterns(patternStatements);
-        typeBuilder.fractionDigits(fractionDigits);
+        typeBuilder.ranges(constraints.getRange());
+        typeBuilder.lengths(constraints.getLength());
+        typeBuilder.patterns(constraints.getPatterns());
+        typeBuilder.fractionDigits(constraints.getFractionDigits());
 
         result = typeBuilder.build();
         return result;
index d14c54219e0fd5e1c1d9f3cdae3b0512f8dd654c..26c2c61b98a783aae48517b6cb5c259db85c8bb0 100644 (file)
@@ -49,13 +49,9 @@ final class TestUtils {
         return parser.parseYangModels(testFiles);
     }
 
-    public static Set<Module> loadModules(String... pathToYangFile) throws IOException {
-        YangModelParser parser = new YangParserImpl();
-        List<InputStream> input = new ArrayList<InputStream>();
-        for(String path : pathToYangFile) {
-            input.add(TestUtils.class.getResourceAsStream(path));
-        }
-        Set<Module> modules = new HashSet<Module>(
+    public static Set<Module> loadModules(List<InputStream> input) throws IOException {
+        final YangModelParser parser = new YangParserImpl();
+        final Set<Module> modules = new HashSet<Module>(
                 parser.parseYangModelsFromStreams(input));
         for(InputStream stream : input) {
             stream.close();
@@ -63,11 +59,11 @@ final class TestUtils {
         return modules;
     }
 
-    public static Module loadModule(String pathToYangFile) throws IOException {
-        YangModelParser parser = new YangParserImpl();
-        InputStream stream = TestUtils.class.getResourceAsStream(pathToYangFile);
-        List<InputStream> input = Collections.singletonList(stream);
-        Set<Module> modules = new HashSet<Module>(
+    public static Module loadModule(final InputStream stream) throws
+            IOException {
+        final YangModelParser parser = new YangParserImpl();
+        final List<InputStream> input = Collections.singletonList(stream);
+        final Set<Module> modules = new HashSet<Module>(
                 parser.parseYangModelsFromStreams(input));
         stream.close();
         return modules.iterator().next();
index 461cc4b5c28522d675851bb417563f2baaa91830..2c910ce3f69affe70d54adce8222a9f82ee4aeac 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit;
 import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
 import org.opendaylight.controller.yang.model.api.type.LengthConstraint;
 import org.opendaylight.controller.yang.model.api.type.PatternConstraint;
+import org.opendaylight.controller.yang.model.api.type.StringTypeDefinition;
 import org.opendaylight.controller.yang.model.util.BitsType;
 import org.opendaylight.controller.yang.model.util.EnumerationType;
 import org.opendaylight.controller.yang.model.util.ExtendedType;
@@ -38,7 +39,8 @@ public class TypesResolutionTest {
 
     @Before
     public void init() throws FileNotFoundException {
-        testedModules = TestUtils.loadModules("src/test/resources/types");
+        testedModules = TestUtils.loadModules(getClass().getResource
+                ("/types").getPath());
     }
 
     @Test
@@ -122,16 +124,19 @@ public class TypesResolutionTest {
         List<TypeDefinition<?>> unionTypes = baseType.getTypes();
 
         ExtendedType ipv4 = (ExtendedType) unionTypes.get(0);
-        ExtendedType ipv4Base = (ExtendedType) ipv4.getBaseType();
+        assertTrue(ipv4.getBaseType() instanceof StringTypeDefinition);
         String expectedPattern = "(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}"
                 + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
                 + "(%[\\p{N}\\p{L}]+)?";
-        assertEquals(expectedPattern, ipv4Base.getPatterns().get(0)
+        assertEquals(expectedPattern, ipv4.getPatterns().get(0)
                 .getRegularExpression());
 
+        TypeDefinition<?> ipv4Address = TestUtils.findTypedef(typedefs, "ipv4-address");
+        assertEquals(ipv4Address, ipv4);
+
         ExtendedType ipv6 = (ExtendedType) unionTypes.get(1);
-        ExtendedType ipv6Base = (ExtendedType) ipv6.getBaseType();
-        List<PatternConstraint> ipv6Patterns = ipv6Base.getPatterns();
+        assertTrue(ipv6.getBaseType() instanceof StringTypeDefinition);
+        List<PatternConstraint> ipv6Patterns = ipv6.getPatterns();
         expectedPattern = "((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}"
                 + "((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|"
                 + "(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}"
@@ -140,6 +145,9 @@ public class TypesResolutionTest {
         assertEquals(expectedPattern, ipv6Patterns.get(0)
                 .getRegularExpression());
 
+        TypeDefinition<?> ipv6Address = TestUtils.findTypedef(typedefs, "ipv6-address");
+        assertEquals(ipv6Address, ipv6);
+
         expectedPattern = "(([^:]+:){6}(([^:]+:[^:]+)|(.*\\..*)))|"
                 + "((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)" + "(%.+)?";
         assertEquals(expectedPattern, ipv6Patterns.get(1)
@@ -150,18 +158,18 @@ public class TypesResolutionTest {
     public void testDomainName() {
         Module tested = TestUtils.findModule(testedModules, "ietf-inet-types");
         Set<TypeDefinition<?>> typedefs = tested.getTypeDefinitions();
-        TypeDefinition<?> type = TestUtils.findTypedef(typedefs, "domain-name");
-        ExtendedType baseType = (ExtendedType) type.getBaseType();
-        List<PatternConstraint> patterns = baseType.getPatterns();
+        ExtendedType type = (ExtendedType)TestUtils.findTypedef(typedefs, "domain-name");
+        assertTrue(type.getBaseType() instanceof StringTypeDefinition);
+        List<PatternConstraint> patterns = type.getPatterns();
         assertEquals(1, patterns.size());
         String expectedPattern = "((([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.)*"
                 + "([a-zA-Z0-9_]([a-zA-Z0-9\\-_]){0,61})?[a-zA-Z0-9]\\.?)"
                 + "|\\.";
         assertEquals(expectedPattern, patterns.get(0).getRegularExpression());
 
-        List<LengthConstraint> lengths = baseType.getLengths();
+        List<LengthConstraint> lengths = type.getLengths();
         assertEquals(1, lengths.size());
-        LengthConstraint length = baseType.getLengths().get(0);
+        LengthConstraint length = type.getLengths().get(0);
         assertEquals(1L, length.getMin());
         assertEquals(253L, length.getMax());
     }
@@ -173,7 +181,8 @@ public class TypesResolutionTest {
         LeafSchemaNode leaf = (LeafSchemaNode) tested
                 .getDataChildByName("inst-id-leaf1");
         ExtendedType leafType = (ExtendedType) leaf.getType();
-        InstanceIdentifier leafTypeBase = (InstanceIdentifier)leafType.getBaseType();
+        InstanceIdentifier leafTypeBase = (InstanceIdentifier) leafType
+                .getBaseType();
         assertFalse(leafTypeBase.requireInstance());
     }
 
@@ -300,6 +309,11 @@ public class TypesResolutionTest {
         ExtendedType testedType = (ExtendedType) TestUtils.findTypedef(
                 typedefs, "object-identifier-128");
 
+        List<PatternConstraint> patterns = testedType.getPatterns();
+        assertEquals(1, patterns.size());
+        PatternConstraint pattern = patterns.get(0);
+        assertEquals("\\d*(\\.\\d*){1,127}", pattern.getRegularExpression());
+
         QName testedTypeQName = testedType.getQName();
         assertEquals(URI.create("urn:ietf:params:xml:ns:yang:ietf-yang-types"),
                 testedTypeQName.getNamespace());
@@ -309,15 +323,13 @@ public class TypesResolutionTest {
         assertEquals("object-identifier-128", testedTypeQName.getLocalName());
 
         ExtendedType testedTypeBase = (ExtendedType) testedType.getBaseType();
+        patterns = testedTypeBase.getPatterns();
+        assertEquals(1, patterns.size());
 
-        List<PatternConstraint> patterns = testedTypeBase.getPatterns();
-        assertEquals(2, patterns.size());
-        PatternConstraint pattern1 = patterns.get(0);
-        assertEquals("\\d*(\\.\\d*){1,127}", pattern1.getRegularExpression());
-        PatternConstraint pattern2 = patterns.get(1);
+        pattern = patterns.get(0);
         assertEquals(
                 "(([0-1](\\.[1-3]?[0-9]))|(2\\.(0|([1-9]\\d*))))(\\.(0|([1-9]\\d*)))*",
-                pattern2.getRegularExpression());
+                pattern.getRegularExpression());
 
         QName testedTypeBaseQName = testedTypeBase.getQName();
         assertEquals(URI.create("urn:ietf:params:xml:ns:yang:ietf-yang-types"),
index be44c6ff98f991df55acfaa1188eb5f10559fbb6..35bfb1bebf449290cd97e58eb1af567bc637b35f 100644 (file)
@@ -9,7 +9,11 @@ package org.opendaylight.controller.yang.parser.impl;
 
 import static org.junit.Assert.*;
 
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.junit.Test;
 import org.opendaylight.controller.yang.parser.util.YangParseException;
@@ -20,8 +24,11 @@ public class YangParserNegativeTest {
     @Test
     public void testInvalidImport() throws IOException {
         try {
-            TestUtils.loadModule("/negative-scenario/testfile1.yang");
-            fail("ValidationException should by thrown");
+            try (InputStream stream = new FileInputStream(getClass().getResource
+                    ("/negative-scenario/testfile1.yang").getPath())) {
+                TestUtils.loadModule(stream);
+                fail("ValidationException should by thrown");
+            }
         } catch(YangValidationException e) {
             assertTrue(e.getMessage().contains("Not existing module imported"));
         }
@@ -30,8 +37,11 @@ public class YangParserNegativeTest {
     @Test
     public void testTypeNotFound() throws IOException {
         try {
-            TestUtils.loadModule("/negative-scenario/testfile2.yang");
-            fail("YangParseException should by thrown");
+            try (InputStream stream = new FileInputStream(getClass().getResource
+                    ("/negative-scenario/testfile2.yang").getPath())) {
+                TestUtils.loadModule(stream);
+                fail("YangParseException should by thrown");
+            }
         } catch(YangParseException e) {
             assertTrue(e.getMessage().contains("Error in module 'test2' on line 24: Referenced type 'int-ext' not found."));
         }
@@ -40,8 +50,19 @@ public class YangParserNegativeTest {
     @Test
     public void testInvalidAugmentTarget() throws IOException {
         try {
-            TestUtils.loadModules("/negative-scenario/testfile0.yang", "/negative-scenario/testfile3.yang");
-            fail("YangParseException should by thrown");
+            final List<InputStream> streams = new ArrayList<>(2);
+            try (InputStream testFile0 = new FileInputStream(getClass().getResource
+                    ("/negative-scenario/testfile0.yang").getPath())) {
+                streams.add(testFile0);
+                try (InputStream testFile3 = new FileInputStream(getClass().getResource
+                        ("/negative-scenario/testfile3.yang").getPath())) {
+                    streams.add(testFile3);
+                    assertEquals("Expected loaded files count is 2", 2,
+                            streams.size());
+                    TestUtils.loadModules(streams);
+                    fail("YangParseException should by thrown");
+                }
+            }
         } catch(YangParseException e) {
             assertTrue(e.getMessage().contains("Failed to resolve augments in module 'test3'."));
         }
@@ -50,8 +71,11 @@ public class YangParserNegativeTest {
     @Test
     public void testInvalidRefine() throws IOException {
         try {
-            TestUtils.loadModule("/negative-scenario/testfile4.yang");
-            fail("YangParseException should by thrown");
+            try (InputStream stream = new FileInputStream(getClass().getResource
+                    ("/negative-scenario/testfile4.yang").getPath())) {
+                TestUtils.loadModule(stream);
+                fail("YangParseException should by thrown");
+            }
         } catch(YangParseException e) {
             assertTrue(e.getMessage().contains("Can not refine 'presence' for 'node'."));
         }
index 23bb4a41d2f25fc16c501f06ed9d65b316206d53..733b524cd3656ce5b3830a346eae862ee960db30 100644 (file)
@@ -16,7 +16,6 @@ import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -64,13 +63,14 @@ import org.opendaylight.controller.yang.model.util.Uint32;
 import org.opendaylight.controller.yang.model.util.UnionType;
 
 public class YangParserTest {
-    private final DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+    private final DateFormat simpleDateFormat = new SimpleDateFormat(
+            "yyyy-MM-dd");
 
     private Set<Module> modules;
 
     @Before
     public void init() throws FileNotFoundException {
-        modules = TestUtils.loadModules("src/test/resources/model");
+        modules = TestUtils.loadModules(getClass().getResource("/model").getPath());
         assertEquals(3, modules.size());
     }
 
@@ -209,7 +209,7 @@ public class YangParserTest {
         // leaf if-name
         LeafSchemaNode ifName = (LeafSchemaNode) test
                 .getDataChildByName("if-name");
-        Leafref ifNameType = (Leafref)ifName.getType();
+        Leafref ifNameType = (Leafref) ifName.getType();
         QName qname = ifNameType.getQName();
 
         URI baseYangTypeNS = URI.create("urn:ietf:params:xml:ns:yang:1");
@@ -219,9 +219,8 @@ public class YangParserTest {
         assertEquals("leafref", qname.getLocalName());
 
         // leaf name
-        LeafSchemaNode name = (LeafSchemaNode) test
-                .getDataChildByName("name");
-        StringType nameType = (StringType)name.getType();
+        LeafSchemaNode name = (LeafSchemaNode) test.getDataChildByName("name");
+        StringType nameType = (StringType) name.getType();
         QName nameQName = nameType.getQName();
 
         assertEquals(baseYangTypeNS, nameQName.getNamespace());
@@ -232,7 +231,7 @@ public class YangParserTest {
         // leaf count
         LeafSchemaNode count = (LeafSchemaNode) test
                 .getDataChildByName("count");
-        ExtendedType countType = (ExtendedType)count.getType();
+        ExtendedType countType = (ExtendedType) count.getType();
         QName countTypeQName = countType.getQName();
 
         URI expectedNS = URI.create("urn:simple.types.data.demo");
@@ -242,7 +241,7 @@ public class YangParserTest {
         assertEquals("t2", countTypeQName.getPrefix());
         assertEquals("int8", countTypeQName.getLocalName());
 
-        Int8 countTypeBase = (Int8)countType.getBaseType();
+        Int8 countTypeBase = (Int8) countType.getBaseType();
         QName countTypeBaseQName = countTypeBase.getQName();
 
         assertEquals(baseYangTypeNS, countTypeBaseQName.getNamespace());
@@ -341,17 +340,29 @@ public class YangParserTest {
     }
 
     @Test
-    public void testTypedefRangesResolving() {
+    public void testTypedefRangesResolving() throws ParseException {
         Module testModule = TestUtils.findModule(modules, "types1");
 
         LeafSchemaNode testleaf = (LeafSchemaNode) testModule
                 .getDataChildByName("testleaf");
         ExtendedType leafType = (ExtendedType) testleaf.getType();
-        assertEquals("my-type1", leafType.getQName().getLocalName());
-        assertEquals("t2", leafType.getQName().getPrefix());
+        QName leafTypeQName = leafType.getQName();
+        assertEquals("my-type1", leafTypeQName.getLocalName());
+        assertEquals("t1", leafTypeQName.getPrefix());
+        assertEquals(URI.create("urn:simple.container.demo"),
+                leafTypeQName.getNamespace());
+        Date expectedDate = simpleDateFormat.parse("2013-02-27");
+        assertEquals(expectedDate, leafTypeQName.getRevision());
+        assertEquals(1, leafType.getRanges().size());
+
         ExtendedType baseType = (ExtendedType) leafType.getBaseType();
-        assertEquals("my-base-int32-type", baseType.getQName().getLocalName());
-        assertEquals("t2", baseType.getQName().getPrefix());
+        QName baseTypeQName = baseType.getQName();
+        assertEquals("my-type1", baseTypeQName.getLocalName());
+        assertEquals("t2", baseTypeQName.getPrefix());
+        assertEquals(URI.create("urn:simple.types.data.demo"),
+                baseTypeQName.getNamespace());
+        assertEquals(expectedDate, baseTypeQName.getRevision());
+        assertEquals(2, baseType.getRanges().size());
 
         List<RangeConstraint> ranges = leafType.getRanges();
         assertEquals(1, ranges.size());
@@ -371,28 +382,21 @@ public class YangParserTest {
         assertEquals("my-string-type-ext", testleafTypeQName.getLocalName());
         assertEquals("t2", testleafTypeQName.getPrefix());
 
-        Set<String> expectedRegex = new HashSet<String>();
-        expectedRegex.add("[a-k]*");
-        expectedRegex.add("[b-u]*");
-        expectedRegex.add("[e-z]*");
-
-        Set<String> actualRegex = new HashSet<String>();
         List<PatternConstraint> patterns = testleafType.getPatterns();
-        assertEquals(3, patterns.size());
-        for (PatternConstraint pc : patterns) {
-            actualRegex.add(pc.getRegularExpression());
-        }
-        assertEquals(expectedRegex, actualRegex);
+        assertEquals(1, patterns.size());
+        PatternConstraint pattern = patterns.iterator().next();
+        assertEquals("[e-z]*", pattern.getRegularExpression());
 
-        TypeDefinition<?> baseType = testleafType.getBaseType();
+        ExtendedType baseType = (ExtendedType) testleafType.getBaseType();
         assertEquals("my-string-type2", baseType.getQName().getLocalName());
 
-        List<LengthConstraint> lengths = testleafType.getLengths();
-        assertEquals(1, lengths.size());
+        patterns = baseType.getPatterns();
+        assertEquals(1, patterns.size());
+        pattern = patterns.iterator().next();
+        assertEquals("[b-u]*", pattern.getRegularExpression());
 
-        LengthConstraint length = lengths.get(0);
-        assertEquals(5L, length.getMin());
-        assertEquals(10L, length.getMax());
+        List<LengthConstraint> lengths = testleafType.getLengths();
+        assertTrue(lengths.isEmpty());
     }
 
     @Test
@@ -424,14 +428,14 @@ public class YangParserTest {
         ExtendedType baseType = (ExtendedType) testleafType.getBaseType();
         assertEquals("my-base-int32-type", baseType.getQName().getLocalName());
 
-        ExtendedType int32Type = (ExtendedType) baseType.getBaseType();
-        Int32 int32TypeBase = (Int32)int32Type.getBaseType();
-        QName qname = int32TypeBase.getQName();
-        assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), qname.getNamespace());
+        Int32 int32Type = (Int32) baseType.getBaseType();
+        QName qname = int32Type.getQName();
+        assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"),
+                qname.getNamespace());
         assertNull(qname.getRevision());
         assertEquals("", qname.getPrefix());
         assertEquals("int32", qname.getLocalName());
-        List<RangeConstraint> ranges = int32Type.getRanges();
+        List<RangeConstraint> ranges = baseType.getRanges();
         assertEquals(1, ranges.size());
         RangeConstraint range = ranges.get(0);
         assertEquals(2L, range.getMin());
@@ -447,8 +451,12 @@ public class YangParserTest {
         ExtendedType type = (ExtendedType) testleaf.getType();
         assertEquals(4, (int) type.getFractionDigits());
 
-        Decimal64 baseType = (Decimal64) type.getBaseType();
-        assertEquals(6, (int) baseType.getFractionDigits());
+        ExtendedType typeBase = (ExtendedType) type.getBaseType();
+        assertEquals("my-decimal-type", typeBase.getQName().getLocalName());
+        assertNull(typeBase.getFractionDigits());
+
+        Decimal64 decimal = (Decimal64) typeBase.getBaseType();
+        assertEquals(6, (int) decimal.getFractionDigits());
     }
 
     @Test
@@ -872,7 +880,8 @@ public class YangParserTest {
         Set<TypeDefinition<?>> types = test.getTypeDefinitions();
 
         // my-base-int32-type
-        ExtendedType int32Typedef = (ExtendedType)TestUtils.findTypedef(types, "my-base-int32-type");
+        ExtendedType int32Typedef = (ExtendedType) TestUtils.findTypedef(types,
+                "my-base-int32-type");
         QName int32TypedefQName = int32Typedef.getQName();
 
         URI expectedNS = URI.create("urn:simple.types.data.demo");
@@ -888,24 +897,10 @@ public class YangParserTest {
         assertEquals(int32TypedefQName, typePath.get(0));
 
         // my-base-int32-type/int32
-        ExtendedType int32Ext = (ExtendedType)int32Typedef.getBaseType();
-        QName int32ExtQName = int32Ext.getQName();
-
-        assertEquals(expectedNS, int32ExtQName.getNamespace());
-        assertEquals(expectedDate, int32ExtQName.getRevision());
-        assertEquals("t2", int32ExtQName.getPrefix());
-        assertEquals("int32", int32ExtQName.getLocalName());
-
-        SchemaPath int32ExtSchemaPath = int32Ext.getPath();
-        List<QName> int32ExtPath = int32ExtSchemaPath.getPath();
-        assertEquals(2, int32ExtPath.size());
-        assertEquals(int32TypedefQName, int32ExtPath.get(0));
-        assertEquals(int32ExtQName, int32ExtPath.get(1));
-
-        // my-base-int32-type/int32/int32
-        Int32 int32 = (Int32)int32Ext.getBaseType();
+        Int32 int32 = (Int32) int32Typedef.getBaseType();
         QName int32QName = int32.getQName();
-        assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), int32QName.getNamespace());
+        assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"),
+                int32QName.getNamespace());
         assertNull(int32QName.getRevision());
         assertEquals("", int32QName.getPrefix());
         assertEquals("int32", int32QName.getLocalName());
@@ -914,7 +909,6 @@ public class YangParserTest {
         List<QName> int32Path = int32SchemaPath.getPath();
         assertEquals(3, int32Path.size());
         assertEquals(int32TypedefQName, int32Path.get(0));
-        assertEquals(int32ExtQName, int32Path.get(1));
         assertEquals(int32QName, int32Path.get(2));
     }
 
@@ -924,7 +918,8 @@ public class YangParserTest {
         Set<TypeDefinition<?>> types = test.getTypeDefinitions();
 
         // my-base-int32-type
-        ExtendedType myDecType = (ExtendedType)TestUtils.findTypedef(types, "my-decimal-type");
+        ExtendedType myDecType = (ExtendedType) TestUtils.findTypedef(types,
+                "my-decimal-type");
         QName myDecTypeQName = myDecType.getQName();
 
         URI expectedNS = URI.create("urn:simple.types.data.demo");
@@ -940,10 +935,11 @@ public class YangParserTest {
         assertEquals(myDecTypeQName, typePath.get(0));
 
         // my-base-int32-type/int32
-        Decimal64 dec64 = (Decimal64)myDecType.getBaseType();
+        Decimal64 dec64 = (Decimal64) myDecType.getBaseType();
         QName dec64QName = dec64.getQName();
 
-        assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"), dec64QName.getNamespace());
+        assertEquals(URI.create("urn:ietf:params:xml:ns:yang:1"),
+                dec64QName.getNamespace());
         assertNull(dec64QName.getRevision());
         assertEquals("", dec64QName.getPrefix());
         assertEquals("decimal64", dec64QName.getLocalName());