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.util.ArrayList;
032: import java.util.Collection;
033: import java.util.Collections;
034: import java.util.HashMap;
035: import java.util.HashSet;
036: import java.util.Iterator;
037: import java.util.Map;
038: import java.util.Set;
039: import java.util.Date;
040:
041: import java.text.DateFormat;
042: import java.text.SimpleDateFormat;
043:
044: import javax.naming.directory.Attributes;
045:
046: import org.cougaar.core.service.community.Agent;
047: import org.cougaar.core.service.community.Community;
048: import org.cougaar.core.service.community.Entity;
049:
050: /**
051: * Implementation of org.cougaar.core.service.community.Community interface used
052: * to define communities.
053: */
054: public class CommunityImpl extends EntityImpl implements Community,
055: java.io.Serializable, Cloneable {
056:
057: protected static final DateFormat df = new SimpleDateFormat(
058: "hh:mm:ss,SSS");
059: protected Map entities = Collections.synchronizedMap(new HashMap());
060: protected long lastUpdate;
061:
062: /**
063: * Constructor
064: * @param name Name of community
065: */
066: public CommunityImpl(String name) {
067: super (name);
068: lastUpdate = now();
069: }
070:
071: /**
072: * Constructor
073: * @param name Name of community
074: * @param attrs Initial attributes
075: */
076: public CommunityImpl(String name, Attributes attrs) {
077: super (name, attrs);
078: lastUpdate = now();
079: }
080:
081: /**
082: * Returns a collection containing all entities associated with this
083: * community.
084: * @return Collection of Entity objects
085: */
086: public Collection getEntities() {
087: synchronized (entities) {
088: if (entities.isEmpty()) {
089: return new ArrayList();
090: } else {
091: return new ArrayList(entities.values());
092: }
093: }
094: }
095:
096: public void setEntities(Collection newEntities) {
097: synchronized (entities) {
098: entities = Collections.synchronizedMap(new HashMap());
099: }
100: for (Iterator it = newEntities.iterator(); it.hasNext();) {
101: addEntity((Entity) it.next());
102: }
103: }
104:
105: public void setAttributes(Attributes attrs) {
106: super .setAttributes(attrs);
107: lastUpdate = now();
108: }
109:
110: public long getLastUpdate() {
111: return lastUpdate;
112: }
113:
114: public void setLastUpdate(long time) {
115: lastUpdate = time;
116: }
117:
118: /**
119: * Returns the named Entity or null if it doesn't exist.
120: * @param name Name of entity
121: * @return Entity referenced by name
122: */
123: public Entity getEntity(String name) {
124: return (Entity) entities.get(name);
125: }
126:
127: /**
128: * Returns true if community contains entity.
129: * @param name Name of requested entity
130: * @return true if community contains entity
131: */
132: public boolean hasEntity(String name) {
133: return entities.containsKey(name);
134: }
135:
136: /**
137: * Adds an Entity to the community.
138: * @param entity Entity to add to community
139: */
140: public void addEntity(Entity entity) {
141: if (entity != null) {
142: synchronized (entities) {
143: entities.put(entity.getName(), entity);
144: lastUpdate = now();
145: }
146: }
147: }
148:
149: /**
150: * Removes an Entity from the community.
151: * @param name Name of entity to remove from community
152: */
153: public void removeEntity(String name) {
154: synchronized (entities) {
155: entities.remove(name);
156: lastUpdate = now();
157: }
158: }
159:
160: /**
161: * Performs search of community and returns collection of matching Entity
162: * objects.
163: * @param filter JNDI style search filter
164: * @param qualifier Search qualifier (e.g., AGENTS_ONLY, COMMUNITIES_ONLY, or
165: * ALL_ENTITIES)
166: * @return Set of Entity objects satisfying search filter
167: */
168: public Set search(String filter, int qualifier) {
169: Set matches = new HashSet();
170: SearchStringParser parser = new SearchStringParser();
171: try {
172: Filter f = parser.parse(filter);
173: for (Iterator it = getEntities().iterator(); it.hasNext();) {
174: Entity entity = (Entity) it.next();
175: if (entity != null && f.match(entity.getAttributes())) {
176: if ((qualifier == ALL_ENTITIES)
177: || (qualifier == AGENTS_ONLY && entity instanceof Agent)
178: || (qualifier == COMMUNITIES_ONLY && entity instanceof Community)) {
179: matches.add(entity);
180: }
181: }
182: }
183: } catch (Exception ex) {
184: System.out.println("Exception in Community search, filter="
185: + filter);
186: ex.printStackTrace();
187: }
188: return matches;
189: }
190:
191: // Converts a collection of entities to a compact string representation of names
192: private String entityNames(Collection members) {
193: StringBuffer sb = new StringBuffer("[");
194: for (Iterator it = members.iterator(); it.hasNext();) {
195: sb.append(it.next().toString() + (it.hasNext() ? "," : ""));
196: }
197: return (sb.append("]").toString());
198: }
199:
200: public String qualifierToString(int qualifier) {
201: switch (qualifier) {
202: case AGENTS_ONLY:
203: return "AGENTS_ONLY";
204: case COMMUNITIES_ONLY:
205: return "COMMUNITIES_ONLY";
206: case ALL_ENTITIES:
207: return "ALL_ENTITIES";
208: }
209: return "INVALID_VALUE";
210: }
211:
212: protected long now() {
213: return System.currentTimeMillis();
214: }
215:
216: public Object clone() {
217: CommunityImpl clone = (CommunityImpl) super .clone();
218: clone.lastUpdate = lastUpdate;
219: clone.entities = CommunityUtils.cloneEntities(getEntities());
220: return clone;
221: }
222:
223: public boolean equals(Object o) {
224: if (o instanceof CommunityImpl) {
225: CommunityImpl c = (CommunityImpl) o;
226: return (name.equals(c.name) && lastUpdate == c.lastUpdate && attrs
227: .equals(c.attrs));
228: }
229: return false;
230: }
231:
232: /**
233: * Returns an XML representation of community.
234: * @return XML representation of community
235: */
236: public String toXml() {
237: return toXml("");
238: }
239:
240: /**
241: * Returns an XML representation of community.
242: * @param indent Blank string used to pad beginning of entry to control
243: * indentation formatting
244: * @return XML representation of community
245: */
246: public String toXml(String indent) {
247: StringBuffer sb = new StringBuffer(indent
248: + "<Community name=\"" + getName() + "\" timestamp=\""
249: + df.format(new Date(lastUpdate)) + "\" >\n");
250: Attributes attrs = getAttributes();
251: if (attrs != null && attrs.size() > 0)
252: sb.append(attrsToString(getAttributes(), indent + " "));
253: for (Iterator it = getEntities().iterator(); it.hasNext();) {
254: sb.append(((Entity) it.next()).toXml(indent + " "));
255: }
256: sb.append(indent + "</Community>\n");
257: return sb.toString();
258: }
259:
260: private void writeObject(ObjectOutputStream stream)
261: throws IOException {
262: stream.writeObject(this .getName());
263: stream.writeObject(this .getAttributes());
264: stream.writeObject(getEntities());
265: stream.writeLong(lastUpdate);
266: }
267:
268: private void readObject(ObjectInputStream stream)
269: throws ClassNotFoundException, IOException {
270: entities = Collections.synchronizedMap(new HashMap());
271: setName((String) stream.readObject());
272: setAttributes((Attributes) stream.readObject());
273: setEntities((Collection) stream.readObject());
274: lastUpdate = stream.readLong();
275: }
276: }
|