KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > remote > util > StubToLocalMapper


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9  */

10 package org.mmbase.bridge.remote.util;
11
12 import java.util.*;
13 import org.mmbase.bridge.*;
14
15 import org.mmbase.util.logging.Logging;
16 import org.mmbase.util.logging.Logger;
17
18 /**
19  * StubToLocalMapper is a utitity class that helps a Stub to find it's Local implementation.
20  * @author Kees Jongenburger
21  * @version $Id: StubToLocalMapper.java,v 1.5 2006/07/06 11:53:34 michiel Exp $
22  **/

23 public class StubToLocalMapper {
24     static private final Logger log = Logging.getLoggerInstance(StubToLocalMapper.class);
25     /**
26      * private data member to keep track of mapperCode/object combinations
27      **/

28     private static final Map hash = new Hashtable();
29     private static final Map refcount = new Hashtable();
30
31     /**
32      * Add an object to the mapper.
33      * @param object the object to add to the mapper
34      * @return a string that can later be used to find back the object or remove it (MapperCode)
35      **/

36     public static String JavaDoc add(Object JavaDoc object) {
37         if (object != null) {
38
39             String JavaDoc mapperCode = null;
40             if (object instanceof Node) {
41                 Node node = (Node)object;
42                 mapperCode = "node:" + node.getNodeManager().getName() + "->" + node.getNumber();
43             } else if (object instanceof Cloud) {
44                 Cloud cloud = (Cloud)object;
45                 mapperCode = "cloud:" + cloud.getName();
46             } else if (object instanceof Relation) {
47                 Relation rel = (Relation)object;
48                 mapperCode = "relation:" + rel.getNodeManager().getName() + "->" + rel.getNumber();
49             } else if (object instanceof RelationManager) {
50                 RelationManager relationManager = (RelationManager)object;
51                 mapperCode = "relationmanager:" + relationManager.getName() + "->" + relationManager.getNumber();
52             } else if (object instanceof NodeManager) {
53                 NodeManager nodeManager = (NodeManager)object;
54                 mapperCode = "nodemanager:" + nodeManager.getName() + "->" + nodeManager.getNumber();
55             } else {
56                 mapperCode = "" + object;
57             }
58
59             //code needed to support transactions
60
//the generated key (like node:nodemanagername->nodeNumber) is currently wrong
61
//since multiple different instances of the node might exist
62
//the real fix is to add the BasicCloud.getAccount() to the key
63
//but this requires a different code for every type of object(to find the key)
64
//so first we will as a temp fix try to not also check if the object is in the hash
65
//is so and they are not the same instance we create a new hash entry
66
if (hash.get(mapperCode) != null) {
67                 //if there is a hash entry but the object are not equal
68
if (hash.get(mapperCode) != object) {
69                     for (int counter = 1; true; counter++) {
70                         String JavaDoc newMapperCode = mapperCode + "{" + counter + "}";
71                         if (!hash.containsKey(newMapperCode) || hash.get(newMapperCode) == object) {
72                             mapperCode = newMapperCode;
73                             break;
74                         }
75                     }
76                 }
77             }
78
79             log.debug("add=(" + mapperCode + ")");
80             int rcount = increaseRefCount(mapperCode);
81             if (rcount == 1) {
82                 hash.put(mapperCode, object);
83                 log.debug("add=(" + mapperCode + ")");
84             } else {
85                 log.debug("increace=(" + mapperCode + ")(" + rcount + ")");
86             }
87             return mapperCode;
88         }
89         return "";
90     }
91
92     /**
93      * Increase the counter of references to a certain mapper code.
94      * @param mapperCode the mapper to for wich we do reference counting
95      * @return the amount of references known at this point
96      **/

97     private static int increaseRefCount(String JavaDoc mapperCode) {
98         Integer JavaDoc count = (Integer JavaDoc)refcount.get(mapperCode);
99         if (count == null) {
100             refcount.put(mapperCode, new Integer JavaDoc(1));
101             return 1;
102         } else {
103             refcount.put(mapperCode, new Integer JavaDoc(count.intValue() + 1));
104             return count.intValue() + 1;
105         }
106
107     }
108
109     /**
110      * Decrease the counter of references to a certain mapper code.
111      * @param mapperCode the mapper code for with we do reference counting
112      * @return the number of references we have for the mapper code
113      **/

114     private static int decreaseRefCount(String JavaDoc mapperCode) {
115         Integer JavaDoc count = (Integer JavaDoc)refcount.get(mapperCode);
116         if (count == null) {
117             log.warn("refcount entry not found for(" + mapperCode + ")");
118             return 0;
119         }
120         int c = count.intValue();
121
122         if (c == 1) {
123             refcount.remove(mapperCode);
124             return 0;
125         } else {
126             refcount.put(mapperCode, new Integer JavaDoc(c - 1));
127             return c - 1;
128         }
129     }
130
131     /**
132      * Get an object based on its mapper code.
133      * @param mapperCode the Mappercode of the object
134      * @return the required object or <code>null</code> if there was no such object
135      **/

136     public static Object JavaDoc get(String JavaDoc mapperCode) {
137         log.debug("access=(" + mapperCode + ")");
138         Object JavaDoc o = hash.get(mapperCode);
139         return o;
140     }
141
142     /**
143      * Remove an entry in the StubToLocal mapper.
144      * The entry is only removed if there are no other references to the entry.
145      * @param mapperCode the MapperCode of the object to be removed
146      * @return <code>true</code> if the entry was removed
147      **/

148     public static boolean remove(String JavaDoc mapperCode) {
149         if (mapperCode != null && !mapperCode.equals("")) {
150             int rcount = decreaseRefCount(mapperCode);
151             if (rcount == 0) {
152                 log.debug("remove=(" + mapperCode + ")");
153                 hash.remove(mapperCode);
154                 return true;
155             } else {
156                 log.debug("keep=(" + mapperCode + ") refcount=(" + rcount + ")");
157                 return false;
158             }
159         }
160         return false;
161     }
162 }
163
Popular Tags