001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
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:
027: /**
028: * Role is a representation of a potential state of an asset.
029: */package org.cougaar.planning.ldm.plan;
030:
031: import java.beans.BeanDescriptor;
032: import java.beans.BeanInfo;
033: import java.beans.EventSetDescriptor;
034: import java.beans.IntrospectionException;
035: import java.beans.MethodDescriptor;
036: import java.beans.PropertyDescriptor;
037: import java.io.IOException;
038: import java.io.ObjectInputStream;
039: import java.io.Serializable;
040: import java.util.HashMap;
041:
042: public final class Role implements Serializable, BeanInfo {
043: // role cache - needs to be declared before the statics below
044: private static HashMap roles = new HashMap(29);
045: private static HashMap converseRoles = new HashMap(20);
046: private static Object lock = new Object();
047:
048: private static final String DefaultConverse = "ConverseOf";
049:
050: public static final Role ASSIGNED = Role.getRole("Assigned");
051: public static final Role AVAILABLE = Role.getRole("Available");
052: public static final Role BOGUS = Role.getRole("Bogus");
053:
054: /** String holder for logical name.
055: * No guarantee the string name is unique -- within the Agent, much less
056: * within the society of Agents.
057: **/
058: private String name;
059: private String nameConverse;
060:
061: /** getRole - finds the specified role. Uses role cache
062: *
063: * @param vs String name of the role
064: * @return Role which has the specified name. Returns null if no such role exists.
065: */
066: public static Role getRole(String vs) {
067: vs = vs.intern();
068: synchronized (lock) {
069: Role role = (Role) roles.get(vs);
070:
071: if (role == null) {
072: create(vs, DefaultConverse + vs);
073: role = (Role) roles.get(vs);
074: }
075: return role;
076: }
077: }
078:
079: public static void create(String root,
080: RelationshipType relationshipType) {
081: String roleName = root + relationshipType.getFirstSuffix();
082: String converseRoleName = root
083: + relationshipType.getSecondSuffix();
084: ;
085:
086: create(roleName, converseRoleName);
087: }
088:
089: /** create - creates specified role and its converse.
090: * @throws java.lang.IllegalArgumentException if role or converse already exist.
091: * @param roleName String name of the role
092: * @param converseRoleName String name of the converse role
093: */
094: public static void create(String roleName, String converseRoleName) {
095: synchronized (lock) {
096: Role role = (Role) roles.get(roleName);
097: Role converse = (Role) roles.get(converseRoleName);
098:
099: if (((role != null) && (!role.nameConverse
100: .equals(converseRoleName)))
101: || ((converse != null) && (!converse.nameConverse
102: .equals(roleName)))) {
103: if (role != null) {
104: System.err.println("Role.create() role: "
105: + role.name + " already exists, converse: "
106: + role.nameConverse);
107: }
108: if (converse != null) {
109: System.err.println("Role.create() role: "
110: + converse.name
111: + " already exists, converse: "
112: + converse.nameConverse);
113: }
114:
115: throw new IllegalArgumentException(
116: "Role.create: unable to create role/converse pair - "
117: + roleName + "/" + converseRoleName);
118: }
119:
120: roleName = roleName.intern();
121: role = new Role(roleName); // calls cacheRole
122: role.nameConverse = converseRoleName;
123:
124: converseRoleName = converseRoleName.intern();
125:
126: if (roleName != converseRoleName) {
127: converse = new Role(converseRoleName); // calls cacheRole
128: converse.nameConverse = roleName;
129: converseRoles.put(roleName, converse);
130: }
131:
132: converseRoles.put(converseRoleName, role);
133: } // end synchronized(lock)
134: }
135:
136: /** Answer with the String representation of the name. */
137: public String getName() {
138: return name;
139: }
140:
141: /** @return the converse role. */
142: public Role getConverse() {
143: return (Role) converseRoles.get(name);
144: }
145:
146: /** Implementation of the comparison */
147: public boolean equals(Object obj) {
148: if (obj instanceof Role) {
149: return getName().equals(((Role) obj).getName());
150: }
151: return false;
152: }
153:
154: /** @deprecated Only to be used by Beans Introspection. */
155: public Role() {
156: name = "Bogus";
157: }
158:
159: public String toString() {
160: return name;
161: }
162:
163: public int hashCode() {
164: return name.hashCode();
165: }
166:
167: /** Should only be called through Role.getRole */
168: private Role(String string) {
169: if (string == null) {
170: throw new IllegalArgumentException(
171: "Null valued strings are not allowed");
172: }
173: name = string.intern();
174: cacheRole(this );
175: }
176:
177: private static void cacheRole(Role v) {
178: String vs = v.toString();
179: synchronized (lock) {
180: roles.put(vs, v);
181: }
182: }
183:
184: private void readObject(ObjectInputStream stream)
185: throws ClassNotFoundException, IOException {
186: stream.defaultReadObject();
187: //if (name != null) name = name.intern();
188: }
189:
190: // replace with an interned variation
191: private Object readResolve() {
192: if (roles.get(name) == null) {
193: create(name, nameConverse);
194: }
195: return getRole(name);
196: }
197:
198: // beaninfo
199: private static PropertyDescriptor properties[];
200:
201: static {
202: try {
203: properties = new PropertyDescriptor[1];
204: properties[0] = new PropertyDescriptor("name", Role.class,
205: "getName", null);
206: } catch (IntrospectionException ie) {
207: }
208: }
209:
210: public PropertyDescriptor[] getPropertyDescriptors() {
211: return properties;
212: }
213:
214: public BeanDescriptor getBeanDescriptor() {
215: return null;
216: }
217:
218: public int getDefaultPropertyIndex() {
219: return -1;
220: }
221:
222: public EventSetDescriptor[] getEventSetDescriptors() {
223: return null;
224: }
225:
226: public int getDefaultEventIndex() {
227: return -1;
228: }
229:
230: public MethodDescriptor[] getMethodDescriptors() {
231: return null;
232: }
233:
234: public BeanInfo[] getAdditionalBeanInfo() {
235: return null;
236: }
237:
238: public java.awt.Image getIcon(int iconKind) {
239: return null;
240: }
241:
242: public static void main(String[] args) {
243: System.out.println("Available: " + getRole("Available")
244: + " converse: " + AVAILABLE.getConverse());
245:
246: System.out.println("Assigned: " + getRole("Assigned")
247: + " converse: " + ASSIGNED.getConverse());
248:
249: System.out.println("Bogus: " + getRole("Bogus") + " converse: "
250: + BOGUS.getConverse());
251:
252: create("Available", AVAILABLE.getConverse().getName());
253: create("Available", "Assigned");
254: }
255: }
|