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.adaptivity;
028:
029: import java.util.Collections;
030: import java.util.Set;
031:
032: import org.cougaar.core.mts.MessageAddress;
033: import org.cougaar.core.relay.Relay;
034: import org.cougaar.core.util.UID;
035: import org.cougaar.core.util.UniqueObject;
036: import org.cougaar.util.log.Logger;
037: import org.cougaar.util.log.Logging;
038:
039: /**
040: * The Condition part of a remotely-controlled Condition. This is the
041: * Relay.Target that receives updates from the InterAgentOperatingMode
042: * Relay.Source. An instance of this class is instantiated on the
043: * target's blackboard and acts as any other Condition such as
044: * providing an input to the adaptivity engine.
045: **/
046: public class InterAgentCondition extends OMCBase implements
047: Relay.Source, Relay.Target, Condition, UniqueObject {
048:
049: // this can't be transient like other relays, cause not storing
050: // target separately
051: private Set targets = Collections.EMPTY_SET;
052:
053: private UID uid;
054: private MessageAddress source;
055: private Relay.Token owner;
056:
057: InterAgentCondition(InterAgentOperatingMode iaom, UID uid,
058: MessageAddress src, Relay.Token owner) {
059: super (iaom.getName(), iaom.getAllowedValues(), iaom.getValue());
060: this .owner = owner;
061: this .uid = uid;
062: this .source = src;
063: }
064:
065: InterAgentCondition(InterAgentCondition other, UID uid,
066: MessageAddress src, Relay.Token owner) {
067: super (other.getName(), other.getAllowedValues(), other
068: .getValue());
069: this .owner = owner;
070: this .uid = uid;
071: this .source = src;
072: }
073:
074: InterAgentCondition(String name, OMCRangeList allowedValues) {
075: super (name, allowedValues);
076: }
077:
078: InterAgentCondition(String name, OMCRangeList allowedValues,
079: Comparable initialValue) {
080: super (name, allowedValues, initialValue);
081: }
082:
083: // UniqueObject implementation
084: public UID getUID() {
085: return uid;
086: }
087:
088: // Initialization methods
089: /**
090: * Set the message address of the target. This implementation
091: * presumes that there is but one target.
092: * @param target the address of the target agent.
093: **/
094: public void setTarget(MessageAddress target) {
095: targets = Collections.singleton(target);
096: }
097:
098: /**
099: * Set the UID (unique identifier) of this UniqueObject. Used only
100: * during initialization.
101: * @param uid the UID to be given to this
102: **/
103: public void setUID(UID uid) {
104: if (this .uid != null)
105: throw new RuntimeException("Attempt to change UID");
106: this .uid = uid;
107: }
108:
109: // Relay.Source implementation
110: /**
111: * Get all the addresses of the target agents to which this Relay
112: * should be sent. For this implementation this is always a
113: * singleton set contain just one target.
114: **/
115: public Set getTargets() {
116: return targets;
117: }
118:
119: /**
120: * Get an object representing the value of this Relay suitable
121: * for transmission. This implementation uses itself to represent
122: * its Content.
123: **/
124: public Object getContent() {
125: return this ;
126: }
127:
128: /**
129: * @return a factory to convert the content to a Relay Target.
130: **/
131: public Relay.TargetFactory getTargetFactory() {
132: return InterAgentConditionFactory.INSTANCE;
133: }
134:
135: /**
136: * Set the response that was sent from a target. For LP use only.
137: * This implemenation does nothing because responses are not needed
138: * or used.
139: **/
140: public int updateResponse(MessageAddress target, Object response) {
141: // No response expected
142: return Relay.NO_CHANGE;
143: }
144:
145: /**
146: * This factory creates a new InterAgentCondition.
147: **/
148: private static class InterAgentConditionFactory implements
149: Relay.TargetFactory, java.io.Serializable {
150: public static final InterAgentConditionFactory INSTANCE = new InterAgentConditionFactory();
151:
152: private InterAgentConditionFactory() {
153: }
154:
155: public Relay.Target create(UID uid, MessageAddress source,
156: Object content, Relay.Token owner) {
157: InterAgentCondition iac = (InterAgentCondition) content;
158: return new InterAgentCondition(iac, uid, source, owner);
159: }
160:
161: private Object readResolve() {
162: return INSTANCE;
163: }
164: }
165:
166: // Relay.Target implementation
167: /**
168: * Get the address of the Agent holding the Source copy of
169: * this Relay.
170: **/
171: public MessageAddress getSource() {
172: return source;
173: }
174:
175: /**
176: * Get the current response for this target. Null indicates that
177: * this target has no response. This implementation never has a
178: * response so it always returns null.
179: **/
180: public Object getResponse() {
181: return null;
182: }
183:
184: /**
185: * Update with new content. The only part of the source content used
186: * is the value of the operating mode. This will accept an InterAgentOperatingMode
187: * or an InterAgentCondition as the content. Anything else will cause a ClassCastException.
188: * @return true if the update changed the Relay. The LP should
189: * publishChange the Relay. This implementation returns true only
190: * if the new value differs from the current value.
191: **/
192: public int updateContent(Object content, Relay.Token token) {
193: if (token != owner) {
194: Logger logger = Logging.getLogger(getClass());
195: if (logger.isInfoEnabled()) {
196: logger
197: .info("Ignoring \"Not owner\" bug in \"updateContent()\","
198: + " possibly a rehydration bug (token="
199: + token + ", owner=" + owner + ")");
200: }
201: }
202: if (content instanceof InterAgentOperatingMode) {
203: InterAgentOperatingMode newMode = (InterAgentOperatingMode) content;
204: if (getValue().compareTo(newMode.getValue()) != 0) {
205: setValue(newMode.getValue());
206: return Relay.CONTENT_CHANGE;
207: }
208: } else {
209: // In this case this should be an InterAgentCondition. This currently has a Protected
210: // contructor, so this is probably not the case, but it used this way in
211: // CPURemoteTestPlugin. Let it throw the ClassCastException if it's anything else.
212: InterAgentCondition newCond = (InterAgentCondition) content;
213: if (getValue().compareTo(newCond.getValue()) != 0) {
214: setValue(newCond.getValue());
215: return Relay.CONTENT_CHANGE;
216: }
217: }
218: return Relay.NO_CHANGE;
219: }
220: }
|