Author: trustin
Date: Thu Aug  2 22:28:02 2007
New Revision: 562335

URL: http://svn.apache.org/viewvc?view=rev&rev=562335
Log:
Resolved issue: DIRMINA-410 (DefaultIoFilterChainBuilder synchronization issue 
with contains(...) methods)
* Changed DefaultIoFilterChainBuilder to use CopyOnWriteArrayList
* Added more remove() methods to IoFilterChain in trunk
* Did a little bit more synchronization and volatilization on methods and 
variables



Modified:
    
mina/branches/1.0/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
    
mina/branches/1.1/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
    
mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
    mina/trunk/core/src/main/java/org/apache/mina/common/IoFilterChain.java
    
mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java

Modified: 
mina/branches/1.0/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
URL: 
http://svn.apache.org/viewvc/mina/branches/1.0/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java?view=diff&rev=562335&r1=562334&r2=562335
==============================================================================
--- 
mina/branches/1.0/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
 (original)
+++ 
mina/branches/1.0/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
 Thu Aug  2 22:28:02 2007
@@ -21,15 +21,15 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Map;
 
 import org.apache.mina.common.IoFilter.NextFilter;
 import org.apache.mina.common.IoFilterChain.Entry;
 
+import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList;
+
 /**
  * The default implementation of [EMAIL PROTECTED] IoFilterChainBuilder} which 
is useful
  * in most cases.  [EMAIL PROTECTED] DefaultIoFilterChainBuilder} has an 
identical interface
@@ -56,33 +56,33 @@
  */
 public class DefaultIoFilterChainBuilder implements IoFilterChainBuilder,
         Cloneable {
-    private List entries;
-
-    private Map entriesByName;
+    private final List entries;
 
     /**
      * Creates a new instance with an empty filter list.
      */
     public DefaultIoFilterChainBuilder() {
-        init();
-    }
-
-    private void init() {
-        entries = new ArrayList();
-        entriesByName = new HashMap();
+        entries = new CopyOnWriteArrayList();
     }
 
     /**
      * @see IoFilterChain#getEntry(String)
      */
-    public synchronized Entry getEntry(String name) {
-        return (Entry) entriesByName.get(name);
+    public Entry getEntry(String name) {
+        for (Iterator i = entries.iterator(); i.hasNext(); ) {
+            Entry e = (Entry) i.next();
+            if (e.getName().equals(name)) {
+                return e;
+            }
+        }
+        
+        return null;
     }
 
     /**
      * @see IoFilterChain#get(String)
      */
-    public synchronized IoFilter get(String name) {
+    public IoFilter get(String name) {
         Entry e = getEntry(name);
         if (e == null) {
             return null;
@@ -179,8 +179,6 @@
             IoFilter filter) {
         checkBaseName(baseName);
 
-        List entries = new ArrayList(this.entries);
-
         for (ListIterator i = entries.listIterator(); i.hasNext();) {
             Entry base = (Entry) i.next();
             if (base.getName().equals(baseName)) {
@@ -201,7 +199,7 @@
         for (ListIterator i = entries.listIterator(); i.hasNext();) {
             Entry e = (Entry) i.next();
             if (e.getName().equals(name)) {
-                deregister(i.previousIndex(), e);
+                entries.remove(i.previousIndex());
                 return e.getFilter();
             }
         }
@@ -213,7 +211,7 @@
      * @see IoFilterChain#clear()
      */
     public synchronized void clear() throws Exception {
-        init();
+        entries.clear();
     }
 
     public void buildFilterChain(IoFilterChain chain) throws Exception {
@@ -254,15 +252,7 @@
     }
 
     public Object clone() {
-        DefaultIoFilterChainBuilder ret;
-        try {
-            ret = (DefaultIoFilterChainBuilder) super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw (InternalError) new InternalError().initCause(e);
-        }
-
-        ret.init();
-
+        DefaultIoFilterChainBuilder ret = new DefaultIoFilterChainBuilder();
         for (Iterator i = entries.iterator(); i.hasNext();) {
             Entry e = (Entry) i.next();
             ret.addLast(e.getName(), e.getFilter());
@@ -274,29 +264,20 @@
         if (baseName == null) {
             throw new NullPointerException("baseName");
         }
-        if (!entriesByName.containsKey(baseName)) {
+        
+        if (!contains(baseName)) {
             throw new IllegalArgumentException("Unknown filter name: "
                     + baseName);
         }
     }
 
     private void register(int index, Entry e) {
-        if (entriesByName.containsKey(e.getName())) {
+        if (contains(e.getName())) {
             throw new IllegalArgumentException(
                     "Other filter is using the same name: " + e.getName());
         }
 
-        List newEntries = new ArrayList(entries);
-        newEntries.add(index, e);
-        this.entries = newEntries;
-        entriesByName.put(e.getName(), e);
-    }
-
-    private void deregister(int index, Entry e) {
-        List newEntries = new ArrayList(entries);
-        newEntries.remove(index);
-        this.entries = newEntries;
-        entriesByName.remove(e.getName());
+        entries.add(index, e);
     }
 
     private static class EntryImpl implements Entry {

Modified: 
mina/branches/1.1/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
URL: 
http://svn.apache.org/viewvc/mina/branches/1.1/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java?view=diff&rev=562335&r1=562334&r2=562335
==============================================================================
--- 
mina/branches/1.1/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
 (original)
+++ 
mina/branches/1.1/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
 Thu Aug  2 22:28:02 2007
@@ -21,11 +21,10 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.apache.mina.common.IoFilter.NextFilter;
 import org.apache.mina.common.IoFilterChain.Entry;
@@ -56,33 +55,32 @@
  */
 public class DefaultIoFilterChainBuilder implements IoFilterChainBuilder,
         Cloneable {
-    private List<Entry> entries;
-
-    private Map<String, Entry> entriesByName;
+    private final List<Entry> entries;
 
     /**
      * Creates a new instance with an empty filter list.
      */
     public DefaultIoFilterChainBuilder() {
-        init();
-    }
-
-    private void init() {
-        entries = new ArrayList<Entry>();
-        entriesByName = new HashMap<String, Entry>();
+        entries = new CopyOnWriteArrayList<Entry>();
     }
 
     /**
      * @see IoFilterChain#getEntry(String)
      */
-    public synchronized Entry getEntry(String name) {
-        return entriesByName.get(name);
+    public Entry getEntry(String name) {
+        for (Entry e: entries) {
+            if (e.getName().equals(name)) {
+                return e;
+            }
+        }
+        
+        return null;
     }
 
     /**
      * @see IoFilterChain#get(String)
      */
-    public synchronized IoFilter get(String name) {
+    public IoFilter get(String name) {
         Entry e = getEntry(name);
         if (e == null) {
             return null;
@@ -163,8 +161,8 @@
             IoFilter filter) {
         checkBaseName(baseName);
 
-        for (ListIterator i = entries.listIterator(); i.hasNext();) {
-            Entry base = (Entry) i.next();
+        for (ListIterator<Entry> i = entries.listIterator(); i.hasNext();) {
+            Entry base = i.next();
             if (base.getName().equals(baseName)) {
                 register(i.previousIndex(), new EntryImpl(name, filter));
                 break;
@@ -179,8 +177,6 @@
             IoFilter filter) {
         checkBaseName(baseName);
 
-        List<Entry> entries = new ArrayList<Entry>(this.entries);
-
         for (ListIterator<Entry> i = entries.listIterator(); i.hasNext();) {
             Entry base = i.next();
             if (base.getName().equals(baseName)) {
@@ -201,7 +197,7 @@
         for (ListIterator<Entry> i = entries.listIterator(); i.hasNext();) {
             Entry e = i.next();
             if (e.getName().equals(name)) {
-                deregister(i.previousIndex(), e);
+                entries.remove(i.previousIndex());
                 return e.getFilter();
             }
         }
@@ -213,7 +209,7 @@
      * @see IoFilterChain#clear()
      */
     public synchronized void clear() throws Exception {
-        init();
+        entries.clear();
     }
 
     public void buildFilterChain(IoFilterChain chain) throws Exception {
@@ -254,17 +250,8 @@
     }
 
     public Object clone() {
-        DefaultIoFilterChainBuilder ret;
-        try {
-            ret = (DefaultIoFilterChainBuilder) super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw (InternalError) new InternalError().initCause(e);
-        }
-
-        ret.init();
-
-        for (Iterator<Entry> i = entries.iterator(); i.hasNext();) {
-            Entry e = i.next();
+        DefaultIoFilterChainBuilder ret = new DefaultIoFilterChainBuilder();
+        for (Entry e : entries) {
             ret.addLast(e.getName(), e.getFilter());
         }
         return ret;
@@ -274,29 +261,20 @@
         if (baseName == null) {
             throw new NullPointerException("baseName");
         }
-        if (!entriesByName.containsKey(baseName)) {
+        
+        if (!contains(baseName)) {
             throw new IllegalArgumentException("Unknown filter name: "
                     + baseName);
         }
     }
 
     private void register(int index, Entry e) {
-        if (entriesByName.containsKey(e.getName())) {
+        if (contains(e.getName())) {
             throw new IllegalArgumentException(
                     "Other filter is using the same name: " + e.getName());
         }
 
-        List<Entry> newEntries = new ArrayList<Entry>(entries);
-        newEntries.add(index, e);
-        this.entries = newEntries;
-        entriesByName.put(e.getName(), e);
-    }
-
-    private void deregister(int index, Entry e) {
-        List<Entry> newEntries = new ArrayList<Entry>(entries);
-        newEntries.remove(index);
-        this.entries = newEntries;
-        entriesByName.remove(e.getName());
+        entries.add(index, e);
     }
 
     private static class EntryImpl implements Entry {

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java?view=diff&rev=562335&r1=562334&r2=562335
==============================================================================
--- 
mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
 (original)
+++ 
mina/trunk/core/src/main/java/org/apache/mina/common/DefaultIoFilterChainBuilder.java
 Thu Aug  2 22:28:02 2007
@@ -21,10 +21,8 @@
 
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
 
 import org.apache.mina.common.IoFilter.NextFilter;
@@ -56,33 +54,32 @@
  */
 public class DefaultIoFilterChainBuilder implements IoFilterChainBuilder,
         Cloneable {
-    private List<Entry> entries;
-
-    private Map<String, Entry> entriesByName;
+    private final List<Entry> entries;
 
     /**
      * Creates a new instance with an empty filter list.
      */
     public DefaultIoFilterChainBuilder() {
-        init();
-    }
-
-    private void init() {
         entries = new CopyOnWriteArrayList<Entry>();
-        entriesByName = new HashMap<String, Entry>();
     }
 
     /**
      * @see IoFilterChain#getEntry(String)
      */
-    public synchronized Entry getEntry(String name) {
-        return entriesByName.get(name);
+    public Entry getEntry(String name) {
+        for (Entry e: entries) {
+            if (e.getName().equals(name)) {
+                return e;
+            }
+        }
+        
+        return null;
     }
 
     /**
      * @see IoFilterChain#get(String)
      */
-    public synchronized IoFilter get(String name) {
+    public IoFilter get(String name) {
         Entry e = getEntry(name);
         if (e == null) {
             return null;
@@ -177,8 +174,6 @@
             IoFilter filter) {
         checkBaseName(baseName);
 
-        List<Entry> entries = new ArrayList<Entry>(this.entries);
-
         for (ListIterator<Entry> i = entries.listIterator(); i.hasNext();) {
             Entry base = i.next();
             if (base.getName().equals(baseName)) {
@@ -199,7 +194,7 @@
         for (ListIterator<Entry> i = entries.listIterator(); i.hasNext();) {
             Entry e = i.next();
             if (e.getName().equals(name)) {
-                deregister(i.previousIndex(), e);
+                entries.remove(i.previousIndex());
                 return e.getFilter();
             }
         }
@@ -207,6 +202,44 @@
         throw new IllegalArgumentException("Unknown filter name: " + name);
     }
 
+    /**
+     * @see IoFilterChain#remove(IoFilter)
+     */
+    public synchronized IoFilter remove(IoFilter filter) {
+        if (filter == null) {
+            throw new NullPointerException("filter");
+        }
+
+        for (ListIterator<Entry> i = entries.listIterator(); i.hasNext();) {
+            Entry e = i.next();
+            if (e.getFilter() == filter) {
+                entries.remove(i.previousIndex());
+                return e.getFilter();
+            }
+        }
+
+        throw new IllegalArgumentException("Filter not found: " + 
filter.getClass().getName());
+    }
+
+    /**
+     * @see IoFilterChain#remove(Class)
+     */
+    public synchronized IoFilter remove(Class<? extends IoFilter> filterType) {
+        if (filterType == null) {
+            throw new NullPointerException("filterType");
+        }
+
+        for (ListIterator<Entry> i = entries.listIterator(); i.hasNext();) {
+            Entry e = i.next();
+            if (filterType.isAssignableFrom(e.getFilter().getClass())) {
+                entries.remove(i.previousIndex());
+                return e.getFilter();
+            }
+        }
+
+        throw new IllegalArgumentException("Filter not found: " + 
filterType.getName());
+    }
+
     public synchronized IoFilter replace(String name, IoFilter newFilter) {
         checkBaseName(name);
         EntryImpl e = (EntryImpl) get(name);
@@ -242,8 +275,7 @@
      * @see IoFilterChain#clear()
      */
     public synchronized void clear() throws Exception {
-        entries = new ArrayList<Entry>();
-        entriesByName.clear();
+        entries.clear();
     }
 
     public void buildFilterChain(IoFilterChain chain) throws Exception {
@@ -284,15 +316,7 @@
 
     @Override
     public Object clone() {
-        DefaultIoFilterChainBuilder ret;
-        try {
-            ret = (DefaultIoFilterChainBuilder) super.clone();
-        } catch (CloneNotSupportedException e) {
-            throw (InternalError) new InternalError().initCause(e);
-        }
-
-        ret.init();
-
+        DefaultIoFilterChainBuilder ret = new DefaultIoFilterChainBuilder();
         for (Entry e : entries) {
             ret.addLast(e.getName(), e.getFilter());
         }
@@ -303,35 +327,25 @@
         if (baseName == null) {
             throw new NullPointerException("baseName");
         }
-        if (!entriesByName.containsKey(baseName)) {
+        
+        if (!contains(baseName)) {
             throw new IllegalArgumentException("Unknown filter name: "
                     + baseName);
         }
     }
 
     private void register(int index, Entry e) {
-        if (entriesByName.containsKey(e.getName())) {
+        if (contains(e.getName())) {
             throw new IllegalArgumentException(
                     "Other filter is using the same name: " + e.getName());
         }
 
-        List<Entry> newEntries = new ArrayList<Entry>(entries);
-        newEntries.add(index, e);
-        this.entries = newEntries;
-        entriesByName.put(e.getName(), e);
-    }
-
-    private void deregister(int index, Entry e) {
-        List<Entry> newEntries = new ArrayList<Entry>(entries);
-        newEntries.remove(index);
-        this.entries = newEntries;
-        entriesByName.remove(e.getName());
+        entries.add(index, e);
     }
 
     private static class EntryImpl implements Entry {
         private final String name;
-
-        private IoFilter filter;
+        private volatile IoFilter filter;
 
         private EntryImpl(String name, IoFilter filter) {
             if (name == null) {

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/common/IoFilterChain.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/IoFilterChain.java?view=diff&rev=562335&r1=562334&r2=562335
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/IoFilterChain.java 
(original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/IoFilterChain.java Thu 
Aug  2 22:28:02 2007
@@ -142,7 +142,7 @@
      * 
      * @throws IllegalArgumentException if there's no such filter
      */
-    void replace(Class<? extends IoFilter> oldFilterType, IoFilter newFilter);
+    IoFilter replace(Class<? extends IoFilter> oldFilterType, IoFilter 
newFilter);
 
     /**
      * Removes the filter with the specified name from this chain.
@@ -151,6 +151,23 @@
      *             [EMAIL PROTECTED] IoFilter#destroy()} throws an exception.
      */
     IoFilter remove(String name);
+
+    /**
+     * Replace the filter with the specified name with the specified new
+     * filter.
+     * 
+     * @throws IllegalArgumentException if there's no such filter
+     */
+    void remove(IoFilter filter);
+
+    /**
+     * Replace the filter of the specified type with the specified new
+     * filter.  If there's more than one filter with the specified type,
+     * the first match will be replaced.
+     * 
+     * @throws IllegalArgumentException if there's no such filter
+     */
+    IoFilter remove(Class<? extends IoFilter> filterType);
 
     /**
      * Removes all filters added to this chain.

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java?view=diff&rev=562335&r1=562334&r2=562335
==============================================================================
--- 
mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
 (original)
+++ 
mina/trunk/core/src/main/java/org/apache/mina/common/support/AbstractIoFilterChain.java
 Thu Aug  2 22:28:02 2007
@@ -139,6 +139,33 @@
         return entry.getFilter();
     }
 
+    public synchronized void remove(IoFilter filter) {
+        EntryImpl e = head.nextEntry;
+        while (e != tail) {
+            if (e.getFilter() == filter) {
+                deregister(e);
+                return;
+            }
+            e = e.nextEntry;
+        }
+        throw new IllegalArgumentException("Filter not found: "
+                + filter.getClass().getName());
+    }
+
+    public synchronized IoFilter remove(Class<? extends IoFilter> filterType) {
+        EntryImpl e = head.nextEntry;
+        while (e != tail) {
+            if (filterType.isAssignableFrom(e.getFilter().getClass())) {
+                IoFilter oldFilter = e.getFilter();
+                deregister(e);
+                return oldFilter;
+            }
+            e = e.nextEntry;
+        }
+        throw new IllegalArgumentException("Filter not found: "
+                + filterType.getName());
+    }
+
     public synchronized IoFilter replace(String name, IoFilter newFilter) {
         EntryImpl entry = checkOldName(name);
         IoFilter oldFilter = entry.getFilter();
@@ -159,13 +186,14 @@
                 + oldFilter.getClass().getName());
     }
 
-    public synchronized void replace(Class<? extends IoFilter> oldFilterType,
+    public synchronized IoFilter replace(Class<? extends IoFilter> 
oldFilterType,
             IoFilter newFilter) {
         EntryImpl e = head.nextEntry;
         while (e != tail) {
             if (oldFilterType.isAssignableFrom(e.getFilter().getClass())) {
+                IoFilter oldFilter = e.getFilter();
                 e.setFilter(newFilter);
-                return;
+                return oldFilter;
             }
             e = e.nextEntry;
         }


Reply via email to