You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by gp...@apache.org on 2015/10/13 21:34:02 UTC

[2/2] deltaspike git commit: DELTASPIKE-1001 cleanup caches in case of project-stage unit-test/development

DELTASPIKE-1001 cleanup caches in case of project-stage unit-test/development


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/737d5306
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/737d5306
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/737d5306

Branch: refs/heads/master
Commit: 737d53063bf45789f8d09277d2b079cd33d89614
Parents: eeee464
Author: gpetracek <gp...@apache.org>
Authored: Tue Oct 13 20:30:55 2015 +0200
Committer: gpetracek <gp...@apache.org>
Committed: Tue Oct 13 21:26:25 2015 +0200

----------------------------------------------------------------------
 .../core/util/ClassDeactivationUtils.java       |  48 ++++++--
 .../activation/EditableTestDeactivator.java     |  47 ++++++++
 ...jectStageDependentClassDeactivationTest.java | 111 +++++++++++++++++++
 .../test/api/config/TestConfigSource.java       |   1 +
 4 files changed, 197 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/737d5306/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java
index 6fcd715..2379ee9 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/ClassDeactivationUtils.java
@@ -20,6 +20,7 @@ package org.apache.deltaspike.core.util;
 
 import org.apache.deltaspike.core.api.config.ConfigResolver;
 import org.apache.deltaspike.core.api.config.base.CoreBaseConfig;
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
 import org.apache.deltaspike.core.spi.activation.ClassDeactivator;
 import org.apache.deltaspike.core.spi.activation.Deactivatable;
 
@@ -41,7 +42,7 @@ public abstract class ClassDeactivationUtils
     /**
      * This Map holds the ClassLoader as first level to make it possible to have different configurations per 
      * WebApplication in an EAR or other Multi-ClassLoader scenario.
-     * 
+     *
      * The Map then contains a List of {@link ClassDeactivator}s in order of their configured ordinal.
      */
     private static Map<ClassLoader, List<ClassDeactivator>> classDeactivatorMap
@@ -53,7 +54,9 @@ public abstract class ClassDeactivationUtils
      */
     private static Map<Class<? extends Deactivatable>, Boolean> activationStatusCache
         = new ConcurrentHashMap<Class<? extends Deactivatable>, Boolean>();
-    
+
+    private static ProjectStage previouslyDetectedProjectStage;
+
     private ClassDeactivationUtils()
     {
         // prevent instantiation
@@ -67,19 +70,43 @@ public abstract class ClassDeactivationUtils
      */
     public static boolean isActivated(Class<? extends Deactivatable> targetClass)
     {
-        Boolean activatedClassCacheEntry = activationStatusCache.get(targetClass);
+        performProjectStageDependentCleanup();
+
+        //just to support parallel access to #isActivated (+ reset) in project-stage unit-test and development
+        Map<Class<? extends Deactivatable>, Boolean> activeCache = activationStatusCache;
+        Boolean activatedClassCacheEntry = activeCache.get(targetClass);
 
         if (activatedClassCacheEntry == null)
         {
-            initDeactivatableCacheFor(targetClass);
-            activatedClassCacheEntry = activationStatusCache.get(targetClass);
+            initDeactivatableCacheFor(targetClass, activeCache);
+            activatedClassCacheEntry = activeCache.get(targetClass);
         }
         return activatedClassCacheEntry;
     }
 
-    private static synchronized void initDeactivatableCacheFor(Class<? extends Deactivatable> targetClass)
+    private static void performProjectStageDependentCleanup()
+    {
+        ProjectStage currentProjectStage = ProjectStageProducer.getInstance().getProjectStage();
+
+        if (previouslyDetectedProjectStage != currentProjectStage)
+        {
+            previouslyDetectedProjectStage = currentProjectStage;
+            //don't use #clear to support parallel access to #isActivated (+ reset) without synchronization
+            activationStatusCache = new ConcurrentHashMap<Class<? extends Deactivatable>, Boolean>();
+
+            //#clear is ok here due to the handling in the synchronized method #initDeactivatableCacheFor
+            classDeactivatorMap.clear();
+        }
+        else if (currentProjectStage == ProjectStage.UnitTest || currentProjectStage == ProjectStage.Development)
+        {
+            activationStatusCache = new ConcurrentHashMap<Class<? extends Deactivatable>, Boolean>();
+        }
+    }
+
+    private static synchronized void initDeactivatableCacheFor(Class<? extends Deactivatable> targetClass,
+                                                               Map<Class<? extends Deactivatable>, Boolean> activeCache)
     {
-        Boolean activatedClassCacheEntry = activationStatusCache.get(targetClass);
+        Boolean activatedClassCacheEntry = activeCache.get(targetClass);
 
         if (activatedClassCacheEntry != null) //double-check
         {
@@ -122,12 +149,13 @@ public abstract class ClassDeactivationUtils
             }
         }
 
-        cacheResult(targetClass, isActivated);
+        cacheResult(targetClass, isActivated, activeCache);
     }
 
-    private static void cacheResult(Class<? extends Deactivatable> targetClass, Boolean activated)
+    private static void cacheResult(Class<? extends Deactivatable> targetClass, Boolean activated,
+                                    Map<Class<? extends Deactivatable>, Boolean> activeCache)
     {
-        activationStatusCache.put(targetClass, activated);
+        activeCache.put(targetClass, activated);
         LOG.info("class: " + targetClass.getName() + " activated=" + activated);
     }
 

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/737d5306/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/EditableTestDeactivator.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/EditableTestDeactivator.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/EditableTestDeactivator.java
new file mode 100644
index 0000000..cd06855
--- /dev/null
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/EditableTestDeactivator.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.deltaspike.core.util.activation;
+
+import org.apache.deltaspike.core.spi.activation.ClassDeactivator;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class EditableTestDeactivator implements ClassDeactivator
+{
+    private static Map<Class<? extends Deactivatable>, Boolean> result = new HashMap<Class<? extends Deactivatable>, Boolean>();
+
+    @Override
+    public Boolean isActivated(Class<? extends Deactivatable> targetClass)
+    {
+        return result.get(targetClass);
+    }
+
+    public static void activate(Class<? extends Deactivatable> classToActivate)
+    {
+        result.put(classToActivate, true);
+    }
+
+    public static void deactivate(Class<? extends Deactivatable> classToActivate)
+    {
+        result.put(classToActivate, false);
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/737d5306/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/ProjectStageDependentClassDeactivationTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/ProjectStageDependentClassDeactivationTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/ProjectStageDependentClassDeactivationTest.java
new file mode 100644
index 0000000..6ca2a93
--- /dev/null
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/core/util/activation/ProjectStageDependentClassDeactivationTest.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.deltaspike.core.util.activation;
+
+import org.apache.deltaspike.core.api.projectstage.ProjectStage;
+import org.apache.deltaspike.core.spi.activation.Deactivatable;
+import org.apache.deltaspike.core.util.ClassDeactivationUtils;
+import org.apache.deltaspike.core.util.ProjectStageProducer;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ProjectStageDependentClassDeactivationTest
+{
+    @Test
+    public void deactivationResultInProjectStageUnitTest()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.UnitTest);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(false, ClassDeactivationUtils.isActivated(classToCheck));
+    }
+
+    @Test
+    public void deactivationResultInProjectStageDevelopment()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.Development);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(false, ClassDeactivationUtils.isActivated(classToCheck));
+    }
+
+    @Test
+    public void deactivationResultInProjectStageProduction()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.Production);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
+    }
+
+    @Test
+    public void deactivationResultInProjectStageIntegrationTest()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.IntegrationTest);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
+    }
+
+    @Test
+    public void deactivationResultInProjectStageStaging()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.Staging);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
+    }
+
+    @Test
+    public void deactivationResultInProjectStageSystemTest()
+    {
+        ProjectStageProducer.setProjectStage(ProjectStage.SystemTest);
+
+        final Class<? extends Deactivatable> classToCheck = TestDeactivatable.class;
+        EditableTestDeactivator.activate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck));
+
+        EditableTestDeactivator.deactivate(classToCheck);
+        Assert.assertEquals(true, ClassDeactivationUtils.isActivated(classToCheck)); //due to the cached result
+    }
+
+    private static class TestDeactivatable implements Deactivatable
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/737d5306/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
index 7f0897c..709c1ee 100644
--- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
+++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java
@@ -77,6 +77,7 @@ public class TestConfigSource implements ConfigSource
         props.put("deltaspike.test.class-value", "org.apache.deltaspike.test.api.config.TestConfigSource");
         props.put("deltaspike.test.date-value", "2014-12-24");
         props.put("deltaspike.test.invalid-value", "wrong");
+        props.put("org.apache.deltaspike.core.spi.activation.ClassDeactivator","org.apache.deltaspike.core.util.activation.EditableTestDeactivator");
     }
 
     @Override