Enforce non-null QNameModule namespace 88/61988/18
authorRobert Varga <robert.varga@pantheon.tech>
Fri, 18 Aug 2017 14:01:01 +0000 (16:01 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Tue, 24 Oct 2017 20:20:02 +0000 (22:20 +0200)
QNameModule without a namespace does not really make sense,
enforce valid namespace.

Change-Id: I62e8daf71deba15e4d3bdb975046223ade57cdbe
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QName.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QNameModule.java
yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/QNameTest.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/ModuleIdentifierImpl.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtil.java
yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/BitsTypeTest.java
yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/LeafrefTest.java
yang/yang-model-util/src/test/java/org/opendaylight/yangtools/yang/model/util/SchemaContextUtilTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/util/SchemaContextUtilTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug6961Test.java

index 39aaa9487b467d8c284afd9ebcbb979b2fbe39a7..cbb90ad85aaaba194fdd02e25155ee7ddf2f38cf 100644 (file)
@@ -66,11 +66,6 @@ public final class QName implements Immutable, Serializable, Comparable<QName> {
     private static final String QNAME_STRING_NO_REVISION = "^\\((.+)\\)(.+)$";
     private static final Pattern QNAME_PATTERN_NO_REVISION = Pattern.compile(QNAME_STRING_NO_REVISION);
 
-    @RegEx
-    private static final String QNAME_STRING_NO_NAMESPACE_NO_REVISION = "^(.+)$";
-    private static final Pattern QNAME_PATTERN_NO_NAMESPACE_NO_REVISION =
-        Pattern.compile(QNAME_STRING_NO_NAMESPACE_NO_REVISION);
-
     private static final char[] ILLEGAL_CHARACTERS = new char[] { '?', '(', ')', '&', ':' };
 
     // Non-null
@@ -123,12 +118,7 @@ public final class QName implements Immutable, Serializable, Comparable<QName> {
             final String localName = matcher.group(2);
             return new QName(namespace, localName);
         }
-        matcher = QNAME_PATTERN_NO_NAMESPACE_NO_REVISION.matcher(input);
-        if (matcher.matches()) {
-            final String localName = matcher.group(1);
-            return new QName((URI) null, localName);
-        }
-        throw new IllegalArgumentException("Invalid input:" + input);
+        throw new IllegalArgumentException("Invalid input: " + input);
     }
 
     public static QName create(final QName base, final String localName) {
index acc12bbe4e08e88b44becbe2b551fb8bbce0cd01..6fa4436c09069ddf02fe2dae1fdda1d91510f2e7 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.common;
 
+import static java.util.Objects.requireNonNull;
+
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.Interner;
 import com.google.common.collect.Interners;
@@ -22,10 +24,8 @@ import org.slf4j.LoggerFactory;
 public final class QNameModule implements Immutable, Serializable {
     private static final Interner<QNameModule> INTERNER = Interners.newWeakInterner();
     private static final Logger LOG = LoggerFactory.getLogger(QNameModule.class);
-    private static final QNameModule NULL_INSTANCE = new QNameModule(null, null);
     private static final long serialVersionUID = 2L;
 
-    //Nullable
     private final URI namespace;
 
     //Nullable
@@ -37,8 +37,7 @@ public final class QNameModule implements Immutable, Serializable {
     private transient int hash;
 
     private QNameModule(final URI namespace, final Date revision) {
-        // FIXME: 2.0.0: Preconditions.checkNotNull(namespace)
-        this.namespace = namespace;
+        this.namespace = requireNonNull(namespace);
         this.revision = revision;
     }
 
@@ -59,10 +58,6 @@ public final class QNameModule implements Immutable, Serializable {
      * @return A new, potentially shared, QNameModule instance
      */
     public static QNameModule create(final URI namespace, final Date revision) {
-        if (namespace == null && revision == null) {
-            return NULL_INSTANCE;
-        }
-
         return new QNameModule(namespace, revision);
     }
 
index 56bc0bc629541807022210859796243b8c22b202..f91af065d8775a8266ac2c1684d565350b92b5e7 100644 (file)
@@ -17,32 +17,25 @@ import java.util.Date;
 import org.junit.Test;
 
 public class QNameTest {
-    private final String namespace = "urn:foo";
-    private final String revision = "2013-12-24";
-    private final String localName = "bar";
-    private final URI ns = URI.create(namespace);
+    private static final String NAMESPACE = "urn:foo";
+    private static final String REVISION = "2013-12-24";
+    private static final String LOCALNAME = "bar";
+    private static final URI NS = URI.create(NAMESPACE);
 
     @Test
     public void testStringSerialization() throws Exception {
         {
-            QName qname = QName.create(namespace, revision, localName);
-            assertEquals(QName.QNAME_LEFT_PARENTHESIS + namespace + QName.QNAME_REVISION_DELIMITER
-                    + revision + QName.QNAME_RIGHT_PARENTHESIS + localName, qname.toString());
+            QName qname = QName.create(NAMESPACE, REVISION, LOCALNAME);
+            assertEquals(QName.QNAME_LEFT_PARENTHESIS + NAMESPACE + QName.QNAME_REVISION_DELIMITER
+                    + REVISION + QName.QNAME_RIGHT_PARENTHESIS + LOCALNAME, qname.toString());
             QName copied = QName.create(qname.toString());
             assertEquals(qname, copied);
         }
         // no revision
         {
-            QName qname = new QName(ns, localName);
-            assertEquals(QName.QNAME_LEFT_PARENTHESIS + namespace + QName.QNAME_RIGHT_PARENTHESIS
-                    + localName, qname.toString());
-            QName copied = QName.create(qname.toString());
-            assertEquals(qname, copied);
-        }
-        // no namespace nor revision
-        {
-            QName qname = new QName(null, localName);
-            assertEquals(localName, qname.toString());
+            QName qname = new QName(NS, LOCALNAME);
+            assertEquals(QName.QNAME_LEFT_PARENTHESIS + NAMESPACE + QName.QNAME_RIGHT_PARENTHESIS
+                    + LOCALNAME, qname.toString());
             QName copied = QName.create(qname.toString());
             assertEquals(qname, copied);
         }
@@ -63,34 +56,12 @@ public class QNameTest {
         final String A = "a";
         final String B = "b";
 
-        QName qa = QName.create(A);
-        QName qb = QName.create(A);
-        assertTrue(qa.compareTo(qb) == 0);
-        assertTrue(qb.compareTo(qa) == 0);
-
-        // compare with localName
-        qa = QName.create(A);
-        qb = QName.create(B);
-        assertTrue(qa.compareTo(qb) < 0);
-        assertTrue(qb.compareTo(qa) > 0);
-
         // compare with namespace
-        qa = QName.create(A, revision, A);
-        qb = QName.create(B, revision, A);
-        assertTrue(qa.compareTo(qb) < 0);
-        assertTrue(qb.compareTo(qa) > 0);
-
-        // compare with 1 null namespace
-        qa = QName.create(null, QName.parseRevision(revision), A);
-        qb = QName.create(URI.create(A), QName.parseRevision(revision), A);
+        QName qa = QName.create(A, REVISION, A);
+        QName qb = QName.create(B, REVISION, A);
         assertTrue(qa.compareTo(qb) < 0);
         assertTrue(qb.compareTo(qa) > 0);
 
-        // compare with both null namespace
-        qb = QName.create(null, QName.parseRevision(revision), A);
-        assertTrue(qa.compareTo(qb) == 0);
-        assertTrue(qb.compareTo(qa) == 0);
-
         // compare with revision
         qa = QName.create(A, "2013-12-24", A);
         qb = QName.create(A, "2013-12-25", A);
@@ -99,7 +70,7 @@ public class QNameTest {
 
         // compare with 1 null revision
         qa = QName.create(URI.create(A), null, A);
-        qb = QName.create(URI.create(A), QName.parseRevision(revision), A);
+        qb = QName.create(URI.create(A), QName.parseRevision(REVISION), A);
         assertTrue(qa.compareTo(qb) < 0);
         assertTrue(qb.compareTo(qa) > 0);
 
@@ -111,9 +82,9 @@ public class QNameTest {
 
     @Test
     public void testQName() {
-        final QName qname = QName.create(namespace, revision, localName);
-        final QName qname1 = QName.create(namespace, localName);
-        final QName qname2 = QName.create(qname1, localName);
+        final QName qname = QName.create(NAMESPACE, REVISION, LOCALNAME);
+        final QName qname1 = QName.create(NAMESPACE, LOCALNAME);
+        final QName qname2 = QName.create(qname1, LOCALNAME);
         assertEquals(qname1, qname.withoutRevision());
         assertEquals(qname1, qname2);
         assertTrue(qname.isEqualWithoutRevision(qname1));
@@ -124,14 +95,14 @@ public class QNameTest {
 
     @Test
     public void testQNameModule() {
-        final QNameModule qnameModule = QNameModule.create(ns, new Date());
+        final QNameModule qnameModule = QNameModule.create(NS, new Date());
         assertNotNull(qnameModule.toString());
         assertNotNull(qnameModule.getRevisionNamespace());
     }
 
     private static void assertLocalNameFails(final String localName) {
         try {
-            new QName(null, localName);
+            new QName(NS, localName);
             fail("Local name should fail:" + localName);
         } catch (IllegalArgumentException e) {
             // Expected
index 01598ab720af162858f614f20d59ab91501afca5..7b951c81404ed86c614ec976d35b7cb374301974 100644 (file)
@@ -10,10 +10,8 @@ package org.opendaylight.yangtools.yang.model.util;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import com.google.common.annotations.Beta;
-import java.net.URI;
 import java.util.Date;
 import java.util.Optional;
-import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 
 /**
@@ -26,26 +24,21 @@ import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 @Deprecated
 @Beta
 public final class ModuleIdentifierImpl implements ModuleIdentifier {
-    private final QNameModule qnameModule;
+    private final Date revision;
     private final String name;
 
-    private ModuleIdentifierImpl(final String name, final Optional<URI> namespace, final Optional<Date> revision) {
+    private ModuleIdentifierImpl(final String name, final Optional<Date> revision) {
         this.name = checkNotNull(name);
-        this.qnameModule = QNameModule.create(namespace.orElse(null), revision.orElse(null));
+        this.revision = revision.orElse(null);
     }
 
     public static ModuleIdentifier create(final String name, final Optional<Date> revision) {
-        return new ModuleIdentifierImpl(name, Optional.empty(), revision);
-    }
-
-    public static ModuleIdentifier create(final String name, final Optional<URI> namespace,
-            final Optional<Date> revision) {
-        return new ModuleIdentifierImpl(name, namespace, revision);
+        return new ModuleIdentifierImpl(name, revision);
     }
 
     @Override
     public Optional<Date> getRevision() {
-        return Optional.ofNullable(qnameModule.getRevision());
+        return Optional.ofNullable(revision);
     }
 
     @Override
@@ -57,7 +50,7 @@ public final class ModuleIdentifierImpl implements ModuleIdentifier {
     public String toString() {
         return "ModuleIdentifierImpl{"
             + "name='" + name + '\''
-            + ", revision=" + qnameModule.getFormattedRevision()
+            + ", revision=" + revision
             + '}';
     }
 
index 67ab8ed8ddacaa01042a17f65638393edc79cac0..8061d9a4ad29611ea13530cefd494991e16925c6 100644 (file)
@@ -305,8 +305,7 @@ public final class SchemaContextUtil {
     }
 
     private static ModuleIdentifier moduleToIdentifier(final Module module) {
-        return ModuleIdentifierImpl.create(module.getName(), Optional.of(module.getNamespace()),
-            Optional.of(module.getRevision()));
+        return ModuleIdentifierImpl.create(module.getName(), Optional.of(module.getRevision()));
     }
 
     private static SchemaNode findNodeInModule(final Module module, final Iterable<QName> path) {
index b4054de4cc0f42e5fb04cd66ae3e0ebd924d4060..cc541dffe261aa3f2af912cb905dcf8ef56e8232 100644 (file)
@@ -32,7 +32,7 @@ public class BitsTypeTest {
         MockitoAnnotations.initMocks(this);
         doReturn("test").when(bit).getName();
 
-        QName qname = QName.create("TestQName");
+        QName qname = QName.create("namespace", "localname");
         SchemaPath schemaPath = SchemaPath.create(Collections.singletonList(qname), true);
 
         BitsTypeDefinition bitsType = BaseTypes.bitsTypeBuilder(schemaPath).addBit(bit).build();
index 2e4be322a1cfd2859e0f1b6afd2daa85d262befd..3dfe84a8ce54799634bb1cebbe1f255634a4b437 100644 (file)
@@ -27,7 +27,8 @@ public class LeafrefTest {
 
     @Test
     public void testMethodsOfLeafrefTest() {
-        final SchemaPath schemaPath = SchemaPath.create(false, QName.create("Cont1"), QName.create("List1"));
+        final SchemaPath schemaPath = SchemaPath.create(false, QName.create("test", "Cont1"),
+            QName.create("test", "List1"));
         final RevisionAwareXPathImpl revision = new RevisionAwareXPathImpl("/test:Cont1/test:List1", false);
         final RevisionAwareXPathImpl revision2 = new RevisionAwareXPathImpl("/test:Cont1/test:List2", false);
 
@@ -43,7 +44,7 @@ public class LeafrefTest {
         assertNull("Base type of 'leafref' should be null.", leafref.getBaseType());
         assertNull("Units of 'leafref' should be empty.", leafref.getUnits());
         assertNull("Leafref does not have a default value", leafref.getDefaultValue());
-        assertEquals(QName.create("List1"), leafref.getQName());
+        assertEquals(QName.create("test", "List1"), leafref.getQName());
         assertEquals("SchemaPath of 'leafref' is '/Cont1/List1'.", schemaPath, leafref.getPath());
         assertNull(leafref.getDescription());
         assertNull(leafref.getReference());
@@ -64,7 +65,8 @@ public class LeafrefTest {
 
     @Test
     public void testRequireInstanceSubstatement() {
-        final SchemaPath schemaPath = SchemaPath.create(true, QName.create("my-cont"), QName.create("my-leafref"));
+        final SchemaPath schemaPath = SchemaPath.create(true, QName.create("test", "my-cont"),
+            QName.create("test", "my-leafref"));
         final RevisionAwareXPathImpl path = new RevisionAwareXPathImpl("../my-leaf", false);
 
         LeafrefTypeBuilder leafrefTypeBuilder = BaseTypes.leafrefTypeBuilder(schemaPath).setPathStatement(path);
@@ -85,8 +87,9 @@ public class LeafrefTest {
             leafrefTypeBuilder.setRequireInstance(false);
             fail("An IllegalArgumentException should have been thrown.");
         } catch (IllegalArgumentException ex) {
-            assertEquals("Cannot switch off require-instance in type AbsoluteSchemaPath{path=[my-cont, my-leafref]}",
-                    ex.getMessage());
+            assertEquals(
+                "Cannot switch off require-instance in type AbsoluteSchemaPath{path=[(test)my-cont, (test)my-leafref]}",
+                ex.getMessage());
         }
 
     }
index 1160d743d1c31b6dc6041378d4d5fd8d115c7d49..c24fc9e04ec4c05414e5d506833329a4b24ee07d 100644 (file)
@@ -11,6 +11,7 @@ import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.doReturn;
 
+import java.net.URI;
 import java.util.Collections;
 import java.util.Optional;
 import org.junit.Test;
@@ -26,6 +27,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.util.type.BaseTypes;
 
 public class SchemaContextUtilTest {
+    private static final URI NAMESPACE = URI.create("abc");
     @Mock
     private SchemaContext mockSchemaContext;
     @Mock
@@ -36,12 +38,16 @@ public class SchemaContextUtilTest {
         MockitoAnnotations.initMocks(this);
         doReturn(Optional.empty()).when(mockSchemaContext).findModule(any(QNameModule.class));
 
-        QName qname = QName.create("TestQName");
+        doReturn("test").when(mockModule).getPrefix();
+        doReturn(NAMESPACE).when(mockModule).getNamespace();
+        doReturn(QNameModule.create(NAMESPACE, null)).when(mockModule).getQNameModule();
+
+        QName qname = QName.create("namespace", "localname");
         SchemaPath schemaPath = SchemaPath.create(Collections.singletonList(qname), true);
         assertEquals("Should be null. Module TestQName not found", null,
                 SchemaContextUtil.findDataSchemaNode(mockSchemaContext, schemaPath));
 
-        RevisionAwareXPath xpath = new RevisionAwareXPathImpl("/bookstore/book/title", true);
+        RevisionAwareXPath xpath = new RevisionAwareXPathImpl("/test:bookstore/test:book/test:title", true);
         assertEquals("Should be null. Module bookstore not found", null,
                 SchemaContextUtil.findDataSchemaNode(mockSchemaContext, mockModule, xpath));
 
index 3425c68280cac68bdfcb35a23b9f2cfc18a3ed8a..748333b0742d210ce580f2bda0efc2a2880a7141 100644 (file)
@@ -55,8 +55,9 @@ public class SchemaContextUtilTest {
     public void testFindDummyData() {
         MockitoAnnotations.initMocks(this);
         doReturn(Optional.empty()).when(mockSchemaContext).findModule(any(QNameModule.class));
+        doReturn(URI.create("dummy")).when(mockModule).getNamespace();
 
-        final QName qName = QName.create("TestQName");
+        final QName qName = QName.create("dummy", "TestQName");
         final SchemaPath schemaPath = SchemaPath.create(Collections.singletonList(qName), true);
         assertEquals("Should be null. Module TestQName not found", null,
                 SchemaContextUtil.findDataSchemaNode(mockSchemaContext, schemaPath));
index 7f63b66d7e9f0b64de323a613eaee92362d88aae..8f4970baef139ceaf85c216fcb45b30ed7ff8c6d 100644 (file)
@@ -12,7 +12,6 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import com.google.common.collect.ImmutableSet;
-import java.net.URI;
 import java.util.Date;
 import java.util.Optional;
 import java.util.Set;
@@ -29,12 +28,12 @@ public class Bug6961Test {
     @Test
     public void testBug6961SchemaContext() throws Exception {
         final Optional<Date> date = Optional.of(QName.parseRevision("2016-01-01"));
-        final ModuleIdentifier foo = ModuleIdentifierImpl.create("foo", Optional.of(new URI("foo")), date);
-        final ModuleIdentifier sub1Foo = ModuleIdentifierImpl.create("sub1-foo", Optional.of(new URI("foo")), date);
-        final ModuleIdentifier sub2Foo = ModuleIdentifierImpl.create("sub2-foo", Optional.of(new URI("foo")), date);
-        final ModuleIdentifier bar = ModuleIdentifierImpl.create("bar", Optional.of(new URI("bar")), date);
-        final ModuleIdentifier sub1Bar = ModuleIdentifierImpl.create("sub1-bar", Optional.of(new URI("bar")), date);
-        final ModuleIdentifier baz = ModuleIdentifierImpl.create("baz", Optional.of(new URI("baz")), date);
+        final ModuleIdentifier foo = ModuleIdentifierImpl.create("foo", date);
+        final ModuleIdentifier sub1Foo = ModuleIdentifierImpl.create("sub1-foo", date);
+        final ModuleIdentifier sub2Foo = ModuleIdentifierImpl.create("sub2-foo", date);
+        final ModuleIdentifier bar = ModuleIdentifierImpl.create("bar", date);
+        final ModuleIdentifier sub1Bar = ModuleIdentifierImpl.create("sub1-bar", date);
+        final ModuleIdentifier baz = ModuleIdentifierImpl.create("baz", date);
         final Set<ModuleIdentifier> testSet = ImmutableSet.of(foo, sub1Foo, sub2Foo, bar, sub1Bar, baz);
         final SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug6961/");
         assertNotNull(context);