001: /*
002: * <copyright>
003: *
004: * Copyright 2002-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: package org.cougaar.core.mobility.ldm;
028:
029: import java.io.IOException;
030: import java.io.ObjectInputStream;
031: import java.io.Serializable;
032: import java.util.Collections;
033: import java.util.Set;
034:
035: import org.cougaar.core.mobility.AbstractTicket;
036: import org.cougaar.core.mts.MessageAddress;
037: import org.cougaar.core.relay.Relay;
038: import org.cougaar.core.util.UID;
039:
040: /**
041: * Package-private implementation of {@link AgentControl} using
042: * {@link Relay}s.
043: */
044: class AgentControlImpl implements AgentControl, Relay.Source,
045: Relay.Target, Serializable {
046:
047: private static final ControlStatus NO_CONTROL_STATUS = new ControlStatus(
048: NONE, null);
049:
050: private final UID uid;
051: private final UID ownerUID;
052: private final MessageAddress source;
053: private final MessageAddress target;
054: private final AbstractTicket ticket;
055: private ControlStatus controlStatus;
056:
057: private transient Set _targets;
058:
059: public AgentControlImpl(UID uid, UID ownerUID,
060: MessageAddress source, MessageAddress target,
061: AbstractTicket ticket) {
062: this .uid = uid;
063: this .ownerUID = ownerUID;
064: this .source = source;
065: this .target = target;
066: this .ticket = ticket;
067: if ((uid == null) || (source == null) || (ticket == null)) {
068: throw new IllegalArgumentException("null uid/ticket");
069: }
070: // expecting target to be either addA or origN
071: cacheTargets();
072: // initial Status:
073: this .controlStatus = NO_CONTROL_STATUS;
074: }
075:
076: public UID getUID() {
077: return uid;
078: }
079:
080: public void setUID(UID uid) {
081: throw new UnsupportedOperationException();
082: }
083:
084: // AgentControl:
085:
086: public UID getOwnerUID() {
087: return ownerUID;
088: }
089:
090: public MessageAddress getTarget() {
091: return target;
092: }
093:
094: public AbstractTicket getAbstractTicket() {
095: return ticket;
096: }
097:
098: public int getStatusCode() {
099: return controlStatus.getStatusCode();
100: }
101:
102: public String getStatusCodeAsString() {
103: int i = getStatusCode();
104: switch (i) {
105: case NONE:
106: return "NONE";
107: case CREATED:
108: return "CREATED";
109: case ALREADY_EXISTS:
110: return "ALREADY_EXISTS";
111: case REMOVED:
112: return "REMOVED";
113: case DOES_NOT_EXIST:
114: return "DOES_NOT_EXIST";
115: case MOVED:
116: return "MOVED";
117: case ALREADY_MOVED:
118: return "ALREADY_MOVED";
119: case FAILURE:
120: return "FAILURE";
121: default:
122: return "Unknown (" + i + ")";
123: }
124: }
125:
126: public Throwable getFailureStackTrace() {
127: return controlStatus.getStack();
128: }
129:
130: public void setStatus(int statusCode, Throwable stack) {
131: ControlStatus newCS = new ControlStatus(statusCode, stack);
132: if (!(controlStatus.equals(NO_CONTROL_STATUS))) {
133: throw new IllegalArgumentException("Status already set to "
134: + controlStatus + ", can't override with " + newCS);
135: }
136: controlStatus = newCS;
137: }
138:
139: // Relay.Source:
140:
141: private void cacheTargets() {
142: _targets = (((target != null) && (!(target.equals(source)))) ? Collections
143: .singleton(target)
144: : Collections.EMPTY_SET);
145: }
146:
147: public Set getTargets() {
148: return _targets;
149: }
150:
151: public Object getContent() {
152: return this ;
153: }
154:
155: public Relay.TargetFactory getTargetFactory() {
156: return AgentControlImplFactory.INSTANCE;
157: }
158:
159: public int updateResponse(MessageAddress t, Object response) {
160: ControlStatus newCS = (ControlStatus) response;
161: // assert local-agent == getSource()
162: // assert newMS != null
163: if (!(controlStatus.equals(newCS))) {
164: controlStatus = newCS;
165: return Relay.RESPONSE_CHANGE;
166: }
167: return Relay.NO_CHANGE;
168: }
169:
170: // Relay.Target:
171:
172: public MessageAddress getSource() {
173: return source;
174: }
175:
176: public Object getResponse() {
177: return ((!(controlStatus.equals(NO_CONTROL_STATUS))) ? (controlStatus)
178: : null);
179: }
180:
181: public int updateContent(Object content, Token token) {
182: // currently the content is immutable
183: // maybe support "abort" content in the future
184: return Relay.NO_CHANGE;
185: }
186:
187: public boolean equals(Object o) {
188: if (o == this ) {
189: return true;
190: } else if (!(o instanceof AgentControlImpl)) {
191: return false;
192: } else {
193: UID u = ((AgentControlImpl) o).uid;
194: return uid.equals(u);
195: }
196: }
197:
198: public int hashCode() {
199: return uid.hashCode();
200: }
201:
202: private void readObject(ObjectInputStream stream)
203: throws ClassNotFoundException, IOException {
204: stream.defaultReadObject();
205: cacheTargets();
206: }
207:
208: public String toString() {
209: return "Agent control request " + uid + " owned by " + ownerUID
210: + " and ticket (" + ticket + ") with source " + source
211: + " and target " + target + ", status is "
212: + controlStatus;
213: }
214:
215: private static class ControlStatus implements Serializable {
216: public final int statusCode;
217: public final Throwable stack;
218:
219: public ControlStatus(int statusCode, Throwable stack) {
220: this .statusCode = statusCode;
221: this .stack = stack;
222: }
223:
224: public int getStatusCode() {
225: return statusCode;
226: }
227:
228: public Throwable getStack() {
229: return stack;
230: }
231:
232: public boolean equals(Object o) {
233: if (o == this ) {
234: return true;
235: } else if (!(o instanceof ControlStatus)) {
236: return false;
237: } else {
238: ControlStatus cs = (ControlStatus) o;
239: return ((statusCode == cs.statusCode) && ((stack != null) ? (stack
240: .equals(cs.stack))
241: : (cs.stack == null)));
242: }
243: }
244:
245: public String toString() {
246: return "status (" + statusCode + ") stack(" + stack + ")";
247: }
248: }
249:
250: /**
251: * Simple factory implementation.
252: */
253: private static class AgentControlImplFactory implements
254: Relay.TargetFactory, Serializable {
255:
256: public static AgentControlImplFactory INSTANCE = new AgentControlImplFactory();
257:
258: private AgentControlImplFactory() {
259: }
260:
261: public Relay.Target create(UID uid, MessageAddress source,
262: Object content, Relay.Token token) {
263: AgentControlImpl adi = (AgentControlImpl) content;
264: return new AgentControlImpl(adi.uid, adi.ownerUID, source,
265: null, adi.ticket);
266: }
267:
268: private Object readResolve() {
269: return INSTANCE;
270: }
271: }
272: }
|