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.targets;
024:
025: import net.fenyo.gnetwatch.*;
026: import net.fenyo.gnetwatch.GUI.*;
027: import net.fenyo.gnetwatch.data.*;
028:
029: import org.apache.commons.collections.map.*;
030:
031: import java.net.Inet4Address;
032: import java.net.InetAddress;
033: import java.net.UnknownHostException;
034: import java.util.*;
035:
036: import org.apache.commons.logging.Log;
037: import org.apache.commons.logging.LogFactory;
038:
039: /**
040: * Target is the base class for every types of targets.
041: * @author Alexandre Fenyo
042: * @version $Id: Target.java,v 1.31 2007/03/12 05:04:15 fenyo Exp $
043: */
044:
045: public class Target extends VisualElement {
046: private static Log log = LogFactory.getLog(Target.class);
047:
048: final private String name; // not null
049:
050: private MultiValueMap registered_components = new MultiValueMap();
051:
052: // maps a class of events to instances of this class
053: // note that this class is not synchronized
054: // the MultiValueMap decorates an ArrayList by defaults
055: final private MultiValueMap events = new MultiValueMap();
056:
057: /**
058: * Constructor.
059: * @param name target name.
060: * @throws AlgorithmException exception.
061: */
062: // GUI thread
063: public Target(final String name) throws AlgorithmException {
064: if (name == null)
065: throw new AlgorithmException("name is null");
066: this .name = name;
067: }
068:
069: /**
070: * Informs this target that this component is interested in this type of events.
071: * @param component component to register.
072: * @param clazz type of events.
073: * @return void.
074: */
075: // AWT thread
076: public void registerComponent(final BasicComponent component,
077: final Class clazz) {
078: synchronized (registered_components) {
079: if (!registered_components.containsValue(clazz, component))
080: registered_components.put(clazz, component);
081: }
082: }
083:
084: /**
085: * Unregister a component.
086: * @param component component to unregister.
087: * @param clazz type of events.
088: */
089: // AWT thread
090: public void unregisterComponent(final BasicComponent component,
091: final Class clazz) {
092: synchronized (registered_components) {
093: if (registered_components.remove(clazz, component) == null)
094: log.error("component was not registered");
095: }
096: }
097:
098: /**
099: * Returns the last event.
100: * @param clazz type of events.
101: * @return EventGeneric last event.
102: */
103: public EventGeneric getLastEvent(Class clazz) {
104: synchronized (events) {
105: final ArrayList<EventGeneric> events_of_this _class = (ArrayList<EventGeneric>) events
106: .getCollection(clazz);
107: if (events_of_this _class == null)
108: return null;
109: return events_of_this _class
110: .get(events_of_this _class.size() - 1);
111: }
112: }
113:
114: /**
115: * Returns events from the first BEFORE begin (or at begin) to the last AFTER end (or at end).
116: * @param begin start time.
117: * @param end end time.
118: * @param clazz type of events.
119: * @return List<EventGeneric> list of selected events.
120: */
121: // AWT thread
122: public List<EventGeneric> getEvents(final Date begin,
123: final Date end, Class clazz) {
124: final List<EventGeneric> selected_events = new LinkedList<EventGeneric>();
125:
126: synchronized (events) {
127: final ArrayList<EventGeneric> events_of_this _class = (ArrayList<EventGeneric>) events
128: .getCollection(clazz);
129: if (events_of_this _class == null)
130: return selected_events;
131:
132: EventGeneric just_before = null, just_after = null;
133: for (final EventGeneric event : events_of_this _class) {
134: if (event.getDate().after(begin)
135: && event.getDate().before(end)
136: || event.getDate().equals(begin)
137: || event.getDate().equals(end))
138: selected_events.add(event);
139: if ((event.getDate().before(begin) || event.getDate()
140: .equals(begin))
141: && (just_before == null || event.getDate()
142: .after(just_before.getDate())))
143: just_before = event;
144: if ((event.getDate().after(end) || event.getDate()
145: .equals(end))
146: && (just_after == null || event.getDate()
147: .before(just_after.getDate())))
148: just_after = event;
149: }
150:
151: if (just_before != null || just_after != null) {
152: for (final EventGeneric event : events_of_this _class) {
153: if (just_before != null
154: && just_before.getDate().equals(
155: event.getDate())
156: && !selected_events.contains(event))
157: selected_events.add(event);
158: if (just_after != null
159: && just_after.getDate().equals(
160: event.getDate())
161: && !selected_events.contains(event))
162: selected_events.add(event);
163: }
164: }
165:
166: Collections.sort(selected_events,
167: new Comparator<EventGeneric>() {
168: public int compare(final EventGeneric o1,
169: final EventGeneric o2) {
170: return o1.getDate().compareTo(o2.getDate());
171: }
172: });
173:
174: return selected_events;
175: }
176: }
177:
178: /**
179: * Returns the name of this target.
180: * @param none.
181: * @return String target name.
182: */
183: public String getName() {
184: return name;
185: }
186:
187: /**
188: * Adds a new event.
189: * @param event event to add.
190: * @return void.
191: */
192: // Queue thread
193: public void addEvent(final EventGeneric event) {
194: final List<BasicComponent> components = new ArrayList<BasicComponent>();
195:
196: synchronized (registered_components) {
197: if (registered_components.containsKey(event.getClass()))
198: for (final BasicComponent component : (ArrayList<BasicComponent>) registered_components
199: .getCollection(event.getClass()))
200: components.add(component);
201: }
202: for (final BasicComponent component : components)
203: component.updateValues(event);
204:
205: synchronized (events) {
206: final boolean is_new_event_class = !events
207: .containsKey(event.getClass());
208: events.put(event.getClass(), event);
209: // max of 300 events per type and per target
210: if (events.getCollection(event.getClass()).size() > 300)
211: ((ArrayList) events.getCollection(event.getClass()))
212: .remove(0);
213: if (is_new_event_class == true)
214: getGUI().informTargetHasNewEventClass(this );
215: }
216: }
217:
218: public void removeEvents(final Class clazz) {
219: synchronized (events) {
220: events.remove(clazz);
221: }
222: }
223:
224: /**
225: * Returns the event types of events associated to this target.
226: * @param none.
227: * @return Set<Class> event types.
228: */
229: // GUI thread
230: @SuppressWarnings("unchecked")
231: public Set<Class> getEventTypesInUse() {
232: synchronized (events) {
233: // returns a copy of the set of keys
234: return new HashSet<Class>(events.keySet());
235: }
236: }
237:
238: /**
239: * Called when this target is disposed.
240: * @param none.
241: * @return void.
242: */
243: // GUI thread
244: public void disposed() {
245: super .disposed();
246: getGUI().dropTargetInstance(this );
247: }
248:
249: /**
250: * Checks that this target can be attached to a specific parent element.
251: * @param parent parent element.
252: * @return true if this target can be attached to this parent element.
253: */
254: public boolean canAddTarget(final VisualElement parent) {
255: if (parent != null)
256: synchronized (getGUI().getGUICreated()) {
257: if (getGUI().getGUICreated()[0] == true) {
258: // group "local host" is readonly
259: if (parent.equals(getGUI().getVisualThisHost()))
260: return false;
261:
262: // group "every host" is readonly
263: if (parent.equals(getGUI().getVisualTransientAll()))
264: return false;
265:
266: // group "networks" and its childs are readonly
267: if (parent.equals(getGUI()
268: .getVisualTransientNetworks())
269: || getGUI().getVisualTransientNetworks()
270: .getChildren().contains(parent))
271: return false;
272:
273: // avoid twins
274: if (parent.getChildren().contains(this ))
275: return false;
276:
277: // avoid self reference
278: if (parent.equals(this ))
279: return false;
280:
281: // avoid loops
282: if (parent.getAllParents(getClass()).contains(this ))
283: return false;
284: }
285: }
286:
287: return true;
288: }
289:
290: /**
291: * Attaches this target to a specific parent element.
292: * @param gui current GUI instance.
293: * @param parent parent element.
294: * @return true if this target has been succesfully attached to this parent element.
295: */
296: public boolean addTarget(final GUI gui, final VisualElement parent) {
297: initialize(gui);
298:
299: if (!canAddTarget(parent))
300: return false;
301: if (parent != null && !parent.canManageThisChild(this ))
302: return false;
303:
304: if (parent != null) {
305: getGUI().getCanonicalInstance(this ).setParent(getGUI(),
306: parent);
307: if (getGUI().getCanonicalInstance(this ) == this )
308: return true;
309: }
310: return false;
311: }
312:
313: /**
314: * Compares two targets.
315: * @param o target to compare to.
316: * @return true if the targets are equal.
317: */
318: // any thread
319: public boolean equals(final Object o) {
320: if (this == o)
321: return true;
322: if ((o == null) || (o.getClass() != getClass()))
323: return false;
324: final Target target = (Target) o;
325: return getName().equals(target.getName());
326: }
327:
328: /**
329: * Returns the hashcode for this target.
330: * @param none.
331: * @return int hashcode.
332: */
333: // any thread
334: public int hashCode() {
335: return getName().hashCode();
336: }
337: }
|