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: package org.cougaar.core.qos.ca;
028:
029: import java.lang.reflect.Constructor;
030: import java.util.ArrayList;
031: import java.util.Iterator;
032: import java.util.StringTokenizer;
033:
034: import org.cougaar.core.component.ServiceBroker;
035: import org.cougaar.core.component.ServiceProvider;
036: import org.cougaar.core.plugin.ParameterizedPlugin;
037: import org.cougaar.core.service.LoggingService;
038: import org.cougaar.core.service.ThreadService;
039: import org.cougaar.core.thread.Schedulable;
040:
041: /**
042: * This plugin provides the {@link CoordinationArtifactBroker}
043: * service, which is implemented by an inner class.
044: */
045: public class CoordinationArtifactBrokerPlugin extends
046: ParameterizedPlugin implements ServiceProvider {
047: private static final String[] StandardProviders = {
048: "org.cougaar.ca.artifacts.JessAlarmArtifactProvider",
049: "org.cougaar.ca.artifacts.JessMetricsServiceCoordinationArtifactProvider", };
050:
051: private static final String ProvidersParam = "providers";
052: private ArrayList localProviders;
053: private CoordinationArtifactBroker impl;
054: private LoggingService log;
055:
056: public void load() {
057: super .load();
058:
059: ServiceBroker sb = getServiceBroker();
060: impl = new Impl(sb);
061: sb.addService(CoordinationArtifactBroker.class, this );
062:
063: log = (LoggingService) sb.getService(this ,
064: LoggingService.class, null);
065: }
066:
067: public void start() {
068: super .start();
069: localProviders = new ArrayList();
070: ServiceBroker sb = getServiceBroker();
071: synchronized (localProviders) {
072: for (int i = 0; i < StandardProviders.length; i++) {
073: makeProvider(StandardProviders[i], sb);
074: }
075:
076: String providers = getParameter(ProvidersParam);
077: if (providers != null) {
078: StringTokenizer tk = new StringTokenizer(providers, ",");
079: while (tk.hasMoreTokens()) {
080: String klass = tk.nextToken();
081: makeProvider(klass, sb);
082: }
083: }
084: }
085: }
086:
087: private void makeProvider(String klass, ServiceBroker sb) {
088: Object provider = null;
089: try {
090: Class cl = Class.forName(klass);
091: Class[] ptypes = { ServiceBroker.class };
092: Object[] args = { sb };
093: Constructor cons = cl.getConstructor(ptypes);
094: provider = cons.newInstance(args);
095: if (provider instanceof CoordinationArtifactProviderImpl) {
096: localProviders.add(provider);
097: if (log.isInfoEnabled())
098: log.info("Created provider " + provider);
099: } else {
100: if (log.isWarnEnabled())
101: log.warn(klass
102: + " is not a CoordinationArtifactProvider");
103: }
104: } catch (Exception ex) {
105: if (log.isWarnEnabled())
106: log
107: .warn("Couldn't instantiate CoordinationArtifactProvider "
108: + klass);
109: }
110: }
111:
112: // plugin
113: protected void execute() {
114: }
115:
116: protected void setupSubscriptions() {
117: }
118:
119: // ServiceProvider Interface
120: public Object getService(ServiceBroker sb, Object requestor,
121: Class serviceClass) {
122: if (serviceClass == CoordinationArtifactBroker.class) {
123: return impl;
124: } else {
125: return null;
126: }
127: }
128:
129: public void releaseService(ServiceBroker sb, Object requestor,
130: Class serviceClass, Object service) {
131: }
132:
133: private static class Provisioner {
134: ConnectionSpec spec;
135: RolePlayer player;
136: CoordinationArtifactProvider cap;
137:
138: Provisioner(ConnectionSpec spec, RolePlayer player,
139: CoordinationArtifactProvider cap) {
140: this .spec = spec;
141: this .player = player;
142: this .cap = cap;
143: }
144:
145: void provide() {
146: cap.provideFacet(spec, player);
147: }
148: }
149:
150: private static class PendingRequest {
151: ConnectionSpec spec;
152: RolePlayer player;
153:
154: PendingRequest(ConnectionSpec spec, RolePlayer player) {
155: this .spec = spec;
156: this .player = player;
157: }
158: }
159:
160: private class Impl implements CoordinationArtifactBroker {
161: ThreadService tsvc;
162: ArrayList pendingRequests, pendingProvides;
163: ArrayList providers;
164: Schedulable requestsThread, providesThread;
165: ServiceBroker sb;
166:
167: Impl(ServiceBroker sb) {
168: tsvc = (ThreadService) sb.getService(this ,
169: ThreadService.class, null);
170: pendingRequests = new ArrayList();
171: pendingProvides = new ArrayList();
172: providers = new ArrayList();
173: Runnable requests_runner = new Runnable() {
174: public void run() {
175: checkPendingRequests();
176: }
177: };
178: Runnable provides_runner = new Runnable() {
179: public void run() {
180: checkPendingProvides();
181: }
182: };
183: requestsThread = tsvc.getThread(this , requests_runner,
184: "ArtifactBroker req");
185: providesThread = tsvc.getThread(this , provides_runner,
186: "ArtifactBroker prv");
187: this .sb = sb;
188: }
189:
190: public void requestFacet(ConnectionSpec spec,
191: RolePlayer rolePlayer) {
192: // assume one queued request per player
193: synchronized (pendingRequests) {
194: if (log.isDebugEnabled())
195: log.debug("Pending request for " + spec.ca_kind
196: + " " + spec.role);
197: pendingRequests
198: .add(new PendingRequest(spec, rolePlayer));
199: requestsThread.start();
200: }
201: }
202:
203: private void provide(ConnectionSpec spec, RolePlayer player,
204: CoordinationArtifactProvider cap) {
205: // assume one queued request per player
206: if (log.isDebugEnabled())
207: log.debug("Queue provision of " + cap);
208: synchronized (pendingProvides) {
209: Provisioner p = new Provisioner(spec, player, cap);
210: pendingProvides.add(p);
211: providesThread.start();
212: }
213: }
214:
215: public void registerCoordinationArtifactProvider(
216: CoordinationArtifactProvider cat) {
217: synchronized (providers) {
218: providers.add(cat);
219: }
220: if (log.isDebugEnabled())
221: log.debug("Registered artifact for "
222: + cat.getArtifactKind());
223: requestsThread.start();
224: }
225:
226: // The body of the Schedulable
227: private void checkPendingRequests() {
228: synchronized (pendingRequests) {
229: Iterator itr = pendingRequests.iterator();
230: while (itr.hasNext()) {
231: PendingRequest pr = (PendingRequest) itr.next();
232: RolePlayer player = pr.player;
233: ConnectionSpec spec = pr.spec;
234: if (findFacet(spec, player))
235: itr.remove();
236: }
237: }
238: }
239:
240: private void checkPendingProvides() {
241: synchronized (pendingProvides) {
242: Iterator itr = pendingProvides.iterator();
243: while (itr.hasNext()) {
244: Provisioner p = (Provisioner) itr.next();
245: if (log.isDebugEnabled())
246: log.debug("Provision of " + p.cap);
247: p.provide();
248: }
249: }
250: }
251:
252: private boolean findFacet(ConnectionSpec spec, RolePlayer player) {
253: if (log.isDebugEnabled())
254: log.debug("Looking for " + spec.ca_kind + " "
255: + spec.role);
256: synchronized (providers) {
257: for (int i = 0; i < providers.size(); i++) {
258: CoordinationArtifactProvider cap = (CoordinationArtifactProvider) providers
259: .get(i);
260: if (cap.supports(spec)) {
261: if (log.isDebugEnabled())
262: log.debug("Found " + spec.ca_kind + " "
263: + spec.role);
264: provide(spec, player, cap);
265: return true;
266: }
267: }
268: }
269: if (log.isDebugEnabled())
270: log.debug("Didn't find " + spec.ca_kind + " "
271: + spec.role);
272: return false;
273: }
274:
275: }
276:
277: }
|