KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > oddjob > arooa > registry > ComponentRegistry


1 /*
2  * (c) Rob Gordon 2005
3  */

4 package org.oddjob.arooa.registry;
5
6 import java.util.HashMap JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.Map JavaDoc;
9
10 import org.apache.commons.beanutils.PropertyUtils;
11 import org.oddjob.arooa.ArooaException;
12 import org.oddjob.values.types.MapType;
13
14 /**
15  * Register components by id and look them up by path. A ComponentRegistry is a
16  * hierarchy with child registries. The path identifies in the hierarchy where
17  * the component resides.
18  *
19  * @author Rob Gordon.
20  */

21 public class ComponentRegistry {
22
23     /** The serverId for this registry */
24     private final ServerId serverId;
25     
26     /** Contains the path to this registry. */
27     private Path path;
28
29     /** Maps ids to Components */
30     private final Map JavaDoc/*<String, Object>*/ ids = new HashMap JavaDoc();
31
32     /** Maps components to ids. */
33     private final Map JavaDoc/*<Object, String>*/ components = new HashMap JavaDoc();
34     
35     /** Object to child. The id is the id of the component in this registry
36      * which links to the child registry. The linking component will typically
37      * be a nested OddJob or a client Job. */

38     private final Map JavaDoc children/*<Object, ComponentRegistry>*/ = new HashMap JavaDoc();
39
40     /**
41      * Constructor for a local registry.
42      *
43      */

44     public ComponentRegistry() {
45         this(ServerId.local());
46     }
47     
48     /**
49      * Constructor for a registry that contains proxies
50      * for remote components on the give server.
51      *
52      * @param serverId The ServerId.
53      */

54     public ComponentRegistry(ServerId serverId) {
55         if (serverId == null) {
56             throw new NullPointerException JavaDoc("serverId must not be null!");
57         }
58         this.serverId = serverId;
59         this.path = new Path();
60     }
61     
62     /**
63      * Get the serverId.
64      *
65      * @return The serverId.
66      */

67     public ServerId getServerId() {
68         return serverId;
69     }
70     
71     /**
72      * Add a child ComponentRegistry to this one.
73      *
74      * @param child The child component registry.
75      * @param owner The component in this registry which owns the
76      * child registry.
77      */

78     public void addChild(ComponentRegistry child, Object JavaDoc owner) {
79         if (serverId.equals(child.serverId)) {
80             String JavaDoc ownerId = getIdForComponent(owner);
81             Path childPath = path.addId(ownerId);
82             child.path = childPath;
83         }
84         else {
85             child.path = new Path();
86         }
87         children.put(owner, child);
88     }
89     
90     /**
91      * Remove a child ComponentRegistry.
92      *
93      * @param owner The component in this registry which owns the
94      * child registry.
95      */

96     public void removeChild(Object JavaDoc owner) {
97         children.remove(owner);
98     }
99     
100     /**
101      * Get the component registry owned by the component which will
102      * probably either be an Oddjob or client job.
103      *
104      * @param owner The owner component.
105      * @return A ComponentRegistry or null if the compnent
106      * doesn't own a registry.
107      */

108     public ComponentRegistry registryOwnedBy(Object JavaDoc owner) {
109         return (ComponentRegistry) children.get(owner);
110     }
111
112     /**
113      * Is the give component a registry owner?
114      *
115      * @param component The component.
116      * @return true if it is, false otherwise.
117      */

118     public boolean isOwner(Object JavaDoc component) {
119         return !(children.get(component) == null);
120     }
121     
122     /**
123      * Register an object. The id should not contain reserved characters.
124      *
125      * @param id The id of the object.
126      * @param object The object.
127      */

128     public void register(String JavaDoc id, Object JavaDoc component) {
129         if (id == null) {
130             return;
131         }
132         if (id.indexOf(PropertyUtils.NESTED_DELIM) > -1
133                 || id.indexOf(PropertyUtils.INDEXED_DELIM) > -1
134                 || id.indexOf(PropertyUtils.INDEXED_DELIM2) > -1
135                 || id.indexOf(PropertyUtils.MAPPED_DELIM) > -1
136                 || id.indexOf(PropertyUtils.MAPPED_DELIM2) > -1
137                 || id.indexOf(Path.PATH_SEPARATOR) > -1) {
138             throw new ArooaException("Id contains a reserverd character.");
139         }
140         if (ids.containsKey(id)) {
141             throw new ArooaException("A component with id [" + id + "] is already registered");
142         }
143         ids.put(id, component);
144         components.put(component, id);
145     }
146     
147     /**
148      * Find the id for the given component.
149      *
150      * @param component The component.
151      * @return The id or null if none can be found.
152      */

153     public String JavaDoc getIdForComponent(Object JavaDoc component) {
154         return (String JavaDoc) components.get(component);
155     }
156     
157     /**
158      * Get an object for the given path.
159      *
160      * @param path The path.
161      * @return An object or null if it hasn't been registered.
162      */

163     public Object JavaDoc objectForPath(Path path) {
164         if (path == null) {
165             return null;
166         }
167         Path childPath = path.getChildPath();
168         if (childPath == null) {
169             return null;
170         }
171         String JavaDoc id = path.getId();
172         Object JavaDoc component = ids.get(id);
173         if (childPath.size() == 0) {
174             return component;
175         }
176         ComponentRegistry child =
177             (ComponentRegistry) children.get(component);
178         if (child == null) {
179             return null;
180         }
181         return child.objectForPath(childPath);
182     }
183     
184     /**
185      * Find the object from the possible addresses that could identify it. If
186      * there are several paths to the object (which can happen if the original object
187      * is accessable via several servers), the object with the shortest path is
188      * returned.
189      *
190      * @param addresses The possible addresses of the component.
191      * @return The componen or null if none of the addresses are accessable.
192      */

193     public Object JavaDoc objectForAddress(Address address) {
194         if (address == null) {
195             return null;
196         }
197         ComponentRegistry registry = registryForServer(address.getServerId());
198         if (registry == null) {
199                 return null;
200         }
201         Path relativePath = registry.path.relativeTo(address.getPath());
202         return registry.objectForPath(relativePath);
203     }
204
205     /**
206      * Get the path to a given component that may or may not be
207      * in this registries hierarchy.
208      *
209      * @param component The component.
210      * @return The path or null if it can't be found.
211      */

212     public Path pathForObject(Object JavaDoc component) {
213         if (component == null) {
214             throw new NullPointerException JavaDoc("Component must not be null!");
215         }
216         return pathToComponent(new Path(), component);
217     }
218     
219     /**
220      * Helper funtion to find a path to a component.
221      *
222      * @param existing The current path being built up in this recursive call.
223      * @param component The componet being searched for.
224      *
225      * @return The path relative to this registry or null if it is
226      * is not acessable.
227      */

228     Path pathToComponent(Path existing, Object JavaDoc component) {
229         String JavaDoc id = getIdForComponent(component);
230         if (id != null) {
231             return existing.addId(id);
232         }
233         // go round all the child registries recursing down until we find a
234
// registry for our component.
235
for (Iterator JavaDoc it = children.entrySet().iterator(); it.hasNext();) {
236             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
237             Object JavaDoc childComponent = entry.getKey();
238             String JavaDoc childId = (String JavaDoc) components.get(childComponent);
239             if (childId == null) {
240                 // a registry owner without an id - so no path downwards
241
// from here.
242
return null;
243             }
244             ComponentRegistry child = (ComponentRegistry) entry.getValue();
245             Path result = child.pathToComponent(
246                     existing.addId(childId), component);
247             if (result != null) {
248                 return result;
249             }
250         }
251         return null;
252     }
253     
254     /**
255      * Helper funtion to convert a path for a different server into the
256      * path to that servers client from this registry.
257      *
258      * @param existing The current path being built up in this recursive call.
259      * @param serverId The server id for this current path.
260      *
261      * @return The path relative to the other server or null if the other server
262      * is not acessable.
263      */

264     ComponentRegistry registryForServer(ServerId serverId) {
265         if (this.serverId.equals(serverId)) {
266             return this;
267         }
268         // go round all the child registries recursing down until we find a
269
// registry for the server.
270
for (Iterator JavaDoc it = children.entrySet().iterator(); it.hasNext();) {
271             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
272             ComponentRegistry child = (ComponentRegistry) entry.getValue();
273             ComponentRegistry result = child.registryForServer(serverId);
274             if (result != null) {
275                 return result;
276             }
277         }
278         return null;
279     }
280     
281     /**
282      * Get the possible addresses for a given component in this registry.
283      *
284      * @param object The component.
285      * @return The possible addresses or null if the object is not registered
286      * in this registry.
287      */

288     public Address addressForObject(Object JavaDoc object) {
289         String JavaDoc id = (String JavaDoc) components.get(object);
290         if (id == null) {
291             return null;
292         }
293         return new Address(serverId,
294                 path.addId(id));
295     }
296         
297     /**
298      * Helper funtion to find a registry for a component.
299      *
300      * @param existing The current path being built up in this recursive call.
301      * @param component The componet being searched for.
302      *
303      * @return The path relative to this registry or null if it is
304      * is not acessable.
305      */

306     ComponentRegistry registryForComponent(Object JavaDoc component) {
307         String JavaDoc id = getIdForComponent(component);
308         if (id != null) {
309             return this;
310         }
311         // go round all the child registries recursing down until we find a
312
// registry for our component.
313
for (Iterator JavaDoc it = children.entrySet().iterator(); it.hasNext();) {
314             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) it.next();
315             Object JavaDoc childComponent = entry.getKey();
316             String JavaDoc childId = (String JavaDoc) components.get(childComponent);
317             if (childId == null) {
318                 // a registry owner without an id - so no path downwards
319
// from here.
320
return null;
321             }
322             ComponentRegistry child = (ComponentRegistry) entry.getValue();
323             ComponentRegistry result = child.registryForComponent(component);
324             if (result != null) {
325                 return result;
326             }
327         }
328         return null;
329     }
330     
331     
332     /**
333      * Remove a component from the registry if it exists.
334      *
335      * @param component The compnent.
336      */

337     public void remove(Object JavaDoc component) {
338         String JavaDoc id = (String JavaDoc) components.remove(component);
339         ids.remove(id);
340         children.remove(component);
341     }
342
343     /**
344      * Get the number of child registries for this registry.
345      *
346      * @return The number of child registries.
347      */

348     public int childCount() {
349         return children.size();
350     }
351     
352     /*
353      * (non-Javadoc)
354      * @see java.lang.Object#toString()
355      */

356     public String JavaDoc toString() {
357         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
358         buf.append("ComponentRegistry, ids [" + ids.size() + "], children [" + children.size() + "]");
359         buf.append('\n');
360         buf.append(MapType.propertiesFrom(ids));
361         return buf.toString();
362     }
363 }
364
Popular Tags