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.logistics.servlet;
028:
029: import org.cougaar.core.blackboard.BlackboardClient;
030: import org.cougaar.core.service.BlackboardService;
031: import org.cougaar.core.service.AlarmService;
032: import org.cougaar.core.servlet.ComponentServlet;
033: import org.cougaar.planning.ldm.plan.Role;
034: import org.cougaar.servicediscovery.description.AvailabilityChangeMessage;
035: import org.cougaar.servicediscovery.description.ProviderCapabilities;
036: import org.cougaar.servicediscovery.description.ProviderCapability;
037: import org.cougaar.servicediscovery.transaction.ServiceContractRelay;
038: import org.cougaar.util.MutableTimeSpan;
039: import org.cougaar.util.UnaryPredicate;
040: import org.cougaar.util.log.Logger;
041: import org.cougaar.util.log.Logging;
042:
043: import javax.servlet.http.HttpServletRequest;
044: import javax.servlet.http.HttpServletResponse;
045: import java.io.IOException;
046: import java.io.PrintWriter;
047: import java.text.ParsePosition;
048: import java.text.SimpleDateFormat;
049: import java.util.ArrayList;
050: import java.util.Collection;
051: import java.util.Collections;
052: import java.util.Date;
053: import java.util.Iterator;
054: import java.util.List;
055:
056: public class AvailabilityServlet extends ComponentServlet implements
057: BlackboardClient {
058:
059: private BlackboardService blackboard;
060: private AlarmService alarmService;
061: private List registeredRoles;
062: private final static String PATH = "/availabilityServlet";
063: private final static String ROLE = "role";
064: private final static String AVAILABILITY = "Availability";
065: private final static String START_DATE = "startdate";
066: private final static String END_DATE = "enddate";
067: private final static String ACTION_PARAM = "action";
068: private final static String PUBLISH = "Publish All Rows";
069: private final static String ADD = "Add";
070: private final static String CLEAR = "clear";
071: private final static String CLEAR_SELECTED_ROWS = "Clear Selected Rows";
072: private final static String BACK = "BACK";
073:
074: private List changeMessages = new ArrayList();
075: private static Logger logger = Logging
076: .getLogger(AvailabilityServlet.class);
077: private PrintWriter out;
078: private HttpServletRequest request;
079:
080: public void init() {
081: // get the blackboard service
082: blackboard = (BlackboardService) serviceBroker.getService(this ,
083: BlackboardService.class, null);
084: if (blackboard == null) {
085: throw new RuntimeException(
086: "Unable to obtain blackboard service");
087: }
088: alarmService = (AlarmService) serviceBroker.getService(this ,
089: AlarmService.class, null);
090: if (alarmService == null) {
091: throw new RuntimeException("Unable to set alarm service");
092: }
093: }
094:
095: public void unload() {
096: super .unload();
097: // release the blackboard service
098: if (blackboard != null) {
099: serviceBroker.releaseService(this , BlackboardService.class,
100: blackboard);
101: blackboard = null;
102: }
103: }
104:
105: protected String getPath() {
106: return PATH;
107: }
108:
109: // BlackboardClient method:
110: public String getBlackboardClientName() {
111: return toString();
112: }
113:
114: // BlackboardClient method:
115: public long currentTimeMillis() {
116: return alarmService.currentTimeMillis();
117: }
118:
119: protected static UnaryPredicate availabilityPred = new UnaryPredicate() {
120: public boolean execute(Object o) {
121: return o instanceof AvailabilityChangeMessage;
122: }
123: };
124:
125: public void doGet(HttpServletRequest req, HttpServletResponse res)
126: throws IOException {
127: out = res.getWriter();
128: request = req;
129: registeredRoles = getProviderRoles();
130: String start_date_string = request.getParameter(START_DATE);
131: String end_date_string = request.getParameter(END_DATE);
132: String role = request.getParameter(ROLE);
133: String available = request.getParameter(AVAILABILITY);
134: String action = request.getParameter(ACTION_PARAM);
135: boolean isAvailable = true;
136: if (available != null) {
137: isAvailable = available.equals("available");
138: }
139: SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
140: Date start_date = null;
141: Date end_date = null;
142: if (end_date_string != null) {
143: end_date = dateFormat.parse(end_date_string,
144: new ParsePosition(0));
145: }
146: if (start_date_string != null) {
147: start_date = dateFormat.parse(start_date_string,
148: new ParsePosition(0));
149: }
150: long now = currentTimeMillis();
151: printTitles();
152: printInfo(now);
153: try {
154: if (action == null) {
155: printForm();
156: } else if (action.equals(ADD)) {
157: if (end_date == null) {
158: printError("Could not read date; try again.");
159: printForm();
160: } else if (end_date.getTime() < now) {
161: printError("End date must be in the future; try again.");
162: printForm();
163: } else {
164: addChangeMessage(start_date, end_date, role,
165: isAvailable);
166: }
167: } else if (action.equals(CLEAR_SELECTED_ROWS)) {
168: clearSelectedRows();
169: } else if (action.equals(PUBLISH)) {
170: publish();
171: } else if (action.equals(BACK)) {
172: printForm();
173: }
174: } catch (Exception e) {
175: printError("Servlet error: " + e);
176: } finally {
177: if (blackboard.isTransactionOpen()) {
178: blackboard.closeTransactionDontReset();
179: }
180: out.println("</body>");
181: out.flush();
182: }
183: }
184:
185: private void clearSelectedRows() {
186: String paramValues[] = request.getParameterValues(CLEAR);
187: if (paramValues != null) {
188: for (int i = 0; i < paramValues.length; i++) {
189: int index = Integer.parseInt(paramValues[i]);
190: changeMessages.remove(index);
191: }
192: } else {
193: printError("You must select a row to clear");
194: }
195: printForm();
196: printSelections();
197: }
198:
199: private void addChangeMessage(Date start_date, Date end_date,
200: String role, boolean available) {
201: printForm();
202: MutableTimeSpan span = new MutableTimeSpan();
203: span.setTimeSpan(start_date.getTime(), end_date.getTime());
204: AvailabilityChangeMessage message = new AvailabilityChangeMessage(
205: Role.getRole(role), false, span, available);
206: changeMessages.add(message);
207: printSelections();
208: }
209:
210: private void publish() {
211: blackboard.openTransaction();
212: for (Iterator iterator = changeMessages.iterator(); iterator
213: .hasNext();) {
214: AvailabilityChangeMessage acm = (AvailabilityChangeMessage) iterator
215: .next();
216: blackboard.publishAdd(acm);
217: }
218: blackboard.closeTransaction();
219: printChangeInfo(changeMessages);
220: changeMessages.clear();
221:
222: }
223:
224: private List getProviderRoles() {
225: Collection capabilites = getProviderCapabilities();
226: List roles = new ArrayList();
227: for (Iterator iterator = capabilites.iterator(); iterator
228: .hasNext();) {
229: ProviderCapability pc = (ProviderCapability) iterator
230: .next();
231: pc.getRole();
232: roles.add(pc.getRole());
233: }
234: return roles;
235: }
236:
237: private void printTitles() {
238: String title = "Availability Servlet";
239: out.println("<HTML><HEAD><TITLE>" + title
240: + "</TITLE></HEAD></HTML>" + "<BODY><H1>" + title
241: + "</H1>");
242: }
243:
244: private void printInfo(long now) {
245: String localAgent = getEncodedAgentName();
246: out.println("<p>\n" + "Agent: " + localAgent + "<p>\n"
247: + "Current Society Time: " + new Date(now));
248: }
249:
250: private void printForm() {
251: // Display the registered roles in a table
252: out.print("<p>\n" + "<table border>" + "<tr><th colspan=1>"
253: + "Registered Provider Roles" + "</th>"
254: + "<th colspan=1>" + "Active Contracts" + "</th></tr>");
255: Iterator iter = registeredRoles.iterator();
256: StringBuffer roleOptions = new StringBuffer();
257: while (iter.hasNext()) {
258: Role role = (Role) iter.next();
259: String client = "No";
260: if (hasServiceContract(role)) {
261: client = "Yes";
262: }
263: out.print("<tr><td>" + role + "</td><td align=center>"
264: + client + "</td></tr>");
265: roleOptions.append("<option value=\"" + role + "\">" + role
266: + "</option>" + "\n");
267: }
268: out.print("</table>");
269: out.print("<form method=\"GET\" action=\""
270: + request.getRequestURI() + "\">\n" + "Select role: "
271: + "<select size=1 name=\"" + ROLE + "\">\n"
272: + roleOptions.toString() + "</select>"
273: + "<input type=radio name=\"" + AVAILABILITY
274: + "\" value=\"available\">Available"
275: + "<input type=radio name=\"" + AVAILABILITY
276: + "\" value=\"unavailable\">Unavailable<BR>"
277: + "<p>Enter new start date (MM/DD/YYYY): "
278: + "<input type=\"text\" name=\"" + START_DATE
279: + "\" size=40>\n" + "</select>"
280: + "<p>Enter new end date (MM/DD/YYYY): "
281: + "<input type=\"text\" name=\"" + END_DATE
282: + "\" size=40>\n" + "<p><input type=submit name=\""
283: + ACTION_PARAM + "\" value=\"" + ADD + "\">\n"
284: + "</form>\n");
285: //printSelections(out);
286: }
287:
288: private void printSelections() {
289: if (changeMessages.size() == 0) {
290: return;
291: }
292: out.print("<form method=\"GET\" action=\""
293: + request.getRequestURI() + "\">\n");
294: // Table column headers
295: out.print("<p>\n" + "<table border>" + "<tr>"
296: + "<th colspan=1>" + "Role" + "</th>"
297: + "<th colspan=1>" + "Availability" + "</th>"
298: + "<th colspan=1>" + "Start" + "</th>"
299: + "<th colspan=1>" + "End" + "</th>" + "<th colspan=1>"
300: + "Clear Row" + "</th>" + "</tr>");
301:
302: // table row elements
303: for (int i = 0; i < changeMessages.size(); i++) {
304: AvailabilityChangeMessage acm = (AvailabilityChangeMessage) changeMessages
305: .get(i);
306: out.print("<tr>"
307: + "<td>"
308: + acm.getRole().toString()
309: + "</td>"
310: + "<td>"
311: + getAvailabilityString(acm.isAvailable())
312: + "</td>"
313: + "<td>"
314: + new Date(acm.getTimeSpan().getStartTime())
315: .toString()
316: + "</td>"
317: + "<td>"
318: + new Date(acm.getTimeSpan().getEndTime())
319: .toString() + "</td>" + "<td>"
320: + "<input type=checkbox name=\"" + CLEAR
321: + "\" value=\"" + i + "\">Clear" + "</td>"
322: + "</tr>");
323: }
324: out
325: .print("<tr><td colspan=5 align=right><input type=submit name=\""
326: + ACTION_PARAM
327: + "\" value=\""
328: + CLEAR_SELECTED_ROWS + "\">\n");
329: out.println("</td></tr>");
330: out.print("</table>");
331: out.print("<p><input type=submit name=\"" + ACTION_PARAM
332: + "\" value=\"" + PUBLISH + "\">\n");
333: out.print("</form>");
334: }
335:
336: private void printChangeInfo(Collection messages) {
337: out.println("<p>\n");
338: out.println("Successfully posted availability change:");
339: for (Iterator iterator = messages.iterator(); iterator
340: .hasNext();) {
341: AvailabilityChangeMessage message = (AvailabilityChangeMessage) iterator
342: .next();
343: out.println("<ul><li>Role: " + message.getRole()
344: + "<li>Available: "
345: + getAvailabilityString(message.isAvailable())
346: + "<li>Start Date: "
347: + new Date(message.getTimeSpan().getStartTime())
348: + "<li>End Date: "
349: + new Date(message.getTimeSpan().getEndTime())
350: + "<li>Registry Updated: "
351: + message.isRegistryUpdated() + "</ul>");
352: }
353:
354: out.print("<form method=\"GET\" action=\""
355: + request.getRequestURI() + "\">\n"
356: + "<p><input type=submit name=\"" + ACTION_PARAM
357: + "\" value=\"" + BACK + "\">\n" + "</form>\n");
358:
359: }
360:
361: private void printError(String text) {
362: out.println("<p>\n" + "<b>" + text + "</b>" + "<p>");
363: }
364:
365: private String getAvailabilityString(boolean available) {
366: if (available == true) {
367: return "Available";
368: } else
369: return "Unavailable";
370: }
371:
372: private boolean hasServiceContract(Role role) {
373: blackboard.openTransaction();
374: Collection serviceContracts = blackboard
375: .query(serviceContractRelayPred);
376: blackboard.closeTransaction();
377: for (Iterator iterator = serviceContracts.iterator(); iterator
378: .hasNext();) {
379: ServiceContractRelay scr = (ServiceContractRelay) iterator
380: .next();
381: if (role.equals(scr.getServiceContract().getServiceRole())) {
382: return true;
383: }
384: }
385: return false;
386: }
387:
388: protected static UnaryPredicate capabilitiesPred = new UnaryPredicate() {
389: public boolean execute(Object o) {
390: return (o instanceof ProviderCapabilities);
391: }
392: };
393:
394: private UnaryPredicate serviceContractRelayPred = new UnaryPredicate() {
395: public boolean execute(Object o) {
396: if (o instanceof ServiceContractRelay) {
397: ServiceContractRelay relay = (ServiceContractRelay) o;
398: return (relay.getProviderName()
399: .equals(getEncodedAgentName()));
400: } else {
401: return false;
402: }
403: }
404: };
405:
406: public Collection getProviderCapabilities() {
407: blackboard.openTransaction();
408: Collection capCollect = blackboard.query(capabilitiesPred);
409: blackboard.closeTransaction();
410: if (capCollect.isEmpty()) {
411: return Collections.EMPTY_LIST;
412: }
413: // I think there should only be one
414: if (capCollect.size() > 1) {
415: if (logger.isErrorEnabled())
416: logger
417: .error("There is more than one ProviderCapability object: "
418: + capCollect.size());
419: }
420: ProviderCapabilities pc = (ProviderCapabilities) capCollect
421: .iterator().next();
422: Collection capabilites = pc.getCapabilities();
423: return capabilites;
424: }
425: }
|