001: /*
002: * <copyright>
003: *
004: * Copyright 2001-2004 Mobile Intelligence Corp
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: package org.cougaar.community;
027:
028: import java.io.IOException;
029: import java.io.ObjectInputStream;
030: import java.io.ObjectOutputStream;
031: import java.io.Serializable;
032: import java.util.ArrayList;
033: import java.util.Collection;
034: import java.util.Collections;
035: import java.util.HashMap;
036: import java.util.HashSet;
037: import java.util.Iterator;
038: import java.util.List;
039: import java.util.Map;
040: import java.util.Set;
041:
042: import org.cougaar.core.service.community.Entity;
043:
044: /**
045: * Identifies the entities that an agent has added (via a join request) to
046: * all its parent communities. This map is
047: * compared to Community objects received from the various community
048: * managers sending Community data to this agent. If a mismatch is detected
049: * the agent will attempt to rectify by sending an join or leave request
050: * to manager. A mismatch is likely the result of a community manager
051: * termination/restart.
052: */
053: public class CommunityMemberships implements Serializable {
054:
055: private Map parentCommunities = new HashMap();
056: private transient Set listeners = Collections
057: .synchronizedSet(new HashSet());
058:
059: /**
060: * Add an entity to community.
061: * @param communityName Name of parent community
062: * @param entity Entity added by monitoring agent
063: */
064: public synchronized void add(String communityName, Entity entity) {
065: Map entities = (Map) parentCommunities.get(communityName);
066: if (entities == null) {
067: entities = new HashMap();
068: parentCommunities.put(communityName, entities);
069: }
070: entities.put(entity.getName(), entity);
071: fireListeners();
072: }
073:
074: /**
075: * Get names of all parent communities.
076: * @return Set of community names.
077: */
078: public synchronized Set listCommunities() {
079: return parentCommunities.keySet();
080: }
081:
082: /**
083: * Check for existence of community.
084: * @param communityName Name of community
085: * @return true if community exists
086: */
087: public synchronized boolean contains(String communityName) {
088: return parentCommunities.containsKey(communityName);
089: }
090:
091: /**
092: * Check for existence of entity in community.
093: * @param communityName Name of community
094: * @param entityName Name of entity
095: * @return true if community exists and has entry for specified entity
096: */
097: public synchronized boolean contains(String communityName,
098: String entityName) {
099: Map entities = (Map) parentCommunities.get(communityName);
100: return (entities != null && entities.containsKey(entityName));
101: }
102:
103: /**
104: * Remove community.
105: * @param communityName Name of community to remove
106: */
107: public synchronized void remove(String communityName) {
108: if (parentCommunities.containsKey(communityName)) {
109: parentCommunities.remove(communityName);
110: fireListeners();
111: }
112: }
113:
114: /**
115: * Remove entity from community. If community entry is empty after removal
116: * of entity, the community is also removed.
117: * @param communityName Name of parent community
118: * @param entityName Name of entity to remove
119: */
120: public synchronized void remove(String communityName,
121: String entityName) {
122: Map entities = (Map) parentCommunities.get(communityName);
123: if (entities != null && entities.containsKey(entityName)) {
124: entities.remove(entityName);
125: if (entities.isEmpty())
126: parentCommunities.remove(communityName);
127: fireListeners();
128: }
129: }
130:
131: /**
132: * Returns a Collection of Entity objects associated with named Community.
133: * @param communityName Name of community
134: * @return Collection of Entity objects associated with named community
135: */
136: public synchronized Collection getEntities(String communityName) {
137: Map entities = (Map) parentCommunities.get(communityName);
138: if (entities != null) {
139: return new ArrayList(entities.values());
140: } else {
141: return Collections.EMPTY_SET;
142: }
143: }
144:
145: public String toString() {
146: StringBuffer sb = new StringBuffer();
147: for (Iterator it = parentCommunities.entrySet().iterator(); it
148: .hasNext();) {
149: Map.Entry me = (Map.Entry) it.next();
150: String communityName = (String) me.getKey();
151: Map entities = (Map) me.getValue();
152: String entityNames = CommunityUtils.entityNames(entities
153: .keySet());
154: sb.append(communityName + "=" + entityNames);
155: if (it.hasNext()) {
156: sb.append(", ");
157: }
158: }
159: return sb.toString();
160: }
161:
162: public void addListener(CommunityMembershipsListener cml) {
163: if (listeners == null) {
164: listeners = Collections.synchronizedSet(new HashSet());
165: }
166: listeners.add(cml);
167: }
168:
169: public void removeListener(CommunityMembershipsListener cml) {
170: if (listeners != null) {
171: listeners.remove(cml);
172: }
173: }
174:
175: protected void fireListeners() {
176: if (listeners != null) {
177: List l = new ArrayList(listeners);
178: for (Iterator it = l.iterator(); it.hasNext();) {
179: CommunityMembershipsListener cml = (CommunityMembershipsListener) it
180: .next();
181: cml.membershipsChanged();
182: }
183: }
184: }
185:
186: private void writeObject(ObjectOutputStream stream)
187: throws IOException {
188: synchronized (this ) {
189: stream.writeObject(this .parentCommunities);
190: }
191: }
192:
193: private void readObject(ObjectInputStream stream)
194: throws ClassNotFoundException, IOException {
195: parentCommunities = (HashMap) stream.readObject();
196: }
197: }
|