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.ArrayList;
030: import java.util.Collections;
031: import java.util.Iterator;
032: import java.util.List;
033: import java.util.Set;
034:
035: import org.cougaar.core.blackboard.IncrementalSubscription;
036: import org.cougaar.core.component.ServiceBroker;
037: import org.cougaar.core.component.ServiceProvider;
038: import org.cougaar.core.plugin.ComponentPlugin;
039: import org.cougaar.core.service.BlackboardService;
040: import org.cougaar.core.service.ConditionService;
041: import org.cougaar.core.service.LoggingService;
042: import org.cougaar.util.KeyedSet;
043: import org.cougaar.util.UnaryPredicate;
044:
045: /**
046: * This Plugin serves as an ConditionServiceProvider. It
047: * subscribes to {@link Condition}s using a subscription allowing
048: * immediate access to individual Conditions by name. Provides
049: * ConditionService to components needing name-based access to
050: * Conditions.
051: **/
052: public class ConditionServiceProvider extends ComponentPlugin implements
053: ServiceProvider {
054: /**
055: * A {@link KeyedSet} for sets of Conditions keyed by name.
056: **/
057: private static class ConditionSet extends KeyedSet {
058: public ConditionSet() {
059: super ();
060: makeSynchronized();
061: }
062:
063: protected Object getKey(Object o) {
064: Condition sm = (Condition) o;
065: return sm.getName();
066: }
067:
068: public Condition getCondition(String name) {
069: return (Condition) inner.get(name);
070: }
071: }
072:
073: /**
074: * An implementation of ConditionService in terms of the
075: * information in the ConditionSet.
076: **/
077: private class ConditionServiceImpl implements ConditionService {
078: public Condition getConditionByName(String knobName) {
079: synchronized (smSet) {
080: return smSet.getCondition(knobName);
081: }
082: }
083:
084: public Set getAllConditionNames() {
085: synchronized (smSet) {
086: return Collections.unmodifiableSet(smSet.keySet());
087: }
088: }
089:
090: public void addListener(Listener l) {
091: synchronized (listeners) {
092: listeners.add(l);
093: }
094: }
095:
096: public void removeListener(Listener l) {
097: synchronized (listeners) {
098: listeners.remove(l);
099: }
100: }
101: }
102:
103: private static UnaryPredicate ConditionPredicate = new UnaryPredicate() {
104: public boolean execute(Object o) {
105: return o instanceof Condition;
106: }
107: };
108:
109: private ConditionSet smSet = new ConditionSet();
110: private IncrementalSubscription conditions;
111:
112: private List listeners = new ArrayList(2);
113:
114: private LoggingService logger;
115:
116: /**
117: * Override base class method to register our service with the
118: * service broker.
119: **/
120: public void load() {
121: super .load();
122: logger = (LoggingService) getServiceBroker().getService(this ,
123: LoggingService.class, null);
124: getServiceBroker().addService(ConditionService.class, this );
125: }
126:
127: public void unload() {
128: getServiceBroker().releaseService(this , LoggingService.class,
129: logger);
130: getServiceBroker().revokeService(ConditionService.class, this );
131: super .unload();
132: }
133:
134: /**
135: * Standard setupSubscriptions subscribes to all Conditions.
136: **/
137: public void setupSubscriptions() {
138: synchronized (smSet) {
139: conditions = (IncrementalSubscription) getBlackboardService()
140: .subscribe(ConditionPredicate);
141: smSet.addAll(conditions);
142: }
143: }
144:
145: /**
146: * Standard execute method does nothing. Our subscription
147: * automatically maintains the information of interest in smSet
148: * where it is referenced directly by the service API.
149: **/
150: public void execute() {
151: if (conditions.hasChanged()) {
152: synchronized (smSet) {
153: smSet.addAll(conditions.getAddedCollection());
154: smSet.removeAll(conditions.getRemovedCollection());
155: }
156: fireListeners();
157: }
158: }
159:
160: private void fireListeners() {
161: BlackboardService bb = getBlackboardService();
162: if (logger.isDebugEnabled()) {
163: for (Iterator i = conditions.getAddedCollection()
164: .iterator(); i.hasNext();) {
165: logger.debug("Condition added: " + i.next());
166: }
167: for (Iterator i = conditions.getChangedCollection()
168: .iterator(); i.hasNext();) {
169: logger.debug("Condition changed: " + i.next());
170: }
171: for (Iterator i = conditions.getRemovedCollection()
172: .iterator(); i.hasNext();) {
173: logger.debug("Condition removed: " + i.next());
174: }
175: logger.debug("ConditionServiceProvider.fireListeners:");
176: }
177: for (Iterator i = listeners.iterator(); i.hasNext();) {
178: Object o = i.next();
179: if (logger.isDebugEnabled())
180: logger.debug(" " + o);
181: bb.publishChange(o);
182: }
183: }
184:
185: /**
186: * Gets (creates) an implementation of the ConditionService.
187: * This is part of our implementation of the ServiceProvider API.
188: **/
189: public Object getService(ServiceBroker sb, Object requestor,
190: Class serviceClass) {
191: if (serviceClass == ConditionService.class) {
192: return new ConditionServiceImpl();
193: }
194: throw new IllegalArgumentException(getClass()
195: + " does not furnish " + serviceClass);
196: }
197:
198: /**
199: * Releases an implementation of the ConditionService.
200: * This is part of our implementation of the ServiceProvider API.
201: **/
202: public void releaseService(ServiceBroker sb, Object requestor,
203: Class serviceClass, Object svc) {
204: if (serviceClass != ConditionService.class
205: || svc.getClass() != ConditionServiceImpl.class) {
206: throw new IllegalArgumentException(getClass()
207: + " did not furnish " + svc);
208: }
209: }
210: }
|