001: /*_############################################################################
002: _##
003: _## SNMP4J-AgentX - AgentXMessageDispatcherImpl.java
004: _##
005: _## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
006: _##
007: _## This program is free software; you can redistribute it and/or modify
008: _## it under the terms of the GNU General Public License version 2 as
009: _## published by the Free Software Foundation.
010: _##
011: _## This program is distributed in the hope that it will be useful,
012: _## but WITHOUT ANY WARRANTY; without even the implied warranty of
013: _## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: _## GNU General Public License for more details.
015: _##
016: _## You should have received a copy of the GNU General Public License
017: _## along with this program; if not, write to the Free Software
018: _## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
019: _## MA 02110-1301 USA
020: _##
021: _##########################################################################*/
022:
023: package org.snmp4j.agent.agentx;
024:
025: import java.nio.*;
026: import java.util.*;
027:
028: import org.snmp4j.*;
029: import org.snmp4j.smi.*;
030: import java.io.IOException;
031: import org.snmp4j.agent.agentx.AgentXPDU;
032: import org.snmp4j.log.LogFactory;
033: import org.snmp4j.log.LogAdapter;
034: import org.snmp4j.mp.PduHandle;
035: import org.snmp4j.mp.PduHandleCallback;
036:
037: public class AgentXMessageDispatcherImpl implements
038: AgentXMessageDispatcher {
039:
040: private static final LogAdapter logger = LogFactory
041: .getLogger(AgentXMessageDispatcherImpl.class);
042:
043: private List transportMappings = new ArrayList();
044: private List commandListener = new ArrayList();
045: private volatile int nextPacketID = 0;
046:
047: public AgentXMessageDispatcherImpl() {
048: }
049:
050: public synchronized int getNextPacketID() {
051: int nextID = ++nextPacketID;
052: if (nextID <= 0) {
053: nextID = nextPacketID = 1;
054: }
055: return nextID;
056: }
057:
058: protected PduHandle createPduHandle() {
059: return new PduHandle(getNextPacketID());
060: }
061:
062: public synchronized void addTransportMapping(
063: TransportMapping transport) {
064: transportMappings.add(transport);
065: transport.addTransportListener(this );
066: }
067:
068: public Collection getTransportMappings() {
069: return new ArrayList(transportMappings);
070: }
071:
072: public void processMessage(TransportMapping sourceTransport,
073: Address incomingAddress, ByteBuffer wholeMessage) {
074: try {
075: AgentXPDU pdu = AgentXPDU.decode(wholeMessage);
076: AgentXCommandEvent event = new AgentXCommandEvent(this ,
077: this , incomingAddress, sourceTransport, pdu);
078: fireCommandEvent(event);
079: } catch (IOException ex) {
080: if (logger.isDebugEnabled()) {
081: ex.printStackTrace();
082: }
083: logger.warn(ex);
084: if (ex instanceof AgentXParseException) {
085: // exception can be handled on AgentX protocol level
086: AgentXCommandEvent event = new AgentXCommandEvent(this ,
087: this , incomingAddress, sourceTransport,
088: (AgentXParseException) ex);
089: fireCommandEvent(event);
090: }
091: }
092: }
093:
094: public TransportMapping removeTransportMapping(
095: TransportMapping transport) {
096: if (transportMappings.remove(transport)) {
097: transport.removeTransportListener(this );
098: return transport;
099: }
100: return null;
101: }
102:
103: public PduHandle send(TransportMapping transport, Address address,
104: AgentXPDU message, PduHandleCallback callback)
105: throws IOException {
106: PduHandle handle;
107: if (message instanceof AgentXResponsePDU) {
108: handle = new PduHandle(message.getPacketID());
109: } else {
110: handle = createPduHandle();
111: message.setPacketID(handle.getTransactionID());
112: }
113: if (callback != null) {
114: callback.pduHandleAssigned(handle, message);
115: }
116: if (transport != null) {
117: sendPDU(address, message, transport);
118: return handle;
119: } else {
120: for (int i = 0; i < transportMappings.size(); i++) {
121: TransportMapping t = (TransportMapping) transportMappings
122: .get(i);
123: if (address.getClass().equals(
124: t.getSupportedAddressClass())) {
125: sendPDU(address, message, t);
126: return handle;
127: }
128: }
129: }
130: return null;
131: }
132:
133: private void sendPDU(Address address, AgentXPDU message,
134: TransportMapping transport) throws IOException {
135: ByteBuffer buf = ByteBuffer.allocate(message.getPayloadLength()
136: + AgentXProtocol.HEADER_LENGTH);
137: message.encode(buf);
138: send(address, transport, buf);
139: }
140:
141: public void send(Address address, TransportMapping transport,
142: ByteBuffer message) throws IOException {
143: message.flip();
144: byte[] bytes = new byte[message.limit()];
145: message.get(bytes);
146: transport.sendMessage(address, bytes);
147: }
148:
149: protected synchronized void fireCommandEvent(
150: AgentXCommandEvent event) {
151: for (int i = 0; i < commandListener.size(); i++) {
152: ((AgentXCommandListener) commandListener.get(i))
153: .processCommand(event);
154: if (event.isProcessed()) {
155: return;
156: }
157: }
158: }
159:
160: public synchronized void addCommandListener(AgentXCommandListener l) {
161: commandListener.add(l);
162: }
163:
164: public synchronized void removeCommandListener(
165: AgentXCommandListener l) {
166: commandListener.remove(l);
167: }
168: }
|