Coverage details for edu.uci.ics.jung.utils.UnifiedUserData

LineHitsSource
1 /*
2  * Created on Jul 30, 2005
3  *
4  * Copyright (c) 2005, the JUNG Project and the Regents of the University
5  * of California
6  * All rights reserved.
7  *
8  * This software is open-source under the BSD license; see either
9  * "license.txt" or
10  * http://jung.sourceforge.net/license.txt for a description.
11  */
12 package edu.uci.ics.jung.utils;
13  
14 import java.util.HashMap;
15 import java.util.Iterator;
16 import java.util.LinkedList;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.WeakHashMap;
20  
21 import org.apache.commons.collections.IteratorUtils;
22  
23 import edu.uci.ics.jung.exceptions.FatalException;
24  
25 /**
26  * Represents custom user- and system-level information to extend the definition
27  * of a node. This is the easiest way to extend the class without subclassing.
28  *
29  * This works as a dictionary in order to help ensure that there are
30  * possibilities for extending user information to a variety of different sorts
31  * of data. (Each provider of information can register their own enhanced
32  * information without interfering with other providers.)
33  *
34  * Some suggested uses of UserData include
35  * <ul>
36  * <li/>Underlying data references, such as pointers to data sources</li>
37  * <li/>Raw data which can be analyzed or used by the constraint and filter systems
38  * <li/>Temporary enhanced information which can be used for visualization
39  * </ul>
40  *
41  * Consider a series of nodes that has, among other things, enhanced information
42  * about 3D coordinates. This might be stored in the 3DData data structure,
43  * which generates itself with an input from a node.
44  *
45  * Thus the relevant call might be <code>n.addUserDatum("3DData", new 3DData (
46  * ))</code>.
47  * Later, to access this information, the call might be <code>3DData dd =
48  * (3DData) n.getUserDatum("3DData").</code>
49  *
50  * <h3>Shared and Individual Data</h3>
51  * Note that the there are no required semantics for the key or the information.
52  * However, it is necessary to specify information that is used for SHARED and
53  * for INDIVIDUAL data elements. When a new View of a graph is
54  * generated, the Node elements inside it are all shallow-copied. The UserData
55  * that they use, however, is <em>not</em> copied, by default. This is the
56  * correct and logical behavior if the UserData contains source information.
57  *
58  * But what when the UserData contains transient information, specific to the
59  * view, such as graph metrics or coordinates? In that case, the UserData would
60  * be quite inappropriate to share that information between copies.
61  *
62  * The solution to this is to add a third flag, "shared", which tells whether
63  * the currect data is shared or not. This flag is assigned when the data is
64  * added.
65  */
660public class UnifiedUserData extends UserData implements UserDataFactory
67 {
68     // maps a Key to a Pair( UserData, CopyAction )
69 // private Map userDataStorage;
700    protected final static Map key_meta_map = new HashMap();
71 // private final static Object NO_GRAPH = "NO_GRAPH";
72  
73 // private Map getStorage() {
74 // if (userDataStorage == null) {
75 // userDataStorage = new HashMap();
76 // }
77 // return userDataStorage;
78 // }
79  
80 // /**
81 // * This class actually clones by removing the reference to the copyAction
82 // * and userData
83 // */
84 // protected Object clone() throws CloneNotSupportedException {
85 // UserData ud = (UserData) super.clone();
86 //// ud.userDataStorage = null;
87 // return ud;
88 // }
89  
90     protected Map getKeyMap(Object key)
91     {
920        Map key_map = (Map)key_meta_map.get(key);
930        if (key_map == null)
94         {
950            key_map = new WeakHashMap();
96 // key_map = new HashMap();
970            key_meta_map.put(key, key_map);
98         }
990        return key_map;
100     }
101  
102 // protected Pair getObjectKey()
103 // {
104 // Object container = this;
105 // if (this instanceof Element)
106 // {
107 // container = ((Element)this).getGraph();
108 // if (container == null)
109 // container = NO_GRAPH;
110 // }
111 //// return new Pair(new WeakReference(this), new WeakReference(container));
112 // return new Pair(this, container);
113 // }
114     
115     /**
116      * Adds user-level information to the node. Throws an exception if the node
117      * already has information associated with it.
118      *
119      * @param key
120      * A unique (per type, not per node) key into the information
121      * @param value
122      * The extended information associated with the node
123      */
124     public void addUserDatum(Object key, Object value, CopyAction shared) {
1250        if (key == null)
1260            throw new IllegalArgumentException("Key must not be null");
127  
1280        Map key_map = getKeyMap(key);
129         
130 // Pair object_key = getObjectKey();
131 // if (key_map.containsKey(object_key))
1320        if (key_map.containsKey(this))
1330            throw new IllegalArgumentException("Key <" + key
134                     + "> had already been added to object " + this);
135         
1360        Pair object_value = new Pair(value, shared);
137         
138 // key_map.put(object_key, object_value);
1390        key_map.put(this, object_value);
140         
141 // if (!getStorage().containsKey(key)) {
142 // getStorage().put(key, new Pair(value, shared));
143 // } else {
144 // throw new IllegalArgumentException("Key <" + key
145 // + "> had already been added to an object with keys "
146 // + getKeys());
147 // }
1480    }
149  
150     /**
151      * @return
152      */
153 // private Set getKeys() {
154 // return getStorage().keySet();
155 // }
156  
157     /**
158      * Uses the CopyAction to determine how each of the user datum elements in
159      * udc should be carried over to the this UserDataContiner
160      *
161      * @param udc
162      * The UserDataContainer whose user data is being imported
163      */
164     public void importUserData(UserDataContainer udc) {
1650        for (Iterator keyIt = udc.getUserDatumKeyIterator(); keyIt.hasNext();) {
1660            Object key = keyIt.next();
1670            Object value = udc.getUserDatum(key);
1680            CopyAction action = udc.getUserDatumCopyAction(key);
1690            Object newValue = action.onCopy(value, udc, this);
170             try {
1710                if (newValue != null) addUserDatum(key, newValue, action);
172  
1730            } catch (IllegalArgumentException iae) {
1740                List userDataKeys = IteratorUtils.toList(udc
175                         .getUserDatumKeyIterator());
1760                throw new FatalException("Copying <" + key + "> of "
177                         + userDataKeys
178                         + " into a container that started with some keys ",
179                         iae);
1800            }
181         }
182  
1830    }
184  
185     /**
186      * Changes the user-level information to the object. Equivalent to calling
187      *
188      * <pre>
189      * removeUserDatum( key );
190      * addUserDatum(key, value)
191      * </pre>
192      *
193      * @param key
194      * @param value
195      */
196     public void setUserDatum(Object key, Object value, CopyAction shared) {
197 // removeUserDatum(key);
198 // addUserDatum(key, value, shared);
199 // getKeyMap(key).put(getObjectKey(), new Pair(value, shared));
2000        getKeyMap(key).put(this, new Pair(value, shared));
201 // getStorage().put(key, new Pair(value, shared));
2020    }
203  
204     /**
205      * Returns UserData (if any) for this key, or <em>null</em> if not
206      * known.
207      *
208      * @param key
209      */
210     public Object getUserDatum(Object key)
211     {
2120        Pair value_pair = this.getUserDatumValuePair(key);
213 // Pair p = (Pair) getStorage().get(key);
2140        if (value_pair == null)
2150            return null;
2160        return value_pair.getFirst();
217     }
218  
219     protected Pair getUserDatumValuePair(Object key)
220     {
221 // return (Pair)(getKeyMap(key).get(getObjectKey()));
2220        return (Pair)(getKeyMap(key).get(this));
223     }
224     
225     /**
226      * Removes the Datum (if any) for this key, and returns it.
227      *
228      * @param key
229      */
230     public Object removeUserDatum(Object key) {
2310        Object o = getUserDatum(key);
2320        Map key_map = getKeyMap(key);
233 // key_map.remove(getObjectKey());
2340        key_map.remove(this);
2350        if (key_map.isEmpty())
2360            key_meta_map.remove(key_map);
237 // getStorage().remove(key);
238 // return value_pair.getFirst();
2390        return o;
240     }
241  
242     /**
243      * Returns an <code>Iterator</code> which can be used to iterate over
244      * all the user data repository keys for this object.
245      *
246      * @return Iterator
247      */
248     public Iterator getUserDatumKeyIterator() {
2490        List keys = new LinkedList();
250 // Pair key_pair = getObjectKey();
2510        for (Iterator iter = key_meta_map.keySet().iterator(); iter.hasNext(); )
252         {
2530            Object key = iter.next();
2540            Map key_map = getKeyMap(key);
255 // if (key_map.containsKey(key_pair))
2560            if (key_map.containsKey(this))
2570                keys.add(key);
258         }
2590        return keys.iterator();
260 // return getStorage().keySet().iterator();
261     }
262  
263     /**
264      * @see UserDataContainer#containsUserDatumKey(Object)
265      */
266     public boolean containsUserDatumKey(Object key)
267     {
268 // return ((Map)key_meta_map.get(key)).containsKey(getObjectKey());
2690        return ((Map)key_meta_map.get(key)).containsKey(this);
270 // return getStorage().containsKey(key);
271     }
272     
273     /**
274      * Returns the CopyAction associated with this key.
275      *
276      * @param key
277      * @return CopyAction
278      */
279     public CopyAction getUserDatumCopyAction(Object key) {
2800        Pair value_pair = this.getUserDatumValuePair(key);
2810        if (value_pair == null) return null;
282 // Pair p = (Pair) getStorage().get(key);
2830        return (CopyAction) value_pair.getSecond();
284     }
285  
286     public UserDataContainer getInstance()
287     {
2880        return new UnifiedUserData();
289     }
290     
291     public Object clone() throws CloneNotSupportedException
292     {
2930        return super.clone();
294     }
295     
296 }

this report was generated by version 1.0.5 of jcoverage.
visit www.jcoverage.com for updates.

copyright © 2003, jcoverage ltd. all rights reserved.
Java is a trademark of Sun Microsystems, Inc. in the United States and other countries.