001: /*
002: * <copyright>
003: *
004: * Copyright 2000-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.servlet;
028:
029: import java.net.URLEncoder;
030: import java.util.List;
031:
032: import javax.servlet.http.HttpServlet;
033:
034: import org.cougaar.core.component.BindingSite;
035: import org.cougaar.core.component.Component;
036: import org.cougaar.core.component.ServiceBroker;
037: import org.cougaar.core.mts.MessageAddress;
038: import org.cougaar.core.service.AgentIdentificationService;
039: import org.cougaar.core.service.LoggingService;
040: import org.cougaar.core.service.ServletService;
041: import org.cougaar.util.GenericStateModel;
042: import org.cougaar.util.GenericStateModelAdapter;
043: import org.cougaar.util.StateModelException;
044:
045: /**
046: * Abstract base-class for a Component that is also a Servlet.
047: * <p>
048: * This is very similar to BaseServletComponent, except that
049: * the component itself is registered as the servlet.
050: */
051: public abstract class ComponentServlet extends HttpServlet implements
052: Component {
053:
054: // default state model (no multiple inheritence!):
055: private final GenericStateModel gsm = new GenericStateModelAdapter() {
056: };
057:
058: // path parameter:
059: private String myPath;
060:
061: // subclasses are free to use both of these:
062: protected BindingSite bindingSite;
063: protected ServiceBroker serviceBroker;
064:
065: // this class handles the "servletService" details:
066: protected ServletService servletService;
067:
068: // the local agent address:
069: protected AgentIdentificationService agentIdService;
070: protected MessageAddress agentId;
071: protected String encAgentName;
072:
073: public ComponentServlet() {
074: super ();
075: }
076:
077: //
078: // inherits "doGet(..)" and all other HttpServlet methods
079: //
080:
081: /**
082: * Capture the (optional) load-time parameters.
083: * <p>
084: * This is typically a List of Strings.
085: */
086: public void setParameter(Object o) {
087: if (o instanceof String) {
088: myPath = (String) o;
089: } else if (o instanceof List) {
090: List l = (List) o;
091: if (l.size() > 0) {
092: Object o1 = l.get(0);
093: if (o1 instanceof String) {
094: myPath = (String) o1;
095: }
096: }
097: }
098: if (myPath != null && myPath.startsWith("path=")) {
099: myPath = myPath.substring("path=".length());
100: }
101: }
102:
103: /**
104: * Get the path for the Servlet's registration.
105: * <p>
106: * Typically supplied by the component parameter, but
107: * subclasses can hard-code the path by overriding
108: * this method.
109: */
110: protected String getPath() {
111: return myPath;
112: }
113:
114: protected MessageAddress getAgentIdentifier() {
115: return agentId;
116: }
117:
118: /** URL-encoded name of the local agent */
119: protected String getEncodedAgentName() {
120: return encAgentName;
121: }
122:
123: public void setBindingSite(BindingSite bindingSite) {
124: this .bindingSite = bindingSite;
125: }
126:
127: public void setServiceBroker(ServiceBroker sb) {
128: this .serviceBroker = sb;
129: }
130:
131: protected ServiceBroker getServiceBroker() {
132: return serviceBroker;
133: }
134:
135: public void setAgentIdentificationService(
136: AgentIdentificationService agentIdService) {
137: this .agentIdService = agentIdService;
138: if (agentIdService == null) {
139: // Revocation
140: } else {
141: this .agentId = agentIdService.getMessageAddress();
142: if (agentId != null) {
143: try {
144: String name = agentId.getAddress();
145: encAgentName = URLEncoder.encode(name, "UTF-8");
146: } catch (java.io.UnsupportedEncodingException e) {
147: // should never happen
148: throw new RuntimeException(
149: "Unable to encode to UTF-8?");
150: }
151: }
152: }
153: }
154:
155: public void initialize() throws StateModelException {
156: gsm.initialize();
157: }
158:
159: public void load() {
160: gsm.load();
161:
162: // get the servlet service, if available
163: servletService = (ServletService) serviceBroker.getService(
164: this , ServletService.class, null);
165: if (servletService == null) {
166: LoggingService log = (LoggingService) serviceBroker
167: .getService(this , LoggingService.class, null);
168: if (log != null && log.isWarnEnabled()) {
169: log.warn("Unable to obtain servlet service");
170: }
171: return;
172: }
173:
174: // register this servlet
175: String path = getPath();
176: try {
177: servletService.register(path, this );
178: } catch (Exception e) {
179: String failMsg = (path == null ? "Servlet path not specified"
180: : "Unable to register servlet with path \"" + path
181: + "\"");
182: throw new RuntimeException(failMsg, e);
183: }
184:
185: // unlike ComponentPlugin, we typically do NOT want
186: // BlackboardService or AlarmService or SchedulerService,
187: // since servlets run in the servlet server's thread.
188: //
189: // see the BlackboardQueryService for simple blackboard
190: // access.
191: }
192:
193: public void start() throws StateModelException {
194: gsm.start();
195: }
196:
197: public void suspend() throws StateModelException {
198: gsm.suspend();
199: }
200:
201: public void resume() throws StateModelException {
202: gsm.resume();
203: }
204:
205: public void stop() throws StateModelException {
206: gsm.stop();
207: }
208:
209: public void halt() throws StateModelException {
210: gsm.halt();
211: }
212:
213: public int getModelState() {
214: return gsm.getModelState();
215: }
216:
217: public void unload() {
218: gsm.unload();
219: // release the servlet service, which will automatically
220: // unregister the servlet
221: if (servletService != null) {
222: serviceBroker.releaseService(this , ServletService.class,
223: servletService);
224: servletService = null;
225: }
226: if (agentIdService != null) {
227: serviceBroker.releaseService(this ,
228: AgentIdentificationService.class, agentIdService);
229: agentIdService = null;
230: }
231: // your subclass should also release its services here!
232: }
233: }
|