一、前言
基于minal-core(2.0.4)定义及实现的过滤器的设计实现源码的分解,如下图所示,我们从过滤器的实现源码分析主要有IoFilterChainBuilder、DefaultIoFilterChainBuilder、IoFilterChain、IoFilter、DefaultIoFilterChain及IoFilterAdapter等。
二、源码说明
1.IoFilterChainBuilder接口
package org.apache.mina.core.filterchain;@b@@b@public abstract interface IoFilterChainBuilder@b@{@b@ public static final IoFilterChainBuilder NOOP = new IoFilterChainBuilder()@b@ {@b@ public void buildFilterChain(IoFilterChain chain) throws Exception {@b@ }@b@@b@ public String toString() {@b@ return "NOOP";@b@ }@b@ };@b@@b@ public abstract void buildFilterChain(IoFilterChain paramIoFilterChain)@b@ throws Exception;@b@}
2.DefaultIoFilterChainBuilder实现类
package org.apache.mina.core.filterchain;@b@@b@import java.util.ArrayList;@b@import java.util.Collections;@b@import java.util.Iterator;@b@import java.util.LinkedHashMap;@b@import java.util.List;@b@import java.util.ListIterator;@b@import java.util.Map;@b@import java.util.Map.Entry;@b@import java.util.Random;@b@import java.util.Set;@b@import java.util.concurrent.CopyOnWriteArrayList;@b@import org.slf4j.Logger;@b@import org.slf4j.LoggerFactory;@b@@b@public class DefaultIoFilterChainBuilder@b@ implements IoFilterChainBuilder@b@{@b@ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultIoFilterChainBuilder.class);@b@ private final List<IoFilterChain.Entry> entries;@b@@b@ public DefaultIoFilterChainBuilder()@b@ {@b@ this.entries = new CopyOnWriteArrayList();@b@ }@b@@b@ public DefaultIoFilterChainBuilder(DefaultIoFilterChainBuilder filterChain)@b@ {@b@ if (filterChain == null)@b@ throw new IllegalArgumentException("filterChain");@b@@b@ this.entries = new CopyOnWriteArrayList(filterChain.entries);@b@ }@b@@b@ public IoFilterChain.Entry getEntry(String name)@b@ {@b@ for (IoFilterChain.Entry e : this.entries) {@b@ if (e.getName().equals(name))@b@ return e;@b@@b@ }@b@@b@ return null;@b@ }@b@@b@ public IoFilterChain.Entry getEntry(IoFilter filter)@b@ {@b@ for (IoFilterChain.Entry e : this.entries) {@b@ if (e.getFilter() == filter)@b@ return e;@b@@b@ }@b@@b@ return null;@b@ }@b@@b@ public IoFilterChain.Entry getEntry(Class<? extends IoFilter> filterType)@b@ {@b@ for (IoFilterChain.Entry e : this.entries) {@b@ if (filterType.isAssignableFrom(e.getFilter().getClass()))@b@ return e;@b@@b@ }@b@@b@ return null;@b@ }@b@@b@ public IoFilter get(String name)@b@ {@b@ IoFilterChain.Entry e = getEntry(name);@b@ if (e == null) {@b@ return null;@b@ }@b@@b@ return e.getFilter();@b@ }@b@@b@ public IoFilter get(Class<? extends IoFilter> filterType)@b@ {@b@ IoFilterChain.Entry e = getEntry(filterType);@b@ if (e == null) {@b@ return null;@b@ }@b@@b@ return e.getFilter();@b@ }@b@@b@ public List<IoFilterChain.Entry> getAll()@b@ {@b@ return new ArrayList(this.entries);@b@ }@b@@b@ public List<IoFilterChain.Entry> getAllReversed()@b@ {@b@ List result = getAll();@b@ Collections.reverse(result);@b@ return result;@b@ }@b@@b@ public boolean contains(String name)@b@ {@b@ return (getEntry(name) != null);@b@ }@b@@b@ public boolean contains(IoFilter filter)@b@ {@b@ return (getEntry(filter) != null);@b@ }@b@@b@ public boolean contains(Class<? extends IoFilter> filterType)@b@ {@b@ return (getEntry(filterType) != null);@b@ }@b@@b@ public synchronized void addFirst(String name, IoFilter filter)@b@ {@b@ register(0, new EntryImpl(this, name, filter, null));@b@ }@b@@b@ public synchronized void addLast(String name, IoFilter filter)@b@ {@b@ register(this.entries.size(), new EntryImpl(this, name, filter, null));@b@ }@b@@b@ public synchronized void addBefore(String baseName, String name, IoFilter filter)@b@ {@b@ checkBaseName(baseName);@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry base = (IoFilterChain.Entry)i.next();@b@ if (base.getName().equals(baseName)) {@b@ register(i.previousIndex(), new EntryImpl(this, name, filter, null));@b@ return;@b@ }@b@ }@b@ }@b@@b@ public synchronized void addAfter(String baseName, String name, IoFilter filter)@b@ {@b@ checkBaseName(baseName);@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry base = (IoFilterChain.Entry)i.next();@b@ if (base.getName().equals(baseName)) {@b@ register(i.nextIndex(), new EntryImpl(this, name, filter, null));@b@ return;@b@ }@b@ }@b@ }@b@@b@ public synchronized IoFilter remove(String name)@b@ {@b@ if (name == null) {@b@ throw new IllegalArgumentException("name");@b@ }@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry e = (IoFilterChain.Entry)i.next();@b@ if (e.getName().equals(name)) {@b@ this.entries.remove(i.previousIndex());@b@ return e.getFilter();@b@ }@b@ }@b@@b@ throw new IllegalArgumentException("Unknown filter name: " + name);@b@ }@b@@b@ public synchronized IoFilter remove(IoFilter filter)@b@ {@b@ if (filter == null) {@b@ throw new IllegalArgumentException("filter");@b@ }@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry e = (IoFilterChain.Entry)i.next();@b@ if (e.getFilter() == filter) {@b@ this.entries.remove(i.previousIndex());@b@ return e.getFilter();@b@ }@b@ }@b@@b@ throw new IllegalArgumentException("Filter not found: " + filter.getClass().getName());@b@ }@b@@b@ public synchronized IoFilter remove(Class<? extends IoFilter> filterType)@b@ {@b@ if (filterType == null) {@b@ throw new IllegalArgumentException("filterType");@b@ }@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry e = (IoFilterChain.Entry)i.next();@b@ if (filterType.isAssignableFrom(e.getFilter().getClass())) {@b@ this.entries.remove(i.previousIndex());@b@ return e.getFilter();@b@ }@b@ }@b@@b@ throw new IllegalArgumentException("Filter not found: " + filterType.getName());@b@ }@b@@b@ public synchronized IoFilter replace(String name, IoFilter newFilter) {@b@ checkBaseName(name);@b@ EntryImpl e = (EntryImpl)getEntry(name);@b@ IoFilter oldFilter = e.getFilter();@b@ EntryImpl.access$100(e, newFilter);@b@ return oldFilter;@b@ }@b@@b@ public synchronized void replace(IoFilter oldFilter, IoFilter newFilter) {@b@ for (IoFilterChain.Entry e : this.entries)@b@ if (e.getFilter() == oldFilter) {@b@ EntryImpl.access$100((EntryImpl)e, newFilter);@b@ return;@b@ }@b@@b@ throw new IllegalArgumentException("Filter not found: " + oldFilter.getClass().getName());@b@ }@b@@b@ public synchronized void replace(Class<? extends IoFilter> oldFilterType, IoFilter newFilter)@b@ {@b@ for (IoFilterChain.Entry e : this.entries)@b@ if (oldFilterType.isAssignableFrom(e.getFilter().getClass())) {@b@ EntryImpl.access$100((EntryImpl)e, newFilter);@b@ return;@b@ }@b@@b@ throw new IllegalArgumentException("Filter not found: " + oldFilterType.getName());@b@ }@b@@b@ public synchronized void clear()@b@ {@b@ this.entries.clear();@b@ }@b@@b@ public void setFilters(Map<String, ? extends IoFilter> filters)@b@ {@b@ if (filters == null) {@b@ throw new IllegalArgumentException("filters");@b@ }@b@@b@ if (!(isOrderedMap(filters))) {@b@ throw new IllegalArgumentException("filters is not an ordered map. Please try " + LinkedHashMap.class.getName() + ".");@b@ }@b@@b@ filters = new LinkedHashMap(filters);@b@ for (??? = filters.entrySet().iterator(); ???.hasNext(); ) { Map.Entry e = (Map.Entry)???.next();@b@ if (e.getKey() == null)@b@ throw new IllegalArgumentException("filters contains a null key.");@b@@b@ if (e.getValue() == null)@b@ throw new IllegalArgumentException("filters contains a null value.");@b@@b@ }@b@@b@ synchronized (this) {@b@ clear();@b@ for (Map.Entry e : filters.entrySet())@b@ addLast((String)e.getKey(), (IoFilter)e.getValue());@b@ }@b@ }@b@@b@ private boolean isOrderedMap(Map map)@b@ {@b@ Map newMap;@b@ Class mapType = map.getClass();@b@ if (LinkedHashMap.class.isAssignableFrom(mapType)) {@b@ if (LOGGER.isDebugEnabled())@b@ LOGGER.debug(mapType.getSimpleName() + " is an ordered map.");@b@@b@ return true;@b@ }@b@@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug(mapType.getName() + " is not a " + LinkedHashMap.class.getSimpleName());@b@ }@b@@b@ Class type = mapType;@b@ while (type != null) {@b@ Class[] arr$ = type.getInterfaces(); int len$ = arr$.length; for (int i$ = 0; i$ < len$; ++i$) { Class i = arr$[i$];@b@ if (i.getName().endsWith("OrderedMap")) {@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug(mapType.getSimpleName() + " is an ordered map (guessed from that it " + " implements OrderedMap interface.)");@b@ }@b@@b@ return true;@b@ }@b@ }@b@ type = type.getSuperclass();@b@ }@b@@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug(mapType.getName() + " doesn't implement OrderedMap interface.");@b@ }@b@@b@ LOGGER.debug("Last resort; trying to create a new map instance with a default constructor and test if insertion order is maintained.");@b@ try@b@ {@b@ newMap = (Map)mapType.newInstance();@b@ } catch (Exception e) {@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug("Failed to create a new map instance of '" + mapType.getName() + "'.", e);@b@ }@b@@b@ return false;@b@ }@b@@b@ Random rand = new Random();@b@ List expectedNames = new ArrayList();@b@ IoFilter dummyFilter = new IoFilterAdapter();@b@ for (int i = 0; i < 65536; ++i) {@b@ String filterName;@b@ do@b@ filterName = String.valueOf(rand.nextInt());@b@ while (newMap.containsKey(filterName));@b@@b@ newMap.put(filterName, dummyFilter);@b@ expectedNames.add(filterName);@b@@b@ Iterator it = expectedNames.iterator();@b@ for (Iterator i$ = newMap.keySet().iterator(); i$.hasNext(); ) { Object key = i$.next();@b@ if (!(((String)it.next()).equals(key))) {@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug("The specified map didn't pass the insertion order test after " + (i + 1) + " tries.");@b@ }@b@@b@ return false;@b@ }@b@ }@b@ }@b@@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug("The specified map passed the insertion order test.");@b@ }@b@@b@ return true;@b@ }@b@@b@ public void buildFilterChain(IoFilterChain chain) throws Exception {@b@ for (IoFilterChain.Entry e : this.entries)@b@ chain.addLast(e.getName(), e.getFilter());@b@ }@b@@b@ public String toString()@b@ {@b@ StringBuilder buf = new StringBuilder();@b@ buf.append("{ ");@b@@b@ boolean empty = true;@b@@b@ for (IoFilterChain.Entry e : this.entries) {@b@ if (!(empty))@b@ buf.append(", ");@b@ else {@b@ empty = false;@b@ }@b@@b@ buf.append('(');@b@ buf.append(e.getName());@b@ buf.append(':');@b@ buf.append(e.getFilter());@b@ buf.append(')');@b@ }@b@@b@ if (empty) {@b@ buf.append("empty");@b@ }@b@@b@ buf.append(" }");@b@@b@ return buf.toString();@b@ }@b@@b@ private void checkBaseName(String baseName) {@b@ if (baseName == null) {@b@ throw new IllegalArgumentException("baseName");@b@ }@b@@b@ if (!(contains(baseName)))@b@ throw new IllegalArgumentException("Unknown filter name: " + baseName);@b@ }@b@@b@ private void register(int index, IoFilterChain.Entry e)@b@ {@b@ if (contains(e.getName())) {@b@ throw new IllegalArgumentException("Other filter is using the same name: " + e.getName());@b@ }@b@@b@ this.entries.add(index, e);@b@ }@b@@b@ private class EntryImpl implements IoFilterChain.Entry {@b@ private final String name;@b@ private volatile IoFilter filter;@b@@b@ private EntryImpl(, String paramString, IoFilter paramIoFilter) {@b@ if (paramString == null)@b@ throw new IllegalArgumentException("name");@b@@b@ if (paramIoFilter == null) {@b@ throw new IllegalArgumentException("filter");@b@ }@b@@b@ this.name = paramString;@b@ this.filter = paramIoFilter;@b@ }@b@@b@ public String getName() {@b@ return this.name;@b@ }@b@@b@ public IoFilter getFilter() {@b@ return this.filter;@b@ }@b@@b@ private void setFilter() {@b@ this.filter = filter;@b@ }@b@@b@ public IoFilter.NextFilter getNextFilter() {@b@ throw new IllegalStateException();@b@ }@b@@b@ public String toString()@b@ {@b@ return "(" + getName() + ':' + this.filter + ')';@b@ }@b@@b@ public void addAfter(, IoFilter filter) {@b@ this.this$0.addAfter(getName(), name, filter);@b@ }@b@@b@ public void addBefore(, IoFilter filter) {@b@ this.this$0.addBefore(getName(), name, filter);@b@ }@b@@b@ public void remove() {@b@ this.this$0.remove(getName());@b@ }@b@@b@ public void replace() {@b@ this.this$0.replace(getName(), newFilter);@b@ }@b@ }@b@}
3.IoFilterChain接口类
package org.apache.mina.core.filterchain;@b@@b@import java.util.List;@b@import org.apache.mina.core.session.IdleStatus;@b@import org.apache.mina.core.session.IoSession;@b@import org.apache.mina.core.write.WriteRequest;@b@@b@public abstract interface IoFilterChain@b@{@b@ public abstract IoSession getSession();@b@@b@ public abstract Entry getEntry(String paramString);@b@@b@ public abstract Entry getEntry(IoFilter paramIoFilter);@b@@b@ public abstract Entry getEntry(Class<? extends IoFilter> paramClass);@b@@b@ public abstract IoFilter get(String paramString);@b@@b@ public abstract IoFilter get(Class<? extends IoFilter> paramClass);@b@@b@ public abstract IoFilter.NextFilter getNextFilter(String paramString);@b@@b@ public abstract IoFilter.NextFilter getNextFilter(IoFilter paramIoFilter);@b@@b@ public abstract IoFilter.NextFilter getNextFilter(Class<? extends IoFilter> paramClass);@b@@b@ public abstract List<Entry> getAll();@b@@b@ public abstract List<Entry> getAllReversed();@b@@b@ public abstract boolean contains(String paramString);@b@@b@ public abstract boolean contains(IoFilter paramIoFilter);@b@@b@ public abstract boolean contains(Class<? extends IoFilter> paramClass);@b@@b@ public abstract void addFirst(String paramString, IoFilter paramIoFilter);@b@@b@ public abstract void addLast(String paramString, IoFilter paramIoFilter);@b@@b@ public abstract void addBefore(String paramString1, String paramString2, IoFilter paramIoFilter);@b@@b@ public abstract void addAfter(String paramString1, String paramString2, IoFilter paramIoFilter);@b@@b@ public abstract IoFilter replace(String paramString, IoFilter paramIoFilter);@b@@b@ public abstract void replace(IoFilter paramIoFilter1, IoFilter paramIoFilter2);@b@@b@ public abstract IoFilter replace(Class<? extends IoFilter> paramClass, IoFilter paramIoFilter);@b@@b@ public abstract IoFilter remove(String paramString);@b@@b@ public abstract void remove(IoFilter paramIoFilter);@b@@b@ public abstract IoFilter remove(Class<? extends IoFilter> paramClass);@b@@b@ public abstract void clear()@b@ throws Exception;@b@@b@ public abstract void fireSessionCreated();@b@@b@ public abstract void fireSessionOpened();@b@@b@ public abstract void fireSessionClosed();@b@@b@ public abstract void fireSessionIdle(IdleStatus paramIdleStatus);@b@@b@ public abstract void fireMessageReceived(Object paramObject);@b@@b@ public abstract void fireMessageSent(WriteRequest paramWriteRequest);@b@@b@ public abstract void fireExceptionCaught(Throwable paramThrowable);@b@@b@ public abstract void fireFilterWrite(WriteRequest paramWriteRequest);@b@@b@ public abstract void fireFilterClose();@b@@b@ public static abstract interface Entry@b@ {@b@ public abstract String getName();@b@@b@ public abstract IoFilter getFilter();@b@@b@ public abstract IoFilter.NextFilter getNextFilter();@b@@b@ public abstract void addBefore(String paramString, IoFilter paramIoFilter);@b@@b@ public abstract void addAfter(String paramString, IoFilter paramIoFilter);@b@@b@ public abstract void replace(IoFilter paramIoFilter);@b@@b@ public abstract void remove();@b@ }@b@}
4.DefaultIoFilterChain实现类
package org.apache.mina.core.filterchain;@b@@b@import java.util.ArrayList;@b@import java.util.Collections;@b@import java.util.Iterator;@b@import java.util.LinkedHashMap;@b@import java.util.List;@b@import java.util.ListIterator;@b@import java.util.Map;@b@import java.util.Map.Entry;@b@import java.util.Random;@b@import java.util.Set;@b@import java.util.concurrent.CopyOnWriteArrayList;@b@import org.slf4j.Logger;@b@import org.slf4j.LoggerFactory;@b@@b@public class DefaultIoFilterChainBuilder@b@ implements IoFilterChainBuilder@b@{@b@ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultIoFilterChainBuilder.class);@b@ private final List<IoFilterChain.Entry> entries;@b@@b@ public DefaultIoFilterChainBuilder()@b@ {@b@ this.entries = new CopyOnWriteArrayList();@b@ }@b@@b@ public DefaultIoFilterChainBuilder(DefaultIoFilterChainBuilder filterChain)@b@ {@b@ if (filterChain == null)@b@ throw new IllegalArgumentException("filterChain");@b@@b@ this.entries = new CopyOnWriteArrayList(filterChain.entries);@b@ }@b@@b@ public IoFilterChain.Entry getEntry(String name)@b@ {@b@ for (IoFilterChain.Entry e : this.entries) {@b@ if (e.getName().equals(name))@b@ return e;@b@@b@ }@b@@b@ return null;@b@ }@b@@b@ public IoFilterChain.Entry getEntry(IoFilter filter)@b@ {@b@ for (IoFilterChain.Entry e : this.entries) {@b@ if (e.getFilter() == filter)@b@ return e;@b@@b@ }@b@@b@ return null;@b@ }@b@@b@ public IoFilterChain.Entry getEntry(Class<? extends IoFilter> filterType)@b@ {@b@ for (IoFilterChain.Entry e : this.entries) {@b@ if (filterType.isAssignableFrom(e.getFilter().getClass()))@b@ return e;@b@@b@ }@b@@b@ return null;@b@ }@b@@b@ public IoFilter get(String name)@b@ {@b@ IoFilterChain.Entry e = getEntry(name);@b@ if (e == null) {@b@ return null;@b@ }@b@@b@ return e.getFilter();@b@ }@b@@b@ public IoFilter get(Class<? extends IoFilter> filterType)@b@ {@b@ IoFilterChain.Entry e = getEntry(filterType);@b@ if (e == null) {@b@ return null;@b@ }@b@@b@ return e.getFilter();@b@ }@b@@b@ public List<IoFilterChain.Entry> getAll()@b@ {@b@ return new ArrayList(this.entries);@b@ }@b@@b@ public List<IoFilterChain.Entry> getAllReversed()@b@ {@b@ List result = getAll();@b@ Collections.reverse(result);@b@ return result;@b@ }@b@@b@ public boolean contains(String name)@b@ {@b@ return (getEntry(name) != null);@b@ }@b@@b@ public boolean contains(IoFilter filter)@b@ {@b@ return (getEntry(filter) != null);@b@ }@b@@b@ public boolean contains(Class<? extends IoFilter> filterType)@b@ {@b@ return (getEntry(filterType) != null);@b@ }@b@@b@ public synchronized void addFirst(String name, IoFilter filter)@b@ {@b@ register(0, new EntryImpl(this, name, filter, null));@b@ }@b@@b@ public synchronized void addLast(String name, IoFilter filter)@b@ {@b@ register(this.entries.size(), new EntryImpl(this, name, filter, null));@b@ }@b@@b@ public synchronized void addBefore(String baseName, String name, IoFilter filter)@b@ {@b@ checkBaseName(baseName);@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry base = (IoFilterChain.Entry)i.next();@b@ if (base.getName().equals(baseName)) {@b@ register(i.previousIndex(), new EntryImpl(this, name, filter, null));@b@ return;@b@ }@b@ }@b@ }@b@@b@ public synchronized void addAfter(String baseName, String name, IoFilter filter)@b@ {@b@ checkBaseName(baseName);@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry base = (IoFilterChain.Entry)i.next();@b@ if (base.getName().equals(baseName)) {@b@ register(i.nextIndex(), new EntryImpl(this, name, filter, null));@b@ return;@b@ }@b@ }@b@ }@b@@b@ public synchronized IoFilter remove(String name)@b@ {@b@ if (name == null) {@b@ throw new IllegalArgumentException("name");@b@ }@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry e = (IoFilterChain.Entry)i.next();@b@ if (e.getName().equals(name)) {@b@ this.entries.remove(i.previousIndex());@b@ return e.getFilter();@b@ }@b@ }@b@@b@ throw new IllegalArgumentException("Unknown filter name: " + name);@b@ }@b@@b@ public synchronized IoFilter remove(IoFilter filter)@b@ {@b@ if (filter == null) {@b@ throw new IllegalArgumentException("filter");@b@ }@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry e = (IoFilterChain.Entry)i.next();@b@ if (e.getFilter() == filter) {@b@ this.entries.remove(i.previousIndex());@b@ return e.getFilter();@b@ }@b@ }@b@@b@ throw new IllegalArgumentException("Filter not found: " + filter.getClass().getName());@b@ }@b@@b@ public synchronized IoFilter remove(Class<? extends IoFilter> filterType)@b@ {@b@ if (filterType == null) {@b@ throw new IllegalArgumentException("filterType");@b@ }@b@@b@ for (ListIterator i = this.entries.listIterator(); i.hasNext(); ) {@b@ IoFilterChain.Entry e = (IoFilterChain.Entry)i.next();@b@ if (filterType.isAssignableFrom(e.getFilter().getClass())) {@b@ this.entries.remove(i.previousIndex());@b@ return e.getFilter();@b@ }@b@ }@b@@b@ throw new IllegalArgumentException("Filter not found: " + filterType.getName());@b@ }@b@@b@ public synchronized IoFilter replace(String name, IoFilter newFilter) {@b@ checkBaseName(name);@b@ EntryImpl e = (EntryImpl)getEntry(name);@b@ IoFilter oldFilter = e.getFilter();@b@ EntryImpl.access$100(e, newFilter);@b@ return oldFilter;@b@ }@b@@b@ public synchronized void replace(IoFilter oldFilter, IoFilter newFilter) {@b@ for (IoFilterChain.Entry e : this.entries)@b@ if (e.getFilter() == oldFilter) {@b@ EntryImpl.access$100((EntryImpl)e, newFilter);@b@ return;@b@ }@b@@b@ throw new IllegalArgumentException("Filter not found: " + oldFilter.getClass().getName());@b@ }@b@@b@ public synchronized void replace(Class<? extends IoFilter> oldFilterType, IoFilter newFilter)@b@ {@b@ for (IoFilterChain.Entry e : this.entries)@b@ if (oldFilterType.isAssignableFrom(e.getFilter().getClass())) {@b@ EntryImpl.access$100((EntryImpl)e, newFilter);@b@ return;@b@ }@b@@b@ throw new IllegalArgumentException("Filter not found: " + oldFilterType.getName());@b@ }@b@@b@ public synchronized void clear()@b@ {@b@ this.entries.clear();@b@ }@b@@b@ public void setFilters(Map<String, ? extends IoFilter> filters)@b@ {@b@ if (filters == null) {@b@ throw new IllegalArgumentException("filters");@b@ }@b@@b@ if (!(isOrderedMap(filters))) {@b@ throw new IllegalArgumentException("filters is not an ordered map. Please try " + LinkedHashMap.class.getName() + ".");@b@ }@b@@b@ filters = new LinkedHashMap(filters);@b@ for (??? = filters.entrySet().iterator(); ???.hasNext(); ) { Map.Entry e = (Map.Entry)???.next();@b@ if (e.getKey() == null)@b@ throw new IllegalArgumentException("filters contains a null key.");@b@@b@ if (e.getValue() == null)@b@ throw new IllegalArgumentException("filters contains a null value.");@b@@b@ }@b@@b@ synchronized (this) {@b@ clear();@b@ for (Map.Entry e : filters.entrySet())@b@ addLast((String)e.getKey(), (IoFilter)e.getValue());@b@ }@b@ }@b@@b@ private boolean isOrderedMap(Map map)@b@ {@b@ Map newMap;@b@ Class mapType = map.getClass();@b@ if (LinkedHashMap.class.isAssignableFrom(mapType)) {@b@ if (LOGGER.isDebugEnabled())@b@ LOGGER.debug(mapType.getSimpleName() + " is an ordered map.");@b@@b@ return true;@b@ }@b@@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug(mapType.getName() + " is not a " + LinkedHashMap.class.getSimpleName());@b@ }@b@@b@ Class type = mapType;@b@ while (type != null) {@b@ Class[] arr$ = type.getInterfaces(); int len$ = arr$.length; for (int i$ = 0; i$ < len$; ++i$) { Class i = arr$[i$];@b@ if (i.getName().endsWith("OrderedMap")) {@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug(mapType.getSimpleName() + " is an ordered map (guessed from that it " + " implements OrderedMap interface.)");@b@ }@b@@b@ return true;@b@ }@b@ }@b@ type = type.getSuperclass();@b@ }@b@@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug(mapType.getName() + " doesn't implement OrderedMap interface.");@b@ }@b@@b@ LOGGER.debug("Last resort; trying to create a new map instance with a default constructor and test if insertion order is maintained.");@b@ try@b@ {@b@ newMap = (Map)mapType.newInstance();@b@ } catch (Exception e) {@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug("Failed to create a new map instance of '" + mapType.getName() + "'.", e);@b@ }@b@@b@ return false;@b@ }@b@@b@ Random rand = new Random();@b@ List expectedNames = new ArrayList();@b@ IoFilter dummyFilter = new IoFilterAdapter();@b@ for (int i = 0; i < 65536; ++i) {@b@ String filterName;@b@ do@b@ filterName = String.valueOf(rand.nextInt());@b@ while (newMap.containsKey(filterName));@b@@b@ newMap.put(filterName, dummyFilter);@b@ expectedNames.add(filterName);@b@@b@ Iterator it = expectedNames.iterator();@b@ for (Iterator i$ = newMap.keySet().iterator(); i$.hasNext(); ) { Object key = i$.next();@b@ if (!(((String)it.next()).equals(key))) {@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug("The specified map didn't pass the insertion order test after " + (i + 1) + " tries.");@b@ }@b@@b@ return false;@b@ }@b@ }@b@ }@b@@b@ if (LOGGER.isDebugEnabled()) {@b@ LOGGER.debug("The specified map passed the insertion order test.");@b@ }@b@@b@ return true;@b@ }@b@@b@ public void buildFilterChain(IoFilterChain chain) throws Exception {@b@ for (IoFilterChain.Entry e : this.entries)@b@ chain.addLast(e.getName(), e.getFilter());@b@ }@b@@b@ public String toString()@b@ {@b@ StringBuilder buf = new StringBuilder();@b@ buf.append("{ ");@b@@b@ boolean empty = true;@b@@b@ for (IoFilterChain.Entry e : this.entries) {@b@ if (!(empty))@b@ buf.append(", ");@b@ else {@b@ empty = false;@b@ }@b@@b@ buf.append('(');@b@ buf.append(e.getName());@b@ buf.append(':');@b@ buf.append(e.getFilter());@b@ buf.append(')');@b@ }@b@@b@ if (empty) {@b@ buf.append("empty");@b@ }@b@@b@ buf.append(" }");@b@@b@ return buf.toString();@b@ }@b@@b@ private void checkBaseName(String baseName) {@b@ if (baseName == null) {@b@ throw new IllegalArgumentException("baseName");@b@ }@b@@b@ if (!(contains(baseName)))@b@ throw new IllegalArgumentException("Unknown filter name: " + baseName);@b@ }@b@@b@ private void register(int index, IoFilterChain.Entry e)@b@ {@b@ if (contains(e.getName())) {@b@ throw new IllegalArgumentException("Other filter is using the same name: " + e.getName());@b@ }@b@@b@ this.entries.add(index, e);@b@ }@b@@b@ private class EntryImpl implements IoFilterChain.Entry {@b@ private final String name;@b@ private volatile IoFilter filter;@b@@b@ private EntryImpl(, String paramString, IoFilter paramIoFilter) {@b@ if (paramString == null)@b@ throw new IllegalArgumentException("name");@b@@b@ if (paramIoFilter == null) {@b@ throw new IllegalArgumentException("filter");@b@ }@b@@b@ this.name = paramString;@b@ this.filter = paramIoFilter;@b@ }@b@@b@ public String getName() {@b@ return this.name;@b@ }@b@@b@ public IoFilter getFilter() {@b@ return this.filter;@b@ }@b@@b@ private void setFilter() {@b@ this.filter = filter;@b@ }@b@@b@ public IoFilter.NextFilter getNextFilter() {@b@ throw new IllegalStateException();@b@ }@b@@b@ public String toString()@b@ {@b@ return "(" + getName() + ':' + this.filter + ')';@b@ }@b@@b@ public void addAfter(, IoFilter filter) {@b@ this.this$0.addAfter(getName(), name, filter);@b@ }@b@@b@ public void addBefore(, IoFilter filter) {@b@ this.this$0.addBefore(getName(), name, filter);@b@ }@b@@b@ public void remove() {@b@ this.this$0.remove(getName());@b@ }@b@@b@ public void replace() {@b@ this.this$0.replace(getName(), newFilter);@b@ }@b@ }@b@}
5.IoFilter过滤接口
package org.apache.mina.core.filterchain;@b@@b@import org.apache.mina.core.session.IdleStatus;@b@import org.apache.mina.core.session.IoSession;@b@import org.apache.mina.core.write.WriteRequest;@b@@b@public abstract interface IoFilter@b@{@b@ public abstract void init()@b@ throws Exception;@b@@b@ public abstract void destroy()@b@ throws Exception;@b@@b@ public abstract void onPreAdd(IoFilterChain paramIoFilterChain, String paramString, NextFilter paramNextFilter)@b@ throws Exception;@b@@b@ public abstract void onPostAdd(IoFilterChain paramIoFilterChain, String paramString, NextFilter paramNextFilter)@b@ throws Exception;@b@@b@ public abstract void onPreRemove(IoFilterChain paramIoFilterChain, String paramString, NextFilter paramNextFilter)@b@ throws Exception;@b@@b@ public abstract void onPostRemove(IoFilterChain paramIoFilterChain, String paramString, NextFilter paramNextFilter)@b@ throws Exception;@b@@b@ public abstract void sessionCreated(NextFilter paramNextFilter, IoSession paramIoSession)@b@ throws Exception;@b@@b@ public abstract void sessionOpened(NextFilter paramNextFilter, IoSession paramIoSession)@b@ throws Exception;@b@@b@ public abstract void sessionClosed(NextFilter paramNextFilter, IoSession paramIoSession)@b@ throws Exception;@b@@b@ public abstract void sessionIdle(NextFilter paramNextFilter, IoSession paramIoSession, IdleStatus paramIdleStatus)@b@ throws Exception;@b@@b@ public abstract void exceptionCaught(NextFilter paramNextFilter, IoSession paramIoSession, Throwable paramThrowable)@b@ throws Exception;@b@@b@ public abstract void messageReceived(NextFilter paramNextFilter, IoSession paramIoSession, Object paramObject)@b@ throws Exception;@b@@b@ public abstract void messageSent(NextFilter paramNextFilter, IoSession paramIoSession, WriteRequest paramWriteRequest)@b@ throws Exception;@b@@b@ public abstract void filterClose(NextFilter paramNextFilter, IoSession paramIoSession)@b@ throws Exception;@b@@b@ public abstract void filterWrite(NextFilter paramNextFilter, IoSession paramIoSession, WriteRequest paramWriteRequest)@b@ throws Exception;@b@@b@ public static abstract interface NextFilter@b@ {@b@ public abstract void sessionCreated(IoSession paramIoSession);@b@@b@ public abstract void sessionOpened(IoSession paramIoSession);@b@@b@ public abstract void sessionClosed(IoSession paramIoSession);@b@@b@ public abstract void sessionIdle(IoSession paramIoSession, IdleStatus paramIdleStatus);@b@@b@ public abstract void exceptionCaught(IoSession paramIoSession, Throwable paramThrowable);@b@@b@ public abstract void messageReceived(IoSession paramIoSession, Object paramObject);@b@@b@ public abstract void messageSent(IoSession paramIoSession, WriteRequest paramWriteRequest);@b@@b@ public abstract void filterWrite(IoSession paramIoSession, WriteRequest paramWriteRequest);@b@@b@ public abstract void filterClose(IoSession paramIoSession);@b@ }@b@}
package org.apache.mina.core.filterchain;@b@@b@import org.apache.mina.core.session.IdleStatus;@b@import org.apache.mina.core.session.IoSession;@b@import org.apache.mina.core.write.WriteRequest;@b@@b@public class IoFilterAdapter@b@ implements IoFilter@b@{@b@ public void init()@b@ throws Exception@b@ {@b@ }@b@@b@ public void destroy()@b@ throws Exception@b@ {@b@ }@b@@b@ public void onPreAdd(IoFilterChain parent, String name, IoFilter.NextFilter nextFilter)@b@ throws Exception@b@ {@b@ }@b@@b@ public void onPostAdd(IoFilterChain parent, String name, IoFilter.NextFilter nextFilter)@b@ throws Exception@b@ {@b@ }@b@@b@ public void onPreRemove(IoFilterChain parent, String name, IoFilter.NextFilter nextFilter)@b@ throws Exception@b@ {@b@ }@b@@b@ public void onPostRemove(IoFilterChain parent, String name, IoFilter.NextFilter nextFilter)@b@ throws Exception@b@ {@b@ }@b@@b@ public void sessionCreated(IoFilter.NextFilter nextFilter, IoSession session)@b@ throws Exception@b@ {@b@ nextFilter.sessionCreated(session);@b@ }@b@@b@ public void sessionOpened(IoFilter.NextFilter nextFilter, IoSession session)@b@ throws Exception@b@ {@b@ nextFilter.sessionOpened(session);@b@ }@b@@b@ public void sessionClosed(IoFilter.NextFilter nextFilter, IoSession session)@b@ throws Exception@b@ {@b@ nextFilter.sessionClosed(session);@b@ }@b@@b@ public void sessionIdle(IoFilter.NextFilter nextFilter, IoSession session, IdleStatus status)@b@ throws Exception@b@ {@b@ nextFilter.sessionIdle(session, status);@b@ }@b@@b@ public void exceptionCaught(IoFilter.NextFilter nextFilter, IoSession session, Throwable cause)@b@ throws Exception@b@ {@b@ nextFilter.exceptionCaught(session, cause);@b@ }@b@@b@ public void messageReceived(IoFilter.NextFilter nextFilter, IoSession session, Object message)@b@ throws Exception@b@ {@b@ nextFilter.messageReceived(session, message);@b@ }@b@@b@ public void messageSent(IoFilter.NextFilter nextFilter, IoSession session, WriteRequest writeRequest)@b@ throws Exception@b@ {@b@ nextFilter.messageSent(session, writeRequest);@b@ }@b@@b@ public void filterWrite(IoFilter.NextFilter nextFilter, IoSession session, WriteRequest writeRequest)@b@ throws Exception@b@ {@b@ nextFilter.filterWrite(session, writeRequest);@b@ }@b@@b@ public void filterClose(IoFilter.NextFilter nextFilter, IoSession session)@b@ throws Exception@b@ {@b@ nextFilter.filterClose(session);@b@ }@b@@b@ public String toString() {@b@ return super.getClass().getSimpleName();@b@ }@b@}