EXTVAL-128

git-svn-id: https://svn.apache.org/repos/asf/myfaces/extensions/validator/trunk@1077841 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/AbstractNameMapperAwareFactory.java b/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/AbstractNameMapperAwareFactory.java
index 87c54d9..80a7e79 100644
--- a/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/AbstractNameMapperAwareFactory.java
+++ b/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/AbstractNameMapperAwareFactory.java
@@ -18,6 +18,8 @@
  */

 package org.apache.myfaces.extensions.validator.core.factory;

 

+import org.apache.myfaces.extensions.validator.core.Nested;

+import org.apache.myfaces.extensions.validator.core.mapper.SubMapperAwareNameMapper;

 import org.apache.myfaces.extensions.validator.internal.UsageInformation;

 import org.apache.myfaces.extensions.validator.internal.UsageCategory;

 import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

@@ -75,14 +77,32 @@
 

     public synchronized void deregister(Class<? extends NameMapper> classToDeregister)

     {

-        Iterator<NameMapper<T>> nameMapperIterator = getNameMapperList().iterator();

-        while(nameMapperIterator.hasNext())

+        boolean subNameMapper = false;

+

+        if (classToDeregister != null && classToDeregister.isAnnotationPresent(Nested.class))

         {

-            if(nameMapperIterator.next().getClass().getName().equals(classToDeregister.getName()))

+            subNameMapper = true;

+        }

+

+        Iterator<NameMapper<T>> nameMapperIterator = getNameMapperList().iterator();

+        while (nameMapperIterator.hasNext())

+        {

+            if (subNameMapper)

             {

-                nameMapperIterator.remove();

-                //don't break - e.g. to deregister all wrappers...

-                //break;

+                NameMapper<T> nameMapper = nameMapperIterator.next();

+                if (nameMapper instanceof SubMapperAwareNameMapper)

+                {

+                    ((SubMapperAwareNameMapper) nameMapper).removeNameMapper(classToDeregister);

+                }

+            }

+            else

+            {

+                if (nameMapperIterator.next().getClass().getName().equals(classToDeregister.getName()))

+                {

+                    nameMapperIterator.remove();

+                    //don't break - e.g. to deregister all wrappers...

+                    //break;

+                }

             }

         }

     }

diff --git a/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/SubMapperAwareNameMapper.java b/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/SubMapperAwareNameMapper.java
index 489cf99..1fae13a 100644
--- a/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/SubMapperAwareNameMapper.java
+++ b/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/SubMapperAwareNameMapper.java
@@ -35,4 +35,10 @@
      * @param nameMapper sub-nameMapper to add

      */

     void addNameMapper(NameMapper<T> nameMapper);

+

+    /**

+     * Deregisters all (sub-)name mappers of the given type

+     * @param nameMapperClass type of the (sub-)name mappers which have to be deregistered

+     */

+    void removeNameMapper(Class<? extends NameMapper> nameMapperClass);

 }
\ No newline at end of file
diff --git a/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/DefaultMetaDataTransformerFactory.java b/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/DefaultMetaDataTransformerFactory.java
index e00fd73..1e104ea 100644
--- a/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/DefaultMetaDataTransformerFactory.java
+++ b/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/DefaultMetaDataTransformerFactory.java
@@ -38,6 +38,7 @@
 import org.apache.myfaces.extensions.validator.internal.UsageInformation;

 import org.apache.myfaces.extensions.validator.internal.UsageCategory;

 

+import java.util.ArrayList;

 import java.util.List;

 import java.util.Map;

 import java.util.concurrent.CopyOnWriteArrayList;

@@ -232,6 +233,22 @@
         super.register(validationStrategyNameMapper);

     }

 

+    @Override

+    public void deregister(Class<? extends NameMapper> classToDeregister)

+    {

+        super.deregister(classToDeregister);

+        for (NameMapper<ValidationStrategy> nameMapper

+                : new ArrayList<NameMapper<ValidationStrategy>>(subNameMapperList))

+        {

+

+            if (nameMapper.getClass().equals(classToDeregister))

+            {

+                subNameMapperList.remove(nameMapper);

+            }

+        }

+

+    }

+

     /**

      * it's a very special case due to the missing order in the execution of startup-listeners (phase listeners)

      * packaged in faces-config.xml files of jars

@@ -257,4 +274,11 @@
             }

         }

     }

+

+    //just for testing

+    protected List<NameMapper<ValidationStrategy>> getSubNameMapperList()

+    {

+        return this.subNameMapperList;

+    }

 }

+

diff --git a/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper.java b/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper.java
index 203c926..fc01f00 100644
--- a/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper.java
+++ b/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper.java
@@ -54,6 +54,28 @@
         }

     }

 

+    public void removeNameMapper(Class<? extends NameMapper> nameMapperClass)

+    {

+        List<NameMapper<ValidationStrategy>> nameMappersToRemove =

+                new ArrayList<NameMapper<ValidationStrategy>>(this.subNameMappers.size());

+

+        for(NameMapper<ValidationStrategy> currentSubNameMapper : this.subNameMappers)

+        {

+            if(currentSubNameMapper.getClass().getName().equals(nameMapperClass.getName()))

+            {

+                nameMappersToRemove.add(currentSubNameMapper);

+                //don't break - e.g. to deregister all wrappers...

+                //break;

+            }

+        }

+

+        //do it manually due to the CopyOnWriteArrayList

+        for(NameMapper<ValidationStrategy> currentSubNameMapper : nameMappersToRemove)

+        {

+            this.subNameMappers.remove(currentSubNameMapper);

+        }

+    }

+

     private void sortSubNameMappers()

     {

         List<NameMapper<ValidationStrategy>> sortableList =

diff --git a/test-modules/base-test-infrastructure/src/test/java/org/apache/myfaces/extensions/validator/test/base/mock/MockMetaDataTransformerFactory.java b/test-modules/base-test-infrastructure/src/test/java/org/apache/myfaces/extensions/validator/test/base/mock/MockMetaDataTransformerFactory.java
index aa0d5d8..27cfe52 100644
--- a/test-modules/base-test-infrastructure/src/test/java/org/apache/myfaces/extensions/validator/test/base/mock/MockMetaDataTransformerFactory.java
+++ b/test-modules/base-test-infrastructure/src/test/java/org/apache/myfaces/extensions/validator/test/base/mock/MockMetaDataTransformerFactory.java
@@ -33,4 +33,9 @@
     {

         return super.getNameMapperList();

     }

+

+    public List<NameMapper<ValidationStrategy>> getSubNameMapperList()

+    {

+        return super.getSubNameMapperList();

+    }

 }
\ No newline at end of file
diff --git a/test-modules/bean-validation-tests/src/test/java/org/apache/myfaces/extensions/validator/test/beanval/DeregisterSubNameMapperTestCase.java b/test-modules/bean-validation-tests/src/test/java/org/apache/myfaces/extensions/validator/test/beanval/DeregisterSubNameMapperTestCase.java
new file mode 100644
index 0000000..be850a1
--- /dev/null
+++ b/test-modules/bean-validation-tests/src/test/java/org/apache/myfaces/extensions/validator/test/beanval/DeregisterSubNameMapperTestCase.java
@@ -0,0 +1,95 @@
+/*

+ * 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.myfaces.extensions.validator.test.beanval;

+

+import org.junit.Test;

+import org.junit.Assert;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.beanval.metadata.transformer.mapper.SizeNameMapper;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.mapper.SubMapperAwareNameMapper;

+import org.apache.myfaces.extensions.validator.core.factory.FactoryNames;

+import org.apache.myfaces.extensions.validator.test.base.mock.MockMetaDataTransformerFactory;

+

+import java.util.List;

+

+public class DeregisterSubNameMapperTestCase extends AbstractBeanValidationTestCase

+{

+    @Test

+    public void testDenyNameMapper()

+    {

+        int count = getNameMapperAndSubNameMapperCount();

+

+        Assert.assertEquals(7, count);

+

+        ExtValUtils.denyValidationStrategyToMetaDataTransformerNameMapper(SizeNameMapper.class);

+

+        count = getNameMapperAndSubNameMapperCount();

+        Assert.assertEquals(6, count);

+

+        //no effect because it's denied

+        ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(new SizeNameMapper());

+

+        count = getNameMapperAndSubNameMapperCount();

+        Assert.assertEquals(6, count);

+    }

+    @Test

+    public void testDeregisterNameMapper()

+    {

+        int count = getNameMapperAndSubNameMapperCount();

+

+        Assert.assertEquals(7, count);

+

+        ExtValUtils.deregisterValidationStrategyToMetaDataTransformerNameMapper(SizeNameMapper.class);

+

+        count = getNameMapperAndSubNameMapperCount();

+        Assert.assertEquals(6, count);

+

+        ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(new SizeNameMapper());

+

+        count = getNameMapperAndSubNameMapperCount();

+        Assert.assertEquals(7, count);

+    }

+

+    private int getNameMapperAndSubNameMapperCount()

+    {

+        MockMetaDataTransformerFactory nameMapperAwareFactory =

+                (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.META_DATA_TRANSFORMER_FACTORY, MockMetaDataTransformerFactory.class));

+

+        List<NameMapper<ValidationStrategy>> nameMapperList = nameMapperAwareFactory.getRegisteredNameMapperList();

+

+        int count = 0;

+

+        for(NameMapper<ValidationStrategy> nameMapper : nameMapperList)

+        {

+            if(!(nameMapper instanceof SubMapperAwareNameMapper))

+            {

+                count++;

+            }

+        }

+

+        List<NameMapper<ValidationStrategy>> subNamMappers = nameMapperAwareFactory.getSubNameMapperList();

+        count += subNamMappers.size();

+        return count;

+    }

+}