1 /* 2 * Copyright 2012 The Netty Project 3 * 4 * The Netty Project licenses this file to you under the Apache License, 5 * version 2.0 (the "License"); you may not use this file except in compliance 6 * with the License. You may obtain a copy of the License at: 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations 14 * under the License. 15 */ 16 package org.jboss.netty.handler.execution; 17 18 19 import java.util.concurrent.Executor; 20 21 import org.jboss.netty.util.ExternalResourceReleasable; 22 import org.jboss.netty.util.internal.ExecutorUtil; 23 24 /** 25 * A special {@link Executor} which allows to chain a series of 26 * {@link Executor}s and {@link ChannelEventRunnableFilter}. 27 */ 28 public class ChainedExecutor implements Executor, ExternalResourceReleasable { 29 30 private final Executor cur; 31 private final Executor next; 32 private final ChannelEventRunnableFilter filter; 33 34 /** 35 * Create a new {@link ChainedExecutor} which will used the given 36 * {@link ChannelEventRunnableFilter} to see if the {@link #cur} {@link Executor} should get 37 * used. Otherwise it will pass the work to the {@link #next} {@link Executor} 38 * 39 * @param filter the {@link ChannelEventRunnableFilter} which will be used to check if the 40 * {@link ChannelEventRunnable} should be passed to the cur or next {@link Executor} 41 * @param cur the {@link Executor} to use if the {@link ChannelEventRunnableFilter} match 42 * @param next the {@link Executor} to use if the {@link ChannelEventRunnableFilter} does not match 43 */ 44 public ChainedExecutor(ChannelEventRunnableFilter filter, Executor cur, Executor next) { 45 if (filter == null) { 46 throw new NullPointerException("filter"); 47 } 48 if (cur == null) { 49 throw new NullPointerException("cur"); 50 } 51 if (next == null) { 52 throw new NullPointerException("next"); 53 } 54 55 this.filter = filter; 56 this.cur = cur; 57 this.next = next; 58 } 59 60 /** 61 * Execute the passed {@link ChannelEventRunnable} with the current {@link Executor} if the 62 * {@link ChannelEventRunnableFilter} match. Otherwise pass it to the next {@link Executor} in 63 * the chain. 64 */ 65 public void execute(Runnable command) { 66 assert command instanceof ChannelEventRunnable; 67 if (filter.filter((ChannelEventRunnable) command)) { 68 cur.execute(command); 69 } else { 70 next.execute(command); 71 } 72 } 73 74 public void releaseExternalResources() { 75 ExecutorUtil.terminate(cur, next); 76 releaseExternal(cur); 77 releaseExternal(next); 78 } 79 80 81 private static void releaseExternal(Executor executor) { 82 if (executor instanceof ExternalResourceReleasable) { 83 ((ExternalResourceReleasable) executor).releaseExternalResources(); 84 } 85 } 86 }