Line | Hits | Source |
---|---|---|
1 | /* | |
2 | * Created on Mar 22, 2004 | |
3 | * | |
4 | * Copyright (c) 2004, the JUNG Project and the Regents of the University of | |
5 | * California All rights reserved. | |
6 | * | |
7 | * This software is open-source under the BSD license; see either "license.txt" | |
8 | * or http://jung.sourceforge.net/license.txt for a description. | |
9 | */ | |
10 | package edu.uci.ics.jung.graph.impl; | |
11 | ||
12 | import java.util.Collection; | |
13 | import java.util.HashMap; | |
14 | import java.util.Iterator; | |
15 | import java.util.LinkedList; | |
16 | import java.util.Map; | |
17 | import java.util.Set; | |
18 | ||
19 | import org.apache.commons.collections.Predicate; | |
20 | ||
21 | import edu.uci.ics.jung.exceptions.ConstraintViolationException; | |
22 | import edu.uci.ics.jung.exceptions.FatalException; | |
23 | import edu.uci.ics.jung.graph.ArchetypeEdge; | |
24 | import edu.uci.ics.jung.graph.ArchetypeGraph; | |
25 | import edu.uci.ics.jung.graph.ArchetypeVertex; | |
26 | import edu.uci.ics.jung.graph.event.GraphEventListener; | |
27 | import edu.uci.ics.jung.graph.event.GraphEventType; | |
28 | import edu.uci.ics.jung.graph.event.GraphListenerHandler; | |
29 | import edu.uci.ics.jung.graph.predicates.EdgePredicate; | |
30 | import edu.uci.ics.jung.graph.predicates.GPredicate; | |
31 | import edu.uci.ics.jung.graph.predicates.NotInGraphEdgePredicate; | |
32 | import edu.uci.ics.jung.graph.predicates.NotInGraphVertexPredicate; | |
33 | import edu.uci.ics.jung.graph.predicates.VertexPredicate; | |
34 | import edu.uci.ics.jung.utils.UserDataDelegate; | |
35 | ||
36 | /** | |
37 | * @author Joshua O'Madadhain | |
38 | */ | |
39 | public abstract class AbstractArchetypeGraph extends UserDataDelegate | |
40 | implements ArchetypeGraph, Cloneable { | |
41 | ||
42 | /** | |
43 | * GraphEventType -> Graph Listener list table | |
44 | */ | |
45 | protected GraphListenerHandler mGraphListenerHandler; | |
46 | ||
47 | /** | |
48 | * ID -> Vertex lookup table. | |
49 | */ | |
50 | protected Map mVertexIDs; | |
51 | ||
52 | /** | |
53 | * ID -> Edge lookup table. | |
54 | */ | |
55 | protected Map mEdgeIDs; | |
56 | ||
57 | // /** | |
58 | // * A Collection for user-specified vertex constraints. | |
59 | // */ | |
60 | // protected Requirements user_vertex_requirements; | |
61 | // | |
62 | // /** | |
63 | // * A Collection for user-specified edge constraints. | |
64 | // */ | |
65 | // protected Requirements user_edge_requirements; | |
66 | // | |
67 | // /** | |
68 | // * A Collection for system-specified vertex constraints. | |
69 | // * May not be modified by the user; generally speaking, | |
70 | // * should be set at initialization. | |
71 | // */ | |
72 | // protected Collection system_vertex_requirements; | |
73 | // | |
74 | // /** | |
75 | // * A Collection for system-specified edge constraints. | |
76 | // * May not be modified by the user; generally speaking, | |
77 | // * should be set at initialization. | |
78 | // */ | |
79 | // protected Collection system_edge_requirements; | |
80 | ||
81 | protected Requirements edge_requirements; | |
82 | protected Requirements vertex_requirements; | |
83 | ||
84 | 553 | public AbstractArchetypeGraph() { |
85 | // initialize(); | |
86 | 553 | } |
87 | ||
88 | /** | |
89 | * Initializes all of the graph's internal data structures. Should always be | |
90 | * called by any mechanism that creates a new instance of | |
91 | * <code>AbstractArchetypeGraph</code> (for example, constructors and implementations of | |
92 | * <code>newInstance()</code>). Predicates, if added in this method, | |
93 | * that should not be copied to other graphs | |
94 | * should implement <code>UncopyablePredicate</code>. | |
95 | * | |
96 | * <P>Note: this method is not a substitute for | |
97 | * <code>removeAllVertices()</code>, as it will not notify the vertices | |
98 | * and edges that they have been removed from the graph.</p> | |
99 | */ | |
100 | /** | |
101 | * Initializes all of the graph's internal data structures. Should always be | |
102 | * called by any mechanism that creates a new instance of | |
103 | * AbstractSparseGraph (for example, constructors and implementations of | |
104 | * newInstance()). If you add predicates here, please set their | |
105 | * isInitializeFlag to TRUE. | |
106 | * <P> | |
107 | * Note: this method is not a substitute for | |
108 | * <code>removeAllVertices()</code>, as it will not notify the vertices | |
109 | * and edges that they have been removed from the graph. | |
110 | */ | |
111 | protected void initialize() { | |
112 | 654 | mGraphListenerHandler = new GraphListenerHandler(this); |
113 | 654 | mVertexIDs = new HashMap(); |
114 | 654 | mEdgeIDs = new HashMap(); |
115 | // user_edge_requirements = new Requirements(); | |
116 | // user_vertex_requirements = new Requirements(); | |
117 | // system_edge_requirements = new Requirements(); | |
118 | // system_vertex_requirements = new Requirements(); | |
119 | 654 | edge_requirements = new Requirements(); |
120 | 654 | vertex_requirements = new Requirements(); |
121 | 654 | EdgePredicate ep = new NotInGraphEdgePredicate(this); |
122 | 654 | edge_requirements.add( ep ); |
123 | // system_edge_requirements.add(ep); | |
124 | 654 | ep.isInitializationPredicate = true; |
125 | 654 | VertexPredicate vp = new NotInGraphVertexPredicate(this); |
126 | 654 | vertex_requirements.add( vp ); |
127 | // system_vertex_requirements.add(vp); | |
128 | 654 | vp.isInitializationPredicate = true; |
129 | 654 | } |
130 | ||
131 | // protected void finalize() throws Throwable | |
132 | // { | |
133 | // for (Iterator iter = getUserDatumKeyIterator(); iter.hasNext(); ) | |
134 | // { | |
135 | // removeUserDatum(iter.next()); | |
136 | // } | |
137 | // super.finalize(); | |
138 | // } | |
139 | ||
140 | /** | |
141 | * Creates a new empty graph of the same type as this graph, by cloning this | |
142 | * graph and then clearing the extraneous fields. | |
143 | * | |
144 | * @see edu.uci.ics.jung.graph.ArchetypeGraph#newInstance() | |
145 | */ | |
146 | public ArchetypeGraph newInstance() { | |
147 | try { | |
148 | 101 | AbstractArchetypeGraph aag = (AbstractArchetypeGraph) this.clone(); |
149 | 101 | aag.initialize(); |
150 | // addAllCopyable(aag.system_edge_requirements, system_edge_requirements); | |
151 | // addAllCopyable(aag.system_vertex_requirements, system_vertex_requirements); | |
152 | // addAllCopyable(aag.user_edge_requirements, user_edge_requirements); | |
153 | // addAllCopyable(aag.user_vertex_requirements, user_vertex_requirements); | |
154 | // aag.user_edge_requirements.addAll(getEdgeConstraints()); | |
155 | // aag.user_vertex_requirements.addAll(getVertexConstraints()); | |
156 | 101 | addAllNotInitializers(aag.getEdgeConstraints(), |
157 | getEdgeConstraints()); | |
158 | 101 | addAllNotInitializers(aag.getVertexConstraints(), |
159 | getVertexConstraints()); | |
160 | 101 | return aag; |
161 | 0 | } catch (CloneNotSupportedException e) { |
162 | 0 | throw new FatalException("Failed attempt to clone graph", e); |
163 | } | |
164 | } | |
165 | ||
166 | // /** | |
167 | // * Adds all the predicates in source to the list in target, except those | |
168 | // * that are instances of UncopyablePredicate. | |
169 | // * | |
170 | // * @param targetPredicates | |
171 | // * @param sourcePredicates | |
172 | // */ | |
173 | // protected void addAllCopyable(Collection targetPredicates, Collection sourcePredicates) | |
174 | // { | |
175 | // for (Iterator iter = sourcePredicates.iterator(); iter.hasNext();) | |
176 | // { | |
177 | // Predicate p = (Predicate) iter.next(); | |
178 | // if (! (p instanceof UncopyablePredicate)) | |
179 | // targetPredicates.add(p); | |
180 | // } | |
181 | // } | |
182 | ||
183 | /** | |
184 | * Adds all the predicates in source to the list in target, except those | |
185 | * that answer to isInitializationPredicate. | |
186 | * | |
187 | * @param targetPredicates | |
188 | * @param sourcePredicates | |
189 | */ | |
190 | protected void addAllNotInitializers(Collection targetPredicates, | |
191 | Collection sourcePredicates) { | |
192 | 210 | for (Iterator iter = sourcePredicates.iterator(); iter.hasNext();) { |
193 | 394 | Predicate p = (Predicate) iter.next(); |
194 | 394 | if (p instanceof GPredicate) { |
195 | 213 | GPredicate gp = (GPredicate) p; |
196 | 213 | if (gp.isInitializationPredicate) continue; |
197 | } | |
198 | 184 | targetPredicates.add(p); |
199 | } | |
200 | 210 | } |
201 | ||
202 | ||
203 | /** | |
204 | * Returns the vertex associated with the specified ID, or null if there is | |
205 | * no such vertex. Not intended for user access. | |
206 | */ | |
207 | ArchetypeVertex getVertexByID(int id) { | |
208 | 92914 | return (ArchetypeVertex) mVertexIDs.get(new Integer(id)); |
209 | } | |
210 | ||
211 | /** | |
212 | * Returns the vertex associated with the specified ID, or null if there is | |
213 | * no such vertex. Not intended for user access. | |
214 | */ | |
215 | ArchetypeEdge getEdgeByID(int id) { | |
216 | 124795 | return (ArchetypeEdge) mEdgeIDs.get(new Integer(id)); |
217 | } | |
218 | ||
219 | /** | |
220 | * Returns a human-readable representation of this graph. | |
221 | * | |
222 | * @see java.lang.Object#toString() | |
223 | */ | |
224 | public String toString() { | |
225 | 48 | return "G" + hashCode() + getVertices(); |
226 | } | |
227 | ||
228 | /** | |
229 | * @see ArchetypeGraph#numVertices() | |
230 | */ | |
231 | public int numVertices() { | |
232 | 5791 | return getVertices().size(); |
233 | } | |
234 | ||
235 | /** | |
236 | * @see ArchetypeGraph#numEdges() | |
237 | */ | |
238 | public int numEdges() { | |
239 | 18494 | return getEdges().size(); |
240 | } | |
241 | ||
242 | /** | |
243 | * @see edu.uci.ics.jung.graph.ArchetypeGraph#getVertexConstraints() | |
244 | */ | |
245 | public Collection getVertexConstraints() { | |
246 | // return user_vertex_requirements; | |
247 | 240 | return vertex_requirements; |
248 | } | |
249 | ||
250 | /** | |
251 | * @see edu.uci.ics.jung.graph.ArchetypeGraph#getEdgeConstraints() | |
252 | */ | |
253 | public Collection getEdgeConstraints() { | |
254 | // return user_edge_requirements; | |
255 | 269237 | return edge_requirements; |
256 | } | |
257 | ||
258 | /** | |
259 | * @see edu.uci.ics.jung.graph.ArchetypeGraph#addListener(edu.uci.ics.jung.graph.event.GraphEventListener, | |
260 | * edu.uci.ics.jung.graph.event.GraphEventType) | |
261 | */ | |
262 | public void addListener(GraphEventListener gel, GraphEventType get) { | |
263 | 28 | mGraphListenerHandler.addListener(gel, get); |
264 | 28 | } |
265 | ||
266 | /** | |
267 | * @see edu.uci.ics.jung.graph.ArchetypeGraph#removeListener(edu.uci.ics.jung.graph.event.GraphEventListener, | |
268 | * edu.uci.ics.jung.graph.event.GraphEventType) | |
269 | */ | |
270 | public void removeListener(GraphEventListener gel, GraphEventType get) { | |
271 | 0 | mGraphListenerHandler.removeListener(gel, get); |
272 | 0 | } |
273 | ||
274 | protected boolean listenersExist(GraphEventType type) { | |
275 | 0 | return mGraphListenerHandler.listenersExist(type); |
276 | } | |
277 | ||
278 | /** | |
279 | * Creates a replica of this graph. Creates a new instance, then copies all | |
280 | * vertices, then all edges, and finally all user data. | |
281 | * | |
282 | * @see ArchetypeGraph#copy() | |
283 | * @see AbstractSparseEdge#copy(ArchetypeGraph) | |
284 | * @see AbstractSparseVertex#copy(ArchetypeGraph) | |
285 | */ | |
286 | public ArchetypeGraph copy() { | |
287 | 43 | ArchetypeGraph c = newInstance(); |
288 | 43 | for (Iterator iter = getVertices().iterator(); iter.hasNext();) { |
289 | 237 | ArchetypeVertex av = (ArchetypeVertex) iter.next(); |
290 | 237 | av.copy(c); |
291 | } | |
292 | 43 | for (Iterator iter = getEdges().iterator(); iter.hasNext();) { |
293 | 407 | ArchetypeEdge ae = (ArchetypeEdge) iter.next(); |
294 | 407 | ae.copy(c); |
295 | } | |
296 | 43 | c.importUserData(this); |
297 | 43 | return c; |
298 | } | |
299 | ||
300 | protected void checkConstraints(Object o, Collection c) { | |
301 | 180665 | for (Iterator iter = c.iterator(); iter.hasNext();) { |
302 | 476638 | Predicate p = (Predicate) iter.next(); |
303 | 476638 | if (!p.evaluate(o)) |
304 | { | |
305 | 39 | throw new ConstraintViolationException("Predicate " + |
306 | p.getClass().getName() + " rejected " + o + ": " + p, p); | |
307 | } | |
308 | } | |
309 | 180624 | } |
310 | ||
311 | ||
312 | /** | |
313 | * Removes all vertices (and, therefore, all edges) from this graph. | |
314 | * Syntactic sugar for a loop that calls <code>removeVertex</code> on all | |
315 | * vertices of this graph. | |
316 | * | |
317 | * @see ArchetypeGraph#removeAllVertices() | |
318 | */ | |
319 | public void removeAllVertices() { | |
320 | 21 | removeVertices(getVertices()); |
321 | 21 | } |
322 | ||
323 | /** | |
324 | * Removes all edges from this graph. Syntactic sugar for a loop that calls | |
325 | * <code>removeEdge</code> on all edges of this graph. | |
326 | * | |
327 | * @see ArchetypeGraph#removeAllEdges() | |
328 | */ | |
329 | public void removeAllEdges() { | |
330 | 2 | removeEdges(getEdges()); |
331 | 2 | } |
332 | ||
333 | // /** | |
334 | // * Checks see whether <code>e</code> passes both user and system constraints. | |
335 | // */ | |
336 | // protected void validateEdge(ArchetypeEdge e) | |
337 | // { | |
338 | // validate(e, user_edge_requirements); | |
339 | // validate(e, system_edge_requirements); | |
340 | // } | |
341 | // | |
342 | // /** | |
343 | // * Checks see whether <code>v</code> passes both user and system constraints. | |
344 | // */ | |
345 | // protected void validateVertex(ArchetypeVertex v) | |
346 | // { | |
347 | // validate(v, user_vertex_requirements); | |
348 | // validate(v, system_vertex_requirements); | |
349 | // } | |
350 | ||
351 | protected class Requirements extends LinkedList { | |
352 | ||
353 | public boolean add(Object o) | |
354 | { | |
355 | Set edges = getEdges(); | |
356 | Set vertices = getVertices(); | |
357 | if (!this.contains(o)) | |
358 | { | |
359 | if (!(edges == null || edges.isEmpty()) || !(vertices == null || vertices.isEmpty())) | |
360 | throw new IllegalArgumentException("Cannot add " | |
361 | + "requirements to a non-empty graph"); | |
362 | super.add((Predicate) o); | |
363 | return true; | |
364 | } | |
365 | else | |
366 | return false; // no duplicates allowed | |
367 | } | |
368 | ||
369 | public boolean evaluate(Object o) { | |
370 | for (Iterator iter = iterator(); iter.hasNext();) { | |
371 | Predicate p = (Predicate) iter.next(); | |
372 | if (!p.evaluate(o)) return false; | |
373 | } | |
374 | return true; | |
375 | } | |
376 | } | |
377 | } |
this report was generated by version 1.0.5 of jcoverage. |
copyright © 2003, jcoverage ltd. all rights reserved. |