Share empty ConstraintDefinition instances 98/29098/2
authorRobert Varga <rovarga@cisco.com>
Sun, 1 Nov 2015 18:27:29 +0000 (19:27 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 2 Nov 2015 08:19:04 +0000 (08:19 +0000)
Introduce a specialized class with two singleton instances for holding
the (very common) empty ConstraintDefinition object. Hide
EffectiveConstraintDefinitionImpl and make it expose just a static
factory method, which does the right thing.

Also creates ConstraintDefinitions to hold common functions for the two
implementations.

Change-Id: I4c25aee638ddb0617030fffcb0bc54ac13d28bc1
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveSimpleDataNodeContainer.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ConstraintDefinitions.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveConstraintDefinitionImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EmptyConstraintDefinition.java [new file with mode: 0644]

index 42023f191a067f5707c1fd8a4cf9f31f4fdaf2ff..c273cb5862d5018cadef53fe8fa40f6a6ae903b6 100644 (file)
@@ -24,9 +24,9 @@ abstract class AbstractEffectiveDataSchemaNode<D extends DeclaredStatement<QName
     private final boolean configuration;
     private final ConstraintDefinition constraints;
 
-    public AbstractEffectiveDataSchemaNode(StmtContext<QName, D, ?> ctx) {
+    public AbstractEffectiveDataSchemaNode(final StmtContext<QName, D, ?> ctx) {
         super(ctx);
-        this.constraints = new EffectiveConstraintDefinitionImpl(this);
+        this.constraints = EffectiveConstraintDefinitionImpl.forParent(this);
 
         ConfigEffectiveStatementImpl configStmt = firstEffective(ConfigEffectiveStatementImpl.class);
         this.configuration = (configStmt == null) ? true : configStmt.argument();
index 7503af7e193a505bd507e1f85af6ad3b45e00c28..b8c630ac75f81687ffe9166d55e5c8229659ea0d 100644 (file)
@@ -48,7 +48,7 @@ abstract class AbstractEffectiveSimpleDataNodeContainer<D extends DeclaredStatem
 
         this.qname = ctx.getStatementArgument();
         this.path = ctx.getSchemaPath().get();
-        this.constraints = new EffectiveConstraintDefinitionImpl(this);
+        this.constraints = EffectiveConstraintDefinitionImpl.forParent(this);
 
         ConfigEffectiveStatementImpl configStmt = firstEffective(ConfigEffectiveStatementImpl.class);
         this.configuration = (configStmt == null) ? true : configStmt.argument();
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ConstraintDefinitions.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ConstraintDefinitions.java
new file mode 100644 (file)
index 0000000..2641d2c
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
+
+import com.google.common.base.MoreObjects;
+import java.util.Objects;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+
+/**
+ * Utility methods for ConstraintDefinition implementations.
+ */
+final class ConstraintDefinitions {
+    private ConstraintDefinitions() {
+        throw new UnsupportedOperationException();
+    }
+
+    static int hashCode(final ConstraintDefinition def) {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + Objects.hashCode(def.getWhenCondition());
+        result = prime * result + Objects.hashCode(def.getMustConstraints());
+        result = prime * result + Objects.hashCode(def.getMinElements());
+        result = prime * result + Objects.hashCode(def.getMaxElements());
+        result = prime * result + Objects.hashCode(def.isMandatory());
+        return result;
+    }
+
+    static boolean equals(final ConstraintDefinition def, final Object obj) {
+        if (def == obj) {
+            return true;
+        }
+        if (!(obj instanceof ConstraintDefinition)) {
+            return false;
+        }
+        final ConstraintDefinition other = (EffectiveConstraintDefinitionImpl) obj;
+        if (def.isMandatory() != other.isMandatory()) {
+            return false;
+        }
+        if (!Objects.equals(def.getWhenCondition(), other.getWhenCondition())) {
+            return false;
+        }
+        if (!Objects.equals(def.getMustConstraints(), other.getMustConstraints())) {
+            return false;
+        }
+        if (!Objects.equals(def.getMinElements(), other.getMinElements())) {
+            return false;
+        }
+        if (!Objects.equals(def.getMaxElements(), other.getMaxElements())) {
+            return false;
+        }
+        return true;
+    }
+
+    static String toString(final ConstraintDefinition def) {
+        return MoreObjects.toStringHelper(def).omitNullValues()
+                .add("whenCondition", def.getWhenCondition())
+                .add("mustConstraints", def.getMustConstraints())
+                .add("mandatory", def.isMandatory())
+                .add("minElements", def.getMinElements())
+                .add("maxElements", def.getMaxElements()).toString();
+    }
+}
index a91f518ab0ac5a5a888aabdadc821825a2f2b23d..8b39b4bfde63edba39e04f7beea788ddb0513d76 100644 (file)
@@ -7,47 +7,62 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
-import java.util.Collection;
-import java.util.Objects;
 import java.util.Set;
 import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
 import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
 
-public final class EffectiveConstraintDefinitionImpl implements ConstraintDefinition {
+final class EffectiveConstraintDefinitionImpl implements ConstraintDefinition {
     private static final Integer UNBOUNDED_INT = Integer.MAX_VALUE;
     private static final String UNBOUNDED_STR = "unbounded";
     private final RevisionAwareXPath whenCondition;
     private final Set<MustDefinition> mustConstraints;
-    private final Boolean mandatory;
     private final Integer minElements;
     private final Integer maxElements;
+    private final boolean mandatory;
+
+    private EffectiveConstraintDefinitionImpl(final boolean mandatory, final Integer minElements,
+            final Integer maxElements, final RevisionAwareXPath whenCondition,
+            final Set<MustDefinition> mustConstraints) {
+        this.mandatory = mandatory;
+        this.minElements = Preconditions.checkNotNull(minElements);
+        this.maxElements = Preconditions.checkNotNull(maxElements);
+        this.whenCondition = whenCondition;
+        this.mustConstraints = Preconditions.checkNotNull(mustConstraints);
+    }
 
-    public EffectiveConstraintDefinitionImpl(final EffectiveStatementBase<?, ?> parent) {
-
-        WhenEffectiveStatementImpl firstWhenStmt = parent.firstEffective(WhenEffectiveStatementImpl.class);
-        this.whenCondition = (firstWhenStmt == null) ? null : firstWhenStmt.argument();
-
-        MinElementsEffectiveStatementImpl firstMinElementsStmt = parent
+    static ConstraintDefinition forParent(final EffectiveStatementBase<?, ?> parent) {
+        final MinElementsEffectiveStatementImpl firstMinElementsStmt = parent
                 .firstEffective(MinElementsEffectiveStatementImpl.class);
-        this.minElements = (firstMinElementsStmt == null) ? 0 : firstMinElementsStmt.argument();
+        final Integer minElements = (firstMinElementsStmt == null) ? 0 : firstMinElementsStmt.argument();
 
-        MaxElementsEffectiveStatementImpl firstMaxElementsStmt = parent
+        final MaxElementsEffectiveStatementImpl firstMaxElementsStmt = parent
                 .firstEffective(MaxElementsEffectiveStatementImpl.class);
-        String maxElementsArg = (firstMaxElementsStmt == null) ? UNBOUNDED_STR : firstMaxElementsStmt.argument();
+        final String maxElementsArg = (firstMaxElementsStmt == null) ? UNBOUNDED_STR : firstMaxElementsStmt.argument();
+        final Integer maxElements;
         if (UNBOUNDED_STR.equals(maxElementsArg)) {
-            this.maxElements = UNBOUNDED_INT;
+            maxElements = UNBOUNDED_INT;
         } else {
-            this.maxElements = Integer.valueOf(maxElementsArg);
+            maxElements = Integer.valueOf(maxElementsArg);
         }
 
-        MandatoryEffectiveStatementImpl firstMandatoryStmt = parent
+        final MandatoryEffectiveStatementImpl firstMandatoryStmt = parent
                 .firstEffective(MandatoryEffectiveStatementImpl.class);
-        this.mandatory = (firstMandatoryStmt == null) ? minElements > 0 : firstMandatoryStmt.argument();
+        final boolean mandatory = (firstMandatoryStmt == null) ? minElements > 0 : firstMandatoryStmt.argument();
+
+        final Set<MustDefinition> mustSubstatements = ImmutableSet.copyOf(parent.allSubstatementsOfType(
+            MustDefinition.class));
+        final WhenEffectiveStatementImpl firstWhenStmt = parent.firstEffective(WhenEffectiveStatementImpl.class);
 
-        Collection<MustDefinition> mustSubstatements = parent.allSubstatementsOfType(MustDefinition.class);
-        this.mustConstraints = ImmutableSet.copyOf(mustSubstatements);
+        // Check for singleton instances
+        if (minElements == 0 && maxElements == UNBOUNDED_INT && mustSubstatements.isEmpty() && firstWhenStmt == null) {
+            return EmptyConstraintDefinition.create(mandatory);
+        }
+
+        return new EffectiveConstraintDefinitionImpl(mandatory, minElements, maxElements,
+            (firstWhenStmt == null) ? null : firstWhenStmt.argument(), mustSubstatements);
     }
 
     @Override
@@ -77,56 +92,16 @@ public final class EffectiveConstraintDefinitionImpl implements ConstraintDefini
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + Objects.hashCode(whenCondition);
-        result = prime * result + Objects.hashCode(mustConstraints);
-        result = prime * result + Objects.hashCode(minElements);
-        result = prime * result + Objects.hashCode(maxElements);
-        result = prime * result + mandatory.hashCode();
-        return result;
+        return ConstraintDefinitions.hashCode(this);
     }
 
     @Override
     public boolean equals(final Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        EffectiveConstraintDefinitionImpl other = (EffectiveConstraintDefinitionImpl) obj;
-        if (!mandatory.equals(other.mandatory)) {
-            return false;
-        }
-        if (!Objects.equals(whenCondition, other.whenCondition)) {
-            return false;
-        }
-        if (!Objects.equals(mustConstraints, other.mustConstraints)) {
-            return false;
-        }
-        if (!Objects.equals(minElements, other.minElements)) {
-            return false;
-        }
-        if (!Objects.equals(maxElements, other.maxElements)) {
-            return false;
-        }
-        return true;
+        return ConstraintDefinitions.equals(this, obj);
     }
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder(EffectiveConstraintDefinitionImpl.class.getSimpleName());
-        sb.append("[");
-        sb.append("whenCondition=").append(whenCondition);
-        sb.append(", mustConstraints=").append(mustConstraints);
-        sb.append(", mandatory=").append(mandatory);
-        sb.append(", minElements=").append(minElements);
-        sb.append(", maxElements=").append(maxElements);
-        sb.append("]");
-        return sb.toString();
+        return ConstraintDefinitions.toString(this);
     }
 }
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EmptyConstraintDefinition.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EmptyConstraintDefinition.java
new file mode 100644 (file)
index 0000000..d0bc8ac
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition;
+import org.opendaylight.yangtools.yang.model.api.MustDefinition;
+import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
+
+/**
+ * Utility holder for constraint definitions which do not really constrain anything.
+ */
+abstract class EmptyConstraintDefinition implements ConstraintDefinition {
+    private static final EmptyConstraintDefinition MANDATORY = new EmptyConstraintDefinition() {
+        @Override
+        public boolean isMandatory() {
+            return true;
+        }
+    };
+    private static final EmptyConstraintDefinition OPTIONAL = new EmptyConstraintDefinition() {
+        @Override
+        public boolean isMandatory() {
+            return false;
+        }
+    };
+
+    private EmptyConstraintDefinition() {
+        // Hidden on purpose
+    }
+
+    static EmptyConstraintDefinition create(final boolean mandatory) {
+        return mandatory ? MANDATORY : OPTIONAL;
+    }
+
+    @Override
+    public final RevisionAwareXPath getWhenCondition() {
+        return null;
+    }
+
+    @Override
+    public final Set<MustDefinition> getMustConstraints() {
+        return ImmutableSet.of();
+    }
+
+    @Override
+    public final Integer getMinElements() {
+        return 0;
+    }
+
+    @Override
+    public final Integer getMaxElements() {
+        return Integer.MAX_VALUE;
+    }
+
+    @Override
+    public final int hashCode() {
+        return ConstraintDefinitions.hashCode(this);
+    }
+
+    @Override
+    public final boolean equals(final Object obj) {
+        return ConstraintDefinitions.equals(this, obj);
+    }
+
+    @Override
+    public final String toString() {
+        return ConstraintDefinitions.toString(this);
+    }
+}