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: package org.cougaar.lib.aggagent.servlet;
027:
028: import java.util.Enumeration;
029: import java.util.Hashtable;
030: import java.util.List;
031:
032: import javax.servlet.Servlet;
033:
034: import org.cougaar.core.blackboard.Subscription;
035: import org.cougaar.core.component.BindingSite;
036: import org.cougaar.core.component.ServiceBroker;
037: import org.cougaar.core.plugin.ComponentPlugin;
038: import org.cougaar.core.service.LoggingService;
039: import org.cougaar.core.service.ServletService;
040: import org.cougaar.core.service.wp.WhitePagesService;
041:
042: /**
043: * The Blackboard Servlet Component provides services required for both
044: * Servlet and full blackboard service access.
045: */
046: public abstract class BlackboardServletComponent extends
047: ComponentPlugin {
048: /** correspondence between Servlets and subscriptions */
049: private Hashtable subscribers = new Hashtable();
050:
051: /**
052: * This is the path for my Servlet, relative to the
053: * Agent's URLEncoded name.
054: */
055: protected String myPath = null;
056:
057: protected Servlet myServlet = null;
058:
059: /**
060: * Save our service broker during initialization.
061: */
062: private ServiceBroker serviceBroker = null;
063:
064: /**
065: * To launch our Servlet we will use the
066: * "<code>ServletService</code>" Servlet Registration Service,
067: * which is obtained from the <tt>serviceBroker</tt>.
068: * <p>
069: * This is used during "load()" and "unload()".
070: */
071: private ServletService servletService = null;
072:
073: /**
074: * Needed since this servlet needs to be able to acquire a list of all
075: * available agents.
076: */
077: protected WhitePagesService wps = null;
078:
079: /** Holds value of property loggingService. */
080: protected LoggingService log;
081:
082: /**
083: * Constructor.
084: */
085: public BlackboardServletComponent() {
086: super ();
087: }
088:
089: /**
090: * Subscriptions are generally created dynamically based on servlet requests
091: * in the aggregator code-base.
092: */
093: public void setupSubscriptions() {
094: }
095:
096: /**
097: * Used to inform subscription listeners (which were dynamically created in
098: * response to servlet requests) that their subscription changed.
099: */
100: public void execute() {
101: synchronized (subscribers) {
102: Enumeration subscriptions = subscribers.keys();
103: while (subscriptions.hasMoreElements()) {
104: Subscription subscription = (Subscription) subscriptions
105: .nextElement();
106: if (subscription.hasChanged()) {
107: SubscriptionListener subscriptionListener = (SubscriptionListener) subscribers
108: .get(subscription);
109: // remove a listener if it no longer exists
110: if (subscriptionListener == null) {
111: subscribers.remove(subscription);
112: } else {
113: subscriptionListener
114: .subscriptionChanged(subscription);
115: }
116: }
117: }
118: }
119: }
120:
121: /**
122: * Subscription monitoring support for use by servlets
123: */
124: protected SubscriptionMonitorSupport createSubscriptionSupport() {
125: SubscriptionMonitorSupport sms = new SubscriptionMonitorSupport() {
126: public void setSubscriptionListener(
127: Subscription subscription,
128: SubscriptionListener subscriptionListener) {
129: synchronized (subscribers) {
130: subscribers.put(subscription, subscriptionListener);
131: }
132: }
133:
134: public void removeSubscriptionListener(
135: Subscription subscription) {
136: synchronized (subscribers) {
137: subscribers.remove(subscription);
138: }
139: }
140: };
141: return sms;
142: }
143:
144: /**
145: * Capture servlet path here.
146: */
147: public void setParameter(Object o) {
148: // expecting a List of [String]
149: if (!(o instanceof List)) {
150: throw new IllegalArgumentException(
151: "Expecting a List parameter, not : "
152: + ((o != null) ? o.getClass().getName()
153: : "null"));
154: }
155: List l = (List) o;
156: if (l.size() != 1) {
157: throw new IllegalArgumentException(
158: "Expecting a List with one element,"
159: + " \"path\", not " + l.size());
160: }
161: Object o1 = l.get(0);
162: if (!(o1 instanceof String)) {
163: throw new IllegalArgumentException(
164: "Expecting one String, not (" + o1 + ")");
165: }
166:
167: // save the servlet path
168: this .myPath = (String) o1;
169: }
170:
171: /**
172: * Save our ServiceBroker during initialization.
173: * <p>
174: * This method is called when this class is created.
175: */
176: public void setBindingSite(BindingSite bs) {
177: super .setBindingSite(bs);
178: this .serviceBroker = bs.getServiceBroker();
179: }
180:
181: /**
182: * When this class is created the "load()" method will
183: * be called, at which time we'll register our Servlet.
184: */
185: public void load() {
186: super .load();
187:
188: // get the servlet service
189: servletService = (ServletService) serviceBroker.getService(
190: this , ServletService.class, null);
191: if (servletService == null) {
192: throw new RuntimeException(
193: "Unable to obtain ServletService");
194: }
195:
196: // register our servlet
197: try {
198: servletService.register(myPath, myServlet);
199: } catch (Exception e) {
200: throw new RuntimeException(
201: "Unable to register servlet with path \"" + myPath
202: + "\": " + e.getMessage());
203: }
204:
205: // get the white pages service (for "listAgentNames")
206: wps = (WhitePagesService) serviceBroker.getService(this ,
207: WhitePagesService.class, null);
208: if (wps == null) {
209: throw new RuntimeException(
210: "Unable to obtain white pages service");
211: }
212: }
213:
214: /**
215: * When our class is unloaded we must release our service.
216: * <p>
217: * This will automatically unregister our Servlet.
218: */
219: public void unload() {
220: // release white pages service
221: if (wps != null) {
222: serviceBroker.releaseService(this , WhitePagesService.class,
223: wps);
224: }
225:
226: // release our servlet service
227: if (servletService != null) {
228: serviceBroker.releaseService(this , ServletService.class,
229: servletService);
230: }
231: super .unload();
232: }
233:
234: /**
235: * Pretty to-String for debugging.
236: */
237: public String toString() {
238: return getClass().getName() + "(" + myPath + ")";
239: }
240:
241: /** Getter for property loggingService.
242: * @return Value of property loggingService.
243: */
244: public LoggingService getLoggingService() {
245: return this .log;
246: }
247:
248: /** Setter for property loggingService.
249: * @param loggingService New value of property loggingService.
250: */
251: public void setLoggingService(LoggingService loggingService) {
252: this.log = loggingService;
253: }
254:
255: }
|