Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.mina.handler.chain;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.mina.core.session.IoSession;
/**
* A chain of {@link IoHandlerCommand}s.
*
* @author Apache MINA Project
*/
public class IoHandlerChain implements IoHandlerCommand {
private static volatile int nextId = 0;
private final int id = nextId++;
private final String NEXT_COMMAND = IoHandlerChain.class.getName() + '.' + id + ".nextCommand";
private final Map name2entry = new ConcurrentHashMap<>();
/** The head of the IoHandlerCommand chain */
private final Entry head;
/** THe tail of the IoHandlerCommand chain */
private final Entry tail;
/**
* Creates a new, empty chain of {@link IoHandlerCommand}s.
*/
public IoHandlerChain() {
head = new Entry(null, null, "head", createHeadCommand());
tail = new Entry(head, null, "tail", createTailCommand());
head.nextEntry = tail;
}
private IoHandlerCommand createHeadCommand() {
return new IoHandlerCommand() {
/**
* {@inheritDoc}
*/
@Override
public void execute(NextCommand next, IoSession session, Object message) throws Exception {
next.execute(session, message);
}
};
}
private IoHandlerCommand createTailCommand() {
return new IoHandlerCommand() {
/**
* {@inheritDoc}
*/
@Override
public void execute(NextCommand next, IoSession session, Object message) throws Exception {
next = (NextCommand) session.getAttribute(NEXT_COMMAND);
if (next != null) {
next.execute(session, message);
}
}
};
}
/**
* Retrieve a name-command pair by its name
* @param name The name of the {@link IoHandlerCommand} we are looking for
* @return The associated name-command pair, if any, null otherwise
*/
public Entry getEntry(String name) {
Entry e = name2entry.get(name);
if (e == null) {
return null;
}
return e;
}
/**
* Retrieve a {@link IoHandlerCommand} by its name
*
* @param name The name of the {@link IoHandlerCommand} we are looking for
* @return The associated {@link IoHandlerCommand}, if any, null otherwise
*/
public IoHandlerCommand get(String name) {
Entry e = getEntry(name);
if (e == null) {
return null;
}
return e.getCommand();
}
/**
* Retrieve the {@link IoHandlerCommand} following the {@link IoHandlerCommand} we
* fetched by its name
*
* @param name The name of the {@link IoHandlerCommand}
* @return The {@link IoHandlerCommand} which is next to teh ngiven name, if any, null otherwise
*/
public NextCommand getNextCommand(String name) {
Entry e = getEntry(name);
if (e == null) {
return null;
}
return e.getNextCommand();
}
/**
* Adds a name-command pair into the chain
*
* @param name The name
* @param command The command
*/
public synchronized void addFirst(String name, IoHandlerCommand command) {
checkAddable(name);
register(head, name, command);
}
/**
* Adds a name-command at the end of the chain
*
* @param name The name
* @param command The command
*/
public synchronized void addLast(String name, IoHandlerCommand command) {
checkAddable(name);
register(tail.prevEntry, name, command);
}
/**
* Adds a name-command before a given name-command in the chain
*
* @param baseName The {@linkplain IoHandlerCommand} name before which we will inject a new name-command
* @param name The name The name
* @param command The command The command
*/
public synchronized void addBefore(String baseName, String name, IoHandlerCommand command) {
Entry baseEntry = checkOldName(baseName);
checkAddable(name);
register(baseEntry.prevEntry, name, command);
}
/**
* Adds a name-command after a given name-command in the chain
*
* @param baseName The {@link IoHandlerCommand} name after which we will inject a new name-command
* @param name The name The name
* @param command The command The command
*/
public synchronized void addAfter(String baseName, String name, IoHandlerCommand command) {
Entry baseEntry = checkOldName(baseName);
checkAddable(name);
register(baseEntry, name, command);
}
/**
* Removes a {@link IoHandlerCommand} by its name
*
* @param name The name
* @return The removed {@link IoHandlerCommand}
*/
public synchronized IoHandlerCommand remove(String name) {
Entry entry = checkOldName(name);
deregister(entry);
return entry.getCommand();
}
/**
* Remove all the {@link IoHandlerCommand} from the chain
* @throws Exception If we faced some exception during the cleanup
*/
public synchronized void clear() throws Exception {
Iterator it = new ArrayList(name2entry.keySet()).iterator();
while (it.hasNext()) {
remove(it.next());
}
}
private void register(Entry prevEntry, String name, IoHandlerCommand command) {
Entry newEntry = new Entry(prevEntry, prevEntry.nextEntry, name, command);
prevEntry.nextEntry.prevEntry = newEntry;
prevEntry.nextEntry = newEntry;
name2entry.put(name, newEntry);
}
private void deregister(Entry entry) {
Entry prevEntry = entry.prevEntry;
Entry nextEntry = entry.nextEntry;
prevEntry.nextEntry = nextEntry;
nextEntry.prevEntry = prevEntry;
name2entry.remove(entry.name);
}
/**
* Throws an exception when the specified filter name is not registered in this chain.
*
* @return An filter entry with the specified name.
*/
private Entry checkOldName(String baseName) {
Entry e = name2entry.get(baseName);
if (e == null) {
throw new IllegalArgumentException("Unknown filter name:" + baseName);
}
return e;
}
/**
* Checks the specified filter name is already taken and throws an exception if already taken.
*/
private void checkAddable(String name) {
if (name2entry.containsKey(name)) {
throw new IllegalArgumentException("Other filter is using the same name '" + name + "'");
}
}
/**
* {@inheritDoc}
*/
@Override
public void execute(NextCommand next, IoSession session, Object message) throws Exception {
if (next != null) {
session.setAttribute(NEXT_COMMAND, next);
}
try {
callNextCommand(head, session, message);
} finally {
session.removeAttribute(NEXT_COMMAND);
}
}
private void callNextCommand(Entry entry, IoSession session, Object message) throws Exception {
entry.getCommand().execute(entry.getNextCommand(), session, message);
}
/**
* @return The list of name-commands registered into the chain
*/
public List getAll() {
List list = new ArrayList<>();
Entry e = head.nextEntry;
while (e != tail) {
list.add(e);
e = e.nextEntry;
}
return list;
}
/**
* @return A reverted list of the registered name-commands
*/
public List getAllReversed() {
List list = new ArrayList<>();
Entry e = tail.prevEntry;
while (e != head) {
list.add(e);
e = e.prevEntry;
}
return list;
}
/**
* Checks if the chain of {@link IoHandlerCommand} contains a {@link IoHandlerCommand} by its name
*
* @param name The {@link IoHandlerCommand} name
* @return TRUE if the {@link IoHandlerCommand} is found in the chain
*/
public boolean contains(String name) {
return getEntry(name) != null;
}
/**
* Checks if the chain of {@link IoHandlerCommand} contains a specific {@link IoHandlerCommand}
*
* @param command The {@link IoHandlerCommand} we are looking for
* @return TRUE if the {@link IoHandlerCommand} is found in the chain
*/
public boolean contains(IoHandlerCommand command) {
Entry e = head.nextEntry;
while (e != tail) {
if (e.getCommand() == command) {
return true;
}
e = e.nextEntry;
}
return false;
}
/**
* Checks if the chain of {@link IoHandlerCommand} contains a specific {@link IoHandlerCommand}
*
* @param commandType The type of {@link IoHandlerCommand} we are looking for
* @return TRUE if the {@link IoHandlerCommand} is found in the chain
*/
public boolean contains(Class commandType) {
Entry e = head.nextEntry;
while (e != tail) {
if (commandType.isAssignableFrom(e.getCommand().getClass())) {
return true;
}
e = e.nextEntry;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("{ ");
boolean empty = true;
Entry e = head.nextEntry;
while (e != tail) {
if (!empty) {
buf.append(", ");
} else {
empty = false;
}
buf.append('(');
buf.append(e.getName());
buf.append(':');
buf.append(e.getCommand());
buf.append(')');
e = e.nextEntry;
}
if (empty) {
buf.append("empty");
}
buf.append(" }");
return buf.toString();
}
/**
* Represents a name-command pair that an {@link IoHandlerChain} contains.
*
* @author Apache MINA Project
*/
public class Entry {
private Entry prevEntry;
private Entry nextEntry;
private final String name;
private final IoHandlerCommand command;
private final NextCommand nextCommand;
private Entry(Entry prevEntry, Entry nextEntry, String name, IoHandlerCommand command) {
if (command == null) {
throw new IllegalArgumentException("command");
}
if (name == null) {
throw new IllegalArgumentException("name");
}
this.prevEntry = prevEntry;
this.nextEntry = nextEntry;
this.name = name;
this.command = command;
this.nextCommand = new NextCommand() {
/**
* {@inheritDoc}
*/
@Override
public void execute(IoSession session, Object message) throws Exception {
callNextCommand(Entry.this.nextEntry, session, message);
}
};
}
/**
* @return the name of the command.
*/
public String getName() {
return name;
}
/**
* @return the command.
*/
public IoHandlerCommand getCommand() {
return command;
}
/**
* @return the {@link IoHandlerCommand.NextCommand} of the command.
*/
public NextCommand getNextCommand() {
return nextCommand;
}
}
}