KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > objectserver > l1 > impl > ClientStateManagerImpl


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.objectserver.l1.impl;
6
7 import com.tc.logging.TCLogger;
8 import com.tc.net.protocol.tcm.ChannelID;
9 import com.tc.object.ObjectID;
10 import com.tc.object.dna.api.DNA;
11 import com.tc.objectserver.l1.api.ClientState;
12 import com.tc.objectserver.l1.api.ClientStateManager;
13 import com.tc.objectserver.managedobject.BackReferences;
14 import com.tc.text.PrettyPrintable;
15 import com.tc.text.PrettyPrinter;
16 import com.tc.util.ObjectIDSet2;
17
18 import java.util.Collection JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.LinkedList JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.Set JavaDoc;
26
27 /**
28  * @author steve
29  */

30 public class ClientStateManagerImpl implements ClientStateManager {
31
32   private static final State STARTED = new State("STARTED");
33   private static final State STOPPED = new State("STOPPED");
34
35   private State state = STARTED;
36
37   private final Map JavaDoc clientStates;
38   private final TCLogger logger;
39
40   // for testing
41
public ClientStateManagerImpl(TCLogger logger, Map JavaDoc states) {
42     this.logger = logger;
43     this.clientStates = states;
44   }
45
46   public ClientStateManagerImpl(TCLogger logger) {
47     this(logger, new HashMap JavaDoc());
48   }
49
50   public synchronized List JavaDoc createPrunedChangesAndAddObjectIDTo(Collection JavaDoc changes, BackReferences includeIDs,
51                                                                ChannelID id, Set JavaDoc objectIDs) {
52     assertStarted();
53     ClientStateImpl clientState = getOrCreateClientState(id);
54     LinkedList JavaDoc prunedChanges = new LinkedList JavaDoc();
55
56     for (Iterator JavaDoc i = changes.iterator(); i.hasNext();) {
57       DNA dna = (DNA) i.next();
58       if (clientState.containsReference(dna.getObjectID())) {
59         if (dna.isDelta()) {
60           prunedChanges.add(dna);
61         } else {
62           // This new Object must have already been sent as a part of a different lookup. So ignoring this change.
63
}
64         // } else if (clientState.containsParent(dna.getObjectID(), includeIDs)) {
65
// these objects needs to be looked up from the client during apply
66
// objectIDs.add(dna.getObjectID());
67
}
68     }
69     clientState.addReferencedChildrenTo(objectIDs, includeIDs);
70
71     return prunedChanges;
72   }
73
74   public synchronized void addReference(ChannelID id, ObjectID objectID) {
75     assertStarted();
76     // logger.info("Adding Reference for " + id + " to " + objectID);
77
ClientStateImpl c = getOrCreateClientState(id);
78     c.addReference(objectID);
79   }
80
81   public synchronized void removeReferences(ChannelID id, Set JavaDoc removed) {
82     assertStarted();
83     // logger.info("Removing Reference for " + id + " to " + removed);
84
ClientStateImpl c = getOrCreateClientState(id);
85     c.removeReferences(removed);
86   }
87
88   public synchronized boolean hasReference(ChannelID clientID, ObjectID objectID) {
89     ClientStateImpl c = getOrCreateClientState(clientID);
90     return c.containsReference(objectID);
91   }
92
93   public synchronized void addAllReferencedIdsTo(Set JavaDoc ids) {
94     assertStarted();
95     for (Iterator JavaDoc i = clientStates.values().iterator(); i.hasNext();) {
96       ClientStateImpl s = (ClientStateImpl) i.next();
97       s.addReferencedIdsTo(ids);
98     }
99   }
100
101   public synchronized void removeReferencedFrom(ChannelID channelID, Set JavaDoc oids) {
102     ClientState cs = getOrCreateClientState(channelID);
103     Set JavaDoc refs = cs.getReferences();
104     // XXX:: This is a work around for THashSet's poor implementation of removeAll
105
if (oids.size() >= refs.size()) {
106       oids.removeAll(refs);
107     } else {
108       for (Iterator JavaDoc i = oids.iterator(); i.hasNext();) {
109         if (refs.contains(i.next())) {
110           i.remove();
111         }
112       }
113     }
114
115   }
116
117   /*
118    * returns newly added references
119    */

120   public synchronized Set JavaDoc addReferences(ChannelID channelID, Set JavaDoc oids) {
121     ClientState cs = getOrCreateClientState(channelID);
122     Set JavaDoc refs = cs.getReferences();
123     if (refs.isEmpty()) {
124       refs.addAll(oids);
125       return oids;
126     }
127     Set JavaDoc newReferences = new HashSet JavaDoc();
128     for (Iterator JavaDoc i = oids.iterator(); i.hasNext();) {
129       Object JavaDoc oid = i.next();
130       if (refs.add(oid)) {
131         newReferences.add(oid);
132       }
133     }
134     return newReferences;
135   }
136
137   public synchronized void shutdownClient(ChannelID waitee) {
138     if (!isStarted()) {
139       // it's too late to remove the client from the database. On startup, this guy will fail to reconnect
140
// within the timeout period and be slain.
141
return;
142     }
143     clientStates.remove(waitee);
144   }
145
146   public synchronized void stop() {
147     assertStarted();
148     state = STOPPED;
149     logger.info("ClientStateManager stopped.");
150   }
151
152   private boolean isStarted() {
153     return state == STARTED;
154   }
155
156   private void assertStarted() {
157     if (state != STARTED) throw new AssertionError JavaDoc("Not started.");
158   }
159
160   private ClientStateImpl getOrCreateClientState(ChannelID clientID) {
161     ClientStateImpl clientState;
162     if ((clientState = (ClientStateImpl) clientStates.get(clientID)) == null) {
163       clientState = new ClientStateImpl(clientID);
164       clientStates.put(clientID, clientState);
165     }
166     return clientState;
167   }
168
169   public synchronized PrettyPrinter prettyPrint(PrettyPrinter out) {
170     PrettyPrinter rv = out;
171     out.println(getClass().getName());
172     out = out.duplicateAndIndent();
173     out.indent().println("client states: ");
174     out = out.duplicateAndIndent();
175     for (Iterator JavaDoc i = clientStates.keySet().iterator(); i.hasNext();) {
176       Object JavaDoc key = i.next();
177       ClientStateImpl st = (ClientStateImpl) clientStates.get(key);
178       out.indent().print(key + "=").visit(st).println();
179     }
180     return rv;
181   }
182
183   private static class State {
184     private final String JavaDoc name;
185
186     private State(String JavaDoc name) {
187       this.name = name;
188     }
189
190     public String JavaDoc toString() {
191       return getClass().getName() + "[" + this.name + "]";
192     }
193   }
194
195   private static class ClientStateImpl implements PrettyPrintable, ClientState {
196     private final ChannelID clientID;
197     private final Set JavaDoc managed = new ObjectIDSet2();
198
199     public ClientStateImpl(ChannelID clientID) {
200       this.clientID = clientID;
201     }
202
203     public void addReferencedChildrenTo(Set JavaDoc objectIDs, BackReferences includeIDs) {
204       Set JavaDoc parents = includeIDs.getAllParents();
205       parents.retainAll(managed);
206       includeIDs.addReferencedChildrenTo(objectIDs, parents);
207     }
208
209     public String JavaDoc toString() {
210       return "ClientStateImpl[" + clientID + ", " + managed + "]";
211     }
212
213     public Set JavaDoc getReferences() {
214       return managed;
215     }
216
217     public PrettyPrinter prettyPrint(PrettyPrinter out) {
218       out.println(getClass().getName());
219       out.duplicateAndIndent().indent().print("managed: ").visit(managed);
220       return out;
221     }
222
223     public void addReference(ObjectID id) {
224       managed.add(id);
225     }
226
227     public boolean containsReference(ObjectID id) {
228       return managed.contains(id);
229     }
230
231     public void removeReferences(Set JavaDoc references) {
232       managed.removeAll(references);
233     }
234
235     public void addReferencedIdsTo(Set JavaDoc ids) {
236       ids.addAll(managed);
237     }
238
239     public ChannelID getClientID() {
240       return clientID;
241     }
242   }
243
244 }
245
Popular Tags