BUG-4456: rework leaker integration 51/47451/3
authorRobert Varga <rovarga@cisco.com>
Mon, 24 Oct 2016 16:27:14 +0000 (18:27 +0200)
committerRobert Varga <nite@hq.sk>
Tue, 25 Oct 2016 11:54:21 +0000 (11:54 +0000)
Rather than spreading the use of leaker across three
classes, centralize its use in ExtensionEffectiveStatementImpl
by exposing a protected method which can be overridden.

This is a bit cleaner solution and should end up being more
performant, as other statements do not end up touching
the thread-local variable.

Change-Id: I6f26dca90c0e5a907e98c65aa953f52ef87364e0
Signed-off-by: Robert Varga <rovarga@cisco.com>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ExtensionStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveStatementBase.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ExtensionEffectiveStatementImpl.java

index 7b4d4c25bc339fd5d255c36d0bf56dd7564b689a..fe1c04dc7e3b0677890b744dd98df62e915001a0 100644 (file)
@@ -56,22 +56,7 @@ public class ExtensionStatementImpl extends AbstractDeclaredStatement<QName> imp
         @Override
         public EffectiveStatement<QName,ExtensionStatement> createEffective(
                 final StmtContext<QName,ExtensionStatement ,EffectiveStatement<QName,ExtensionStatement>> ctx) {
-
-            // Look at the thread-local leak in case we are invoked recursively
-            final ExtensionEffectiveStatementImpl existing = RecursiveObjectLeaker.lookup(ctx,
-                ExtensionEffectiveStatementImpl.class);
-            if (existing != null) {
-                // Careful! this not fully initialized!
-                return existing;
-            }
-
-            RecursiveObjectLeaker.beforeConstructor(ctx);
-            try {
-                // This result is fine, we know it has been completely initialized
-                return new ExtensionEffectiveStatementImpl(ctx);
-            } finally {
-                RecursiveObjectLeaker.afterConstructor(ctx);
-            }
+            return ExtensionEffectiveStatementImpl.create(ctx);
         }
 
         @Override
index 8580ef6d756a4ae179880982c9b7a5761a435586..2be188cd88a76093468a97d6e54dca406829f082 100644 (file)
@@ -24,7 +24,6 @@ import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.RecursiveObjectLeaker;
 
 public abstract class EffectiveStatementBase<A, D extends DeclaredStatement<A>> implements EffectiveStatement<A, D> {
     private final List<? extends EffectiveStatement<?, ?>> substatements;
@@ -53,11 +52,20 @@ public abstract class EffectiveStatementBase<A, D extends DeclaredStatement<A>>
         }
         substatementsInit.addAll(effectiveSubstatements);
 
-        // WARNING: this leaks an incompletely-initialized pbject
-        RecursiveObjectLeaker.inConstructor(this);
+        this.substatements = ImmutableList.copyOf(initSubstatements(substatementsInit));
+    }
 
-        this.substatements = ImmutableList.copyOf(Collections2.transform(Collections2.filter(substatementsInit,
-            StmtContext::isSupportedToBuildEffective), StatementContextBase::buildEffective));
+    /**
+     * Create a set of substatements. This method is split out so it can be overridden in
+     * {@link ExtensionEffectiveStatementImpl} to leak a not-fully-initialized instance.
+     *
+     * @param substatementsInit proposed substatements
+     * @return Filtered substatements
+     */
+    Collection<? extends EffectiveStatement<?, ?>> initSubstatements(
+            final Collection<StatementContextBase<?, ?, ?>> substatementsInit) {
+        return Collections2.transform(Collections2.filter(substatementsInit,
+            StmtContext::isSupportedToBuildEffective), StatementContextBase::buildEffective);
     }
 
     @Override
index d40c8ea519ad1342c64ab11ce600baf548a214fa..305fcc6075c9a66668a58d929a6feb97a5a004de 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 import com.google.common.collect.ImmutableList;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Deque;
 import java.util.List;
 import java.util.Objects;
@@ -20,6 +21,8 @@ import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ExtensionStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.RecursiveObjectLeaker;
 
 public class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocumentedNode<QName, ExtensionStatement>
         implements ExtensionDefinition {
@@ -64,7 +67,7 @@ public class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocumented
     private final List<UnknownSchemaNode> unknownNodes;
     private final boolean yin;
 
-    public ExtensionEffectiveStatementImpl(
+    private ExtensionEffectiveStatementImpl(
             final StmtContext<QName, ExtensionStatement, EffectiveStatement<QName, ExtensionStatement>> ctx) {
         super(ctx);
         this.qname = ctx.getStatementArgument();
@@ -96,6 +99,40 @@ public class ExtensionEffectiveStatementImpl extends AbstractEffectiveDocumented
         }
     }
 
+    /**
+     * Create a new ExtensionEffectiveStatement, dealing with potential recursion
+     *
+     * @param ctx Statement context
+     * @return A potentially under-initialized instance
+     */
+    public static EffectiveStatement<QName, ExtensionStatement> create(
+            final StmtContext<QName, ExtensionStatement, EffectiveStatement<QName, ExtensionStatement>> ctx) {
+        // Look at the thread-local leak in case we are invoked recursively
+        final ExtensionEffectiveStatementImpl existing = RecursiveObjectLeaker.lookup(ctx,
+            ExtensionEffectiveStatementImpl.class);
+        if (existing != null) {
+            // Careful! this not fully initialized!
+            return existing;
+        }
+
+        RecursiveObjectLeaker.beforeConstructor(ctx);
+        try {
+            // This result is fine, we know it has been completely initialized
+            return new ExtensionEffectiveStatementImpl(ctx);
+        } finally {
+            RecursiveObjectLeaker.afterConstructor(ctx);
+        }
+    }
+
+    @Override
+    Collection<? extends EffectiveStatement<?, ?>> initSubstatements(
+            final Collection<StatementContextBase<?, ?, ?>> substatementsInit) {
+        // WARNING: this leaks an incompletely-initialized object
+        RecursiveObjectLeaker.inConstructor(this);
+
+        return super.initSubstatements(substatementsInit);
+    }
+
     @Override
     public QName getQName() {
         return qname;