001: /*
002: * GNetWatch
003: * Copyright 2006, 2007 Alexandre Fenyo
004: * gnetwatch@fenyo.net
005: *
006: * This file is part of GNetWatch.
007: *
008: * GNetWatch is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License as published by
010: * the Free Software Foundation; either version 2 of the License, or
011: * (at your option) any later version.
012: *
013: * GNetWatch is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: * GNU General Public License for more details.
017: *
018: * You should have received a copy of the GNU General Public License
019: * along with GNetWatch; if not, write to the Free Software
020: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
021: */
022:
023: package net.fenyo.gnetwatch.activities;
024:
025: import java.util.*;
026: import java.util.regex.Matcher;
027: import java.util.regex.Pattern;
028:
029: import net.fenyo.gnetwatch.*;
030: import net.fenyo.gnetwatch.GUI.GUI;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034:
035: import org.apache.commons.collections.*;
036:
037: import org.dom4j.*;
038: import org.dom4j.io.*;
039: import org.eclipse.swt.SWT;
040: import org.eclipse.swt.widgets.MessageBox;
041:
042: /**
043: * This class captures Ethernet frames using tethereal.
044: * A tethereal instance is spawned through a Capture instance, for each layer-2 interface.
045: * @author Alexandre Fenyo
046: * @version $Id: CaptureManager.java,v 1.8 2007/03/08 18:21:31 fenyo Exp $
047: */
048:
049: public class CaptureManager {
050: private static Log log = LogFactory.getLog(CaptureManager.class);
051:
052: private final Config config;
053: private GUI gui;
054:
055: private final List<Capture> capture_list = new LinkedList<Capture>();
056: // deprecated donc changer de type
057: private MultiMap listeners = new MultiHashMap();
058:
059: public interface HandlePacket {
060: public void document(final Document packet);
061: }
062:
063: /**
064: * Constructor.
065: * main thread.
066: * @param config configuration.
067: */
068: public CaptureManager(final Config config) {
069: this .config = config;
070: }
071:
072: /**
073: * Defines the GUI instance.
074: * @param GUI gui.
075: * @return void.
076: */
077: public void setGUI(final GUI gui) {
078: this .gui = gui;
079: }
080:
081: /**
082: * Creates captures instances for each available interface.
083: * @param filter tethereal filter.
084: * @return void.
085: * @throws InterruptedException exception.
086: */
087: // GUI thread
088: private void startCapture(final String filter)
089: throws InterruptedException {
090: synchronized (capture_list) {
091: final String[] devices = Capture.listDevices();
092:
093: if (devices == null) {
094: final MessageBox dialog = new MessageBox(
095: gui.getShell(), SWT.ICON_ERROR | SWT.OK);
096: dialog.setText(config.getString("thethereal_error"));
097: dialog.setMessage(config
098: .getString("thethereal_error_long"));
099: dialog.open();
100: return;
101: }
102:
103: for (final String device : devices) {
104: final Matcher match = Pattern.compile("^([0-9]*)\\. ")
105: .matcher(device);
106: if (match.find() == true) {
107: final Capture capture = new Capture(config, this ,
108: new Integer(match.group(1)).intValue(),
109: filter);
110: capture_list.add(capture);
111: capture.createCaptureThread();
112: }
113: }
114: }
115: }
116:
117: /**
118: * Stops every capture instances.
119: * @param none.
120: * @return void.
121: * @throws InterruptedException exception.
122: */
123: // GUI thread
124: private void stopCapture() throws InterruptedException {
125: synchronized (capture_list) {
126: for (final Capture capture : capture_list)
127: capture.end();
128: capture_list.clear();
129: }
130: }
131:
132: /**
133: * Creates a filter that integrates every individual listener filters.
134: * @param none.
135: * @return String global filter.
136: */
137: // GUI thread
138: private String getGlobalFilter() {
139: String global_filter = "";
140: synchronized (listeners) {
141: if (!listeners.keySet().contains(""))
142: for (final String individual_filter : new HashSet<String>(
143: listeners.keySet())) {
144: if (!individual_filter.equals("")) {
145: if (global_filter.equals(""))
146: global_filter = "(" + individual_filter
147: + ")";
148: else
149: global_filter += " or ("
150: + individual_filter + ")";
151: }
152: }
153: }
154: return global_filter;
155: }
156:
157: /**
158: * Register a frame listener.
159: * @param filter filter this listener is interested in.
160: * @param callback entry point for asynchronous call.
161: * @throws InterruptedException exception.
162: */
163: // the methods registerListener, unRegisterListener and unRegisterAllListeners are synchronized
164: // to be sure only one is executed at a time
165: // GUI thread
166: public synchronized void registerListener(final String filter,
167: final HandlePacket callback) throws InterruptedException {
168: final boolean does_contain;
169:
170: synchronized (listeners) {
171: does_contain = listeners.containsKey(filter);
172: if (does_contain)
173: listeners.put(filter, callback);
174: }
175:
176: if (!does_contain) {
177: stopCapture();
178:
179: synchronized (listeners) {
180: listeners.put(filter, callback);
181: }
182:
183: startCapture(getGlobalFilter());
184: }
185: }
186:
187: /**
188: * Removes a frame listener.
189: * @param filter filter this listener was interested in.
190: * @param callback entry point for asynchronous call.
191: * @return void.
192: * @throws InterruptedException exception.
193: */
194: // GUI thread
195: public synchronized void unRegisterListener(final String filter,
196: final HandlePacket callback) throws InterruptedException {
197: final boolean does_contain;
198: final int size;
199:
200: synchronized (listeners) {
201: listeners.remove(filter, callback);
202: does_contain = listeners.containsKey(filter);
203: size = listeners.size();
204: }
205:
206: if (!does_contain) {
207: stopCapture();
208: if (size > 0)
209: startCapture(getGlobalFilter());
210: }
211: }
212:
213: /**
214: * Removes every listeners.
215: * @param none.
216: * @return void.
217: * @throws InterruptedException exception.
218: */
219: // main thread
220: public synchronized void unRegisterAllListeners()
221: throws InterruptedException {
222: synchronized (listeners) {
223: listeners.clear();
224: }
225:
226: stopCapture();
227: }
228:
229: /**
230: * Inform every listeners about the next frame.
231: * @param packet next frame.
232: * @return void.
233: */
234: // Capture thread
235: public void handlePacket(final Document packet) {
236: synchronized (listeners) {
237: for (final HandlePacket callback : new ArrayList<HandlePacket>(
238: listeners.values()))
239: callback.document(packet);
240: }
241: }
242: }
|