0001: /*
0002: * <copyright>
0003: *
0004: * Copyright 1997-2004 BBNT Solutions, LLC
0005: * under sponsorship of the Defense Advanced Research Projects
0006: * Agency (DARPA).
0007: *
0008: * You can redistribute this software and/or modify it under the
0009: * terms of the Cougaar Open Source License as published on the
0010: * Cougaar Open Source Website (www.cougaar.org).
0011: *
0012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023: *
0024: * </copyright>
0025: */
0026:
0027: package org.cougaar.mlm.plugin.organization;
0028:
0029: import java.util.*;
0030:
0031: import java.sql.SQLException;
0032: import java.sql.Statement;
0033: import java.sql.ResultSet;
0034: import java.sql.ResultSetMetaData;
0035: import java.sql.Connection;
0036:
0037: import java.text.NumberFormat;
0038: import java.text.DateFormat;
0039: import java.text.SimpleDateFormat;
0040: import java.text.ParseException;
0041:
0042: import org.cougaar.core.blackboard.IncrementalSubscription;
0043: import org.cougaar.core.util.UID;
0044:
0045: import org.cougaar.util.DBProperties;
0046: import org.cougaar.util.DBConnectionPool;
0047: import org.cougaar.util.Parameters;
0048: import org.cougaar.util.UnaryPredicate;
0049:
0050: import org.cougaar.core.plugin.ComponentPlugin;
0051:
0052: import org.cougaar.core.service.DomainService;
0053: import org.cougaar.core.service.ServletService;
0054: import org.cougaar.core.service.LoggingService;
0055: import org.cougaar.core.logging.LoggingServiceWithPrefix;
0056:
0057: import org.cougaar.planning.ldm.PlanningFactory;
0058: import org.cougaar.planning.ldm.plan.AspectType;
0059: import org.cougaar.planning.ldm.plan.AspectValue;
0060: import org.cougaar.planning.ldm.plan.ContextOfOplanIds; //import org.cougaar.planning.ldm.plan.ContextOfUIDs;
0061: import org.cougaar.planning.ldm.plan.NewTask;
0062: import org.cougaar.planning.ldm.plan.NewPrepositionalPhrase;
0063: import org.cougaar.planning.ldm.plan.AllocationResult;
0064: import org.cougaar.planning.ldm.plan.PlanElement;
0065: import org.cougaar.planning.ldm.plan.PrepositionalPhrase;
0066: import org.cougaar.planning.ldm.plan.Plan;
0067: import org.cougaar.planning.ldm.plan.Preference;
0068: import org.cougaar.planning.ldm.plan.RelationshipSchedule;
0069: import org.cougaar.planning.ldm.plan.ScoringFunction;
0070: import org.cougaar.planning.ldm.plan.Task;
0071: import org.cougaar.planning.ldm.plan.TimeAspectValue;
0072: import org.cougaar.planning.ldm.plan.Verb;
0073: import org.cougaar.planning.plugin.util.PluginHelper;
0074:
0075: import org.cougaar.glm.ldm.oplan.OplanStage;
0076: import org.cougaar.glm.ldm.asset.Organization;
0077:
0078: import javax.servlet.http.HttpServlet;
0079: import javax.servlet.http.HttpServletRequest;
0080: import javax.servlet.http.HttpServletResponse;
0081:
0082: import java.io.*;
0083:
0084: /**
0085: * The GLSInitServlet crams all of the functionality of the GLSGUIInitPlugin,
0086: * GLSGUIRescindPlugin, and SQLOplanPlugin sans GUIs into one plugin
0087: * The buttons are now in a client application which talks to the
0088: * servlets in this plugin to publish the oplan and gls tasks
0089: *
0090: **/
0091: public class GLSInitServlet extends ComponentPlugin implements
0092: GLSConstants {
0093:
0094: public static final String GETOPINFO = "getopinfo";
0095: public static final String PUBLISHGLS = "publishgls";
0096: public static final String RESCINDGLS = "rescindgls";
0097:
0098: // private static final String PUBLISH_ON_SELF_ORG = "PublishOnSelfOrg";
0099:
0100: public static final String QUERY_FILE = "oplan.q";
0101: private static final String TIME_QUERY_NAME = "OplanTimeframeQuery";
0102: private static final String STAGE_QUERY_NAME = "OplanStageQuery";
0103:
0104: public static final int LISTENING_TO_NOTHING = 0;
0105: public static final int LISTENING_TO_PROP_REG_SRVCS = 1;
0106: public static final int LISTENING_TO_PROP_FIND_PROV = 2;
0107: public static final int LISTENING_TO_GLS = 3;
0108: private static final long DATE_ERROR = Long.MIN_VALUE;
0109:
0110: static NumberFormat confidenceFormat = NumberFormat
0111: .getPercentInstance();
0112:
0113: private DBProperties dbp;
0114: private String database;
0115: private String username;
0116: private String password;
0117:
0118: private String oplanId;
0119:
0120: private static DateFormat cDateFormat = new SimpleDateFormat(
0121: "yyyy/MM/dd");
0122:
0123: /**
0124: * For making direct request on this plugin (not via servlet).
0125: **/
0126: public static class Request implements Serializable {
0127: private String command;
0128:
0129: public Request(String command) {
0130: this .command = command;
0131: }
0132: }
0133:
0134: private IncrementalSubscription glsSubscription;
0135:
0136: private IncrementalSubscription regSrvcsSubscription;
0137:
0138: private IncrementalSubscription findProvSubscription;
0139:
0140: private IncrementalSubscription myorgassets;
0141:
0142: private IncrementalSubscription requestSubscription;
0143:
0144: private static final String forRoot = "ForRoot".intern();
0145:
0146: // tells reply servlet when to push info
0147: private Object monitor = new Object();
0148:
0149: private static class MyPrivateState implements java.io.Serializable {
0150: boolean oplanInfoExists = false;
0151: boolean unpublishedChanges = false;
0152: int glsTaskNumber = 0;
0153: int prsTaskNumber = 0;
0154: int pfpTaskNumber = 0;
0155: OplanInfo opInfo;
0156: int listening_to = LISTENING_TO_NOTHING;
0157: boolean initialSendGLS = true;
0158: boolean initialSendFindProv = true;
0159: }
0160:
0161: private MyPrivateState myPrivateState;
0162:
0163: /**
0164: * This predicate selects for root GLStasks injected by the GLSInitServlet
0165: **/
0166: private UnaryPredicate glsPredicate = new UnaryPredicate() {
0167: public boolean execute(Object o) {
0168: if (!(o instanceof PlanElement))
0169: return false;
0170: PlanElement pe = (PlanElement) o;
0171: Task task = pe.getTask();
0172: if (!task.getVerb().equals(GET_LOG_SUPPORT))
0173: return false;
0174: if (!task.getSource().equals(getAgentIdentifier()))
0175: return false;
0176: if (!task.getDestination().equals(getAgentIdentifier()))
0177: return false;
0178: return (task.getPrepositionalPhrase(forRoot) != null);
0179: }
0180: };
0181:
0182: /**
0183: * This predicate selects for root PropagateRegisterServices tasks injected by the GLSInitServlet
0184: **/
0185: private UnaryPredicate regSrvcsPredicate = new UnaryPredicate() {
0186: public boolean execute(Object o) {
0187: if (!(o instanceof PlanElement))
0188: return false;
0189: PlanElement pe = (PlanElement) o;
0190: Task task = pe.getTask();
0191: if (!task.getVerb().equals(PROPAGATE_REGISTER_SERVICES))
0192: return false;
0193: if (!task.getSource().equals(getAgentIdentifier()))
0194: return false;
0195: if (!task.getDestination().equals(getAgentIdentifier()))
0196: return false;
0197: return (task.getPrepositionalPhrase(forRoot) != null);
0198: }
0199: };
0200:
0201: /**
0202: * This predicate selects for root PropagateFindProviders tasks injected by the GLSInitServlet
0203: **/
0204: private UnaryPredicate findProvPredicate = new UnaryPredicate() {
0205: public boolean execute(Object o) {
0206: if (!(o instanceof PlanElement))
0207: return false;
0208: PlanElement pe = (PlanElement) o;
0209: Task task = pe.getTask();
0210: if (!task.getVerb().equals(PROPAGATE_FIND_PROVIDERS))
0211: return false;
0212: if (!task.getSource().equals(getAgentIdentifier()))
0213: return false;
0214: if (!task.getDestination().equals(getAgentIdentifier()))
0215: return false;
0216: return (task.getPrepositionalPhrase(forRoot) != null);
0217: }
0218: };
0219:
0220: // Subscribe to my private state object to recover on rehydrate
0221: private static UnaryPredicate statePredicate = new UnaryPredicate() {
0222: public boolean execute(Object o) {
0223: return (o instanceof MyPrivateState);
0224: }
0225: };
0226:
0227: private static UnaryPredicate requestPredicate = new UnaryPredicate() {
0228: public boolean execute(Object o) {
0229: return (o instanceof Request);
0230: }
0231: };
0232:
0233: private static UnaryPredicate orgAssetPred = new UnaryPredicate() {
0234: public boolean execute(Object o) {
0235: return (o instanceof Organization);
0236: }
0237: };
0238:
0239: private ServletService servletService;
0240:
0241: /** Sets the servlet service. Called by introspection on start
0242: **/
0243: public void setServletService(ServletService ss) {
0244: servletService = ss;
0245: }
0246:
0247: private LoggingService logger;
0248:
0249: public void setLoggingService(LoggingService ls) {
0250: logger = ls;
0251: }
0252:
0253: private PlanningFactory theLDMF;
0254:
0255: public void setDomainService(DomainService ds) {
0256: if (ds == null)
0257: theLDMF = null;
0258: else {
0259: theLDMF = (PlanningFactory) ds.getFactory("planning");
0260: }
0261: }
0262:
0263: /*
0264: * Creates a subscription.
0265: */
0266: protected void setupSubscriptions() {
0267: logger = LoggingServiceWithPrefix.add(logger,
0268: getAgentIdentifier() + ": ");
0269:
0270: Collection params = getParameters();
0271: if ((params == null) || (params.size() == 0)) {
0272: throw new IllegalArgumentException(
0273: "GLSInitServlet: Missing plugin parameter.");
0274: }
0275:
0276: // Get the OPLAN ID from the args.
0277: oplanId = (String) params.iterator().next();
0278:
0279: try {
0280: dbp = DBProperties.readQueryFile(QUERY_FILE);
0281: database = dbp.getProperty("Database");
0282: username = dbp.getProperty("Username");
0283: password = dbp.getProperty("Password");
0284: } catch (IOException ioe) {
0285: throw new RuntimeException("Can't read query file: "
0286: + QUERY_FILE, ioe);
0287: }
0288:
0289: glsSubscription = (IncrementalSubscription) blackboard
0290: .subscribe(glsPredicate);
0291: myorgassets = (IncrementalSubscription) blackboard
0292: .subscribe(orgAssetPred);
0293: requestSubscription = (IncrementalSubscription) blackboard
0294: .subscribe(requestPredicate);
0295: regSrvcsSubscription = (IncrementalSubscription) blackboard
0296: .subscribe(regSrvcsPredicate);
0297: findProvSubscription = (IncrementalSubscription) blackboard
0298: .subscribe(findProvPredicate);
0299:
0300: // Set up the local private state object
0301: // It is put on the blackboard for persistence and recovered
0302: // on rehydration
0303: Collection stateColl = blackboard.query(statePredicate);
0304:
0305: // DEBUGGING
0306: if (blackboard.didRehydrate()) {
0307: if (stateColl.isEmpty()) {
0308: if (logger.isErrorEnabled())
0309: logger
0310: .error("GLSInitServlet: myPrivateState object did not persist!");
0311: } else {
0312: //get c0 and next stage info from state object
0313: myPrivateState = (MyPrivateState) stateColl.iterator()
0314: .next();
0315: boolean haveOpInfo = (myPrivateState.opInfo != null);
0316: if (logger.isDebugEnabled()) {
0317: logger
0318: .debug("GLSInitServlet- stateC0 is: "
0319: + (haveOpInfo ? ((Date) (myPrivateState.opInfo
0320: .getCDate())).toString()
0321: : "<undefined -- No OpInfo yet!>"));
0322: }
0323: SortedSet stateSentStages = (haveOpInfo ? myPrivateState.opInfo
0324: .getSentStages()
0325: : new TreeSet());
0326: if (logger.isDebugEnabled()) {
0327: logger
0328: .debug("GLSInitServlet- stateSentStages has size: "
0329: + stateSentStages.size());
0330: }
0331:
0332: //get c0 and next stage info from gls task
0333: if (glsSubscription.isEmpty()) {
0334: if (logger.isWarnEnabled()) {
0335: logger
0336: .warn("GLSInitServlet- glsSubscription is empty on rehydration.");
0337: }
0338: } else {
0339: SortedSet maxGLSStages = null;
0340:
0341: for (Iterator iterator = glsSubscription.iterator(); iterator
0342: .hasNext();) {
0343: PlanElement pe = (PlanElement) iterator.next();
0344: Task gls = pe.getTask();
0345: PrepositionalPhrase stagespp = gls
0346: .getPrepositionalPhrase(FOR_OPLAN_STAGES);
0347:
0348: SortedSet glsStages = (SortedSet) stagespp
0349: .getIndirectObject();
0350:
0351: if (logger.isDebugEnabled()) {
0352: logger
0353: .debug("GLSInitServlet- glsStages have size: "
0354: + glsStages.size());
0355: }
0356:
0357: maxGLSStages = (maxGLSStages == null) ? glsStages
0358: : ((maxGLSStages.size() < glsStages
0359: .size()) ? glsStages
0360: : maxGLSStages);
0361:
0362: PrepositionalPhrase c0pp = gls
0363: .getPrepositionalPhrase(WITH_C0);
0364: long gls_c0 = ((Long) (c0pp.getIndirectObject()))
0365: .longValue();
0366: Date gls_c0_date = new Date(gls_c0);
0367: if (logger.isDebugEnabled()) {
0368: logger
0369: .debug("GLSInitServlet- gls_c0_date is: "
0370: + gls_c0_date);
0371: }
0372: }
0373:
0374: if (logger.isDebugEnabled()) {
0375: logger
0376: .debug("GLSInitServlet- maxGLSStages have size: "
0377: + maxGLSStages.size());
0378: }
0379:
0380: //compare c0 from private state to c0 in gls task
0381: //TO_DO
0382: //compare number of sent stages from private state to sent stages in gls task
0383: if (stateSentStages.size() != maxGLSStages.size()) {
0384: if (logger.isErrorEnabled()) {
0385: logger
0386: .error("GLSInitServlet: myPrivateState sent Stages do not match GLS task after rehyration - "
0387: + "stateSentStages = "
0388: + stateSentStages
0389: + ", glsStages = "
0390: + maxGLSStages);
0391: }
0392: }
0393: }
0394: }
0395: }
0396: // EMD DEBUGGING
0397:
0398: if (stateColl.isEmpty()) {
0399: myPrivateState = new MyPrivateState();
0400: blackboard.publishAdd(myPrivateState);
0401: } else {
0402: myPrivateState = (MyPrivateState) stateColl.iterator()
0403: .next();
0404: }
0405:
0406: // register with servlet service
0407: try {
0408: servletService.register("/glsinit", new GLSServlet());
0409: servletService.register("/glsreply", new GLSReplyServlet());
0410: } catch (Exception e) {
0411: e.printStackTrace();
0412: }
0413:
0414: //if (logger.isDebugEnabled()) logger.debug("GLSInitServlet: "
0415: // + PUBLISH_ON_SELF_ORG + " = " +
0416: // globalParameters.get(PUBLISH_ON_SELF_ORG));
0417: }
0418:
0419: /**
0420: * Executes Plugin functionality.
0421: */
0422: public void execute() {
0423:
0424: switch (myPrivateState.listening_to) {
0425:
0426: case LISTENING_TO_PROP_REG_SRVCS:
0427: if (regSrvcsSubscription.hasChanged()) {
0428: boolean readyForFP = checkIfStageComplete(regSrvcsSubscription
0429: .getChangedCollection());
0430: if (readyForFP) {
0431: boolean hasFindProvidersStep = checkForFindProviders();
0432: if (hasFindProvidersStep) {
0433: myPrivateState.initialSendFindProv = false;
0434: myPrivateState.opInfo.advanceStage();
0435: myPrivateState.listening_to = LISTENING_TO_PROP_FIND_PROV;
0436: sendPropagateFindProviders();
0437: } else {
0438: myPrivateState.initialSendGLS = false;
0439: myPrivateState.opInfo.advanceStage();
0440: myPrivateState.listening_to = LISTENING_TO_GLS;
0441: sendGLS();
0442: }
0443: }
0444: }
0445: break;
0446: case LISTENING_TO_PROP_FIND_PROV:
0447: if (findProvSubscription.hasChanged()) {
0448: boolean readyForStage = checkIfStageComplete(findProvSubscription
0449: .getChangedCollection());
0450: if (readyForStage) {
0451: myPrivateState.listening_to = LISTENING_TO_GLS;
0452: if (myPrivateState.initialSendGLS) {
0453: myPrivateState.initialSendGLS = false;
0454: } else if (logger.isDebugEnabled()) {
0455: logger
0456: .debug("GLSInitServlet: automatically advancing to next Stage");
0457: }
0458: sendRootGLS();
0459: }
0460: }
0461: break;
0462:
0463: case LISTENING_TO_GLS:
0464: if (glsSubscription.hasChanged()) {
0465: boolean readyForNext = checkIfStageComplete(glsSubscription
0466: .getChangedCollection());
0467: if (readyForNext) {
0468: myPrivateState.listening_to = LISTENING_TO_NOTHING;
0469: myPrivateState.opInfo.updateDisplayStage();
0470: blackboard.publishChange(myPrivateState);
0471: doNotify();
0472: }
0473: }
0474: break;
0475: }
0476:
0477: if (requestSubscription.hasChanged()) {
0478: processRequests(requestSubscription.getAddedCollection());
0479: }
0480: }
0481:
0482: private boolean checkForFindProviders() {
0483: SortedSet remaining = myPrivateState.opInfo
0484: .getRemainingStages();
0485: if (!remaining.isEmpty()) {
0486: int nextStageNum = ((OplanStage) (remaining.first()))
0487: .getNumber();
0488: if ((nextStageNum & 1) != 0) { //odd stage number indicates FindProviders Stage
0489: if (logger.isDebugEnabled()) {
0490: logger
0491: .debug("GLSInitServlet: Found a FindProviders Stage");
0492: }
0493: return true;
0494: }
0495: }
0496: return false;
0497: }
0498:
0499: private boolean checkIfStageComplete(
0500: Collection changedRootTaskPlanElements) {
0501: double confidence = 0;
0502: if (changedRootTaskPlanElements.size() > 1) {
0503: logger
0504: .error("GLSInitServlet: Mulitple root task plan element changed - "
0505: + changedRootTaskPlanElements);
0506: }
0507: for (Iterator i = changedRootTaskPlanElements.iterator(); i
0508: .hasNext();) {
0509: PlanElement pe = (PlanElement) i.next();
0510:
0511: AllocationResult ar = null;
0512: if (pe != null) {
0513: ar = pe.getEstimatedResult();
0514: confidence = ar.getConfidenceRating();
0515: if (logger.isDebugEnabled()) {
0516: switch (myPrivateState.listening_to) {
0517: case LISTENING_TO_NOTHING:
0518: logger
0519: .debug("checkIfStageComplete(): State is LISTENING_TO_NOTHING");
0520: break;
0521: case LISTENING_TO_PROP_REG_SRVCS:
0522: logger
0523: .debug("checkIfStageComplete(): State is LISTENING_TO_PROP_REG_SRVCS");
0524: break;
0525: case LISTENING_TO_PROP_FIND_PROV:
0526: logger
0527: .debug("checkIfStageComplete(): State is LISTENING_TO_PROP_FIND_PROV");
0528: break;
0529: case LISTENING_TO_GLS:
0530: logger
0531: .debug("checkIfStageComplete(): State is LISTENING_TO_GLS");
0532: break;
0533: } //end switch
0534: logger.debug("GLSInitServlet: changed task is "
0535: + pe.getTask());
0536: logger
0537: .debug("GLSInitServlet: confidence of changed task - "
0538: + confidence);
0539: }
0540: }
0541: if (confidence >= 1.0) {
0542: //ready to move to next stage
0543: if (logger.isDebugEnabled()) {
0544: logger
0545: .debug("GLSInitServlet: Stage is Complete- Confidence is- "
0546: + confidence + "\n");
0547: }
0548: return true;
0549: }
0550: }
0551: return false;
0552: }
0553:
0554: private void doNotify() {
0555: synchronized (monitor) {
0556: monitor.notifyAll();
0557: }
0558: }
0559:
0560: private void processRequests(Collection newRequests) {
0561: for (Iterator i = newRequests.iterator(); i.hasNext();) {
0562: Request request = (Request) i.next();
0563: if (request.command.equals(GETOPINFO)) {
0564: publishOplan();
0565: } else if (request.command.equals(PUBLISHGLS)) {
0566: publishAllRootGLS();
0567: }
0568: blackboard.publishRemove(request);
0569: }
0570: }
0571:
0572: private Organization getSelfOrg() {
0573: for (Iterator iterator = myorgassets.iterator(); iterator
0574: .hasNext();) {
0575: Organization org = (Organization) iterator.next();
0576:
0577: // Pick up self org
0578: if (org.isSelf()) {
0579: return org;
0580: }
0581: }
0582:
0583: return null;
0584:
0585: }
0586:
0587: private void readOplanTimeframe() throws SQLException, IOException {
0588:
0589: String oplan_opName;
0590: int min_planning_offset;
0591: int start_offset;
0592: int end_offset;
0593: String stage_name;
0594: String stage_desc;
0595: SortedSet ss = new TreeSet();
0596:
0597: try {
0598: String dbtype = dbp.getDBType();
0599: insureDriverClass(dbtype);
0600: Connection conn = DBConnectionPool.getConnection(database,
0601: username, password);
0602: try {
0603: Statement stmt = conn.createStatement();
0604: String query = dbp.getQuery(TIME_QUERY_NAME,
0605: Collections.singletonMap(":oplanid:", oplanId));
0606:
0607: ResultSet rs = stmt.executeQuery(query);
0608: if (rs.next()) {
0609: if (rs.getObject(1) instanceof String)
0610: oplan_opName = ((String) rs.getObject(1));
0611: else
0612: oplan_opName = new String((byte[]) rs
0613: .getObject(1), "US-ASCII");
0614: min_planning_offset = ((Number) (rs.getObject(2)))
0615: .intValue();
0616: start_offset = ((Number) (rs.getObject(3)))
0617: .intValue();
0618: end_offset = ((Number) (rs.getObject(4)))
0619: .intValue();
0620: } else {
0621: throw new SQLException("No results from query:"
0622: + query);
0623: }
0624: rs.close();
0625:
0626: query = dbp.getQuery(STAGE_QUERY_NAME, Collections
0627: .singletonMap(":oplanid:", oplanId));
0628:
0629: rs = stmt.executeQuery(query);
0630: while (rs.next()) {
0631: if (rs.getObject(1) instanceof String) {
0632: stage_name = ((String) rs.getObject(1));
0633: } else
0634: stage_name = new String((byte[]) rs
0635: .getObject(1), "US-ASCII");
0636: int stage_num = ((Number) (rs.getObject(2)))
0637: .intValue();
0638: if (rs.getObject(3) instanceof String) {
0639: stage_desc = ((String) rs.getObject(3));
0640: } else
0641: stage_desc = new String((byte[]) rs
0642: .getObject(3), "US-ASCII");
0643: OplanStage op = new OplanStage(stage_num,
0644: stage_name, stage_desc);
0645: ss.add(op);
0646: }
0647:
0648: stmt.close();
0649: } catch (Exception except) {
0650: if (except instanceof SQLException) {
0651: throw (SQLException) except;
0652: }
0653: SQLException myEx1 = new SQLException("Query failed.");
0654: myEx1.initCause(except);
0655: throw myEx1;
0656: } finally {
0657: conn.close();
0658: }
0659:
0660: } catch (Exception e) {
0661: if (e instanceof SQLException) {
0662: throw (SQLException) e;
0663: }
0664: SQLException myEx = new SQLException(
0665: "Driver not found for " + database);
0666: myEx.initCause(e);
0667: throw myEx;
0668: }
0669:
0670: long start_time = currentTimeMillis();
0671: long initialTime = parseInitialTime();
0672: if (initialTime != DATE_ERROR) {
0673: start_time = initialTime;
0674: }
0675: myPrivateState.opInfo = new OplanInfo(oplanId, oplan_opName,
0676: start_time, min_planning_offset, start_offset,
0677: end_offset, ss);
0678:
0679: if (logger.isDebugEnabled()) {
0680: logger.debug("GLSInitServlet: OplanStages from db are: "
0681: + myPrivateState.opInfo.getRemainingStages());
0682: }
0683:
0684: blackboard.publishChange(myPrivateState);
0685: doNotify();
0686: }
0687:
0688: private long parseInitialTime() {
0689: String propertyName = "org.cougaar.initTime";
0690: long date = DATE_ERROR;
0691: long time = DATE_ERROR;
0692: String value = System.getProperty(propertyName);
0693: if (value != null) {
0694: try {
0695: DateFormat f = (new SimpleDateFormat(
0696: "MM/dd/yyy H:mm:ss"));
0697: f.setTimeZone(TimeZone.getTimeZone("GMT"));
0698: time = f.parse(value).getTime();
0699: // get midnight of specified date
0700: Calendar c = f.getCalendar();
0701: c.setTimeInMillis(time);
0702: c.set(Calendar.HOUR, 0);
0703: c.set(Calendar.MINUTE, 0);
0704: c.set(Calendar.SECOND, 0);
0705: c.set(Calendar.MILLISECOND, 0);
0706: date = c.getTimeInMillis();
0707: } catch (ParseException e) {
0708: // try with just the date
0709: try {
0710: DateFormat f = (new SimpleDateFormat("MM/dd/yyy"));
0711: f.setTimeZone(TimeZone.getTimeZone("GMT"));
0712: time = f.parse(value).getTime();
0713: } catch (ParseException e1) {
0714: if (logger.isDebugEnabled())
0715: logger.debug("Failed to parse property "
0716: + propertyName
0717: + " as date+time or just time: "
0718: + value, e1);
0719: }
0720: }
0721: }
0722: return time;
0723: }
0724:
0725: private void insureDriverClass(String dbtype) throws SQLException,
0726: ClassNotFoundException {
0727: String driverParam = "driver." + dbtype;
0728: String driverClass = Parameters.findParameter(driverParam);
0729: if (driverClass == null) {
0730: // this is likely a "cougaar.rc" problem.
0731: // Parameters should be modified to help generate this exception:
0732: throw new SQLException("Unable to find driver class for \""
0733: + driverParam + "\" -- check your \"cougaar.rc\"");
0734: }
0735: Class.forName(driverClass);
0736: }
0737:
0738: private void publishOplan() {
0739: if (myPrivateState.oplanInfoExists) {
0740: // Calling this is an error
0741: if (logger.isWarnEnabled())
0742: logger.warn("Not re-fetching Oplan Info",
0743: new Throwable());
0744: return;
0745: }
0746:
0747: blackboard.openTransaction();
0748: try {
0749: readOplanTimeframe();
0750: } catch (Exception e) {
0751: logger.error("Failed to get oplan timeframe from DB", e);
0752: }
0753: myPrivateState.oplanInfoExists = true;
0754: blackboard.publishChange(myPrivateState);
0755: blackboard.closeTransactionDontReset();
0756: }
0757:
0758: private void publishAllRootGLS() {
0759: sendGLS();
0760: }
0761:
0762: public void PublishRootTask(String oplanID, String c0_date) {
0763: blackboard.openTransaction();
0764: if (myPrivateState.initialSendGLS) {
0765: myPrivateState.opInfo.setCDate(c0_date);
0766: myPrivateState.listening_to = LISTENING_TO_PROP_REG_SRVCS;
0767: sendPropagateRegisterServices();
0768: } else if (checkForFindProviders()) {
0769: myPrivateState.listening_to = LISTENING_TO_PROP_FIND_PROV;
0770: myPrivateState.opInfo.advanceStage();
0771: if (myPrivateState.initialSendFindProv) {
0772: myPrivateState.initialSendFindProv = false;
0773: sendPropagateFindProviders();
0774: }
0775: } else {
0776: myPrivateState.listening_to = LISTENING_TO_GLS;
0777: sendRootGLS();
0778: }
0779: blackboard.closeTransactionDontReset();
0780: }
0781:
0782: public void sendRootGLS() {
0783: SortedSet remaining = myPrivateState.opInfo
0784: .getRemainingStages();
0785: if (remaining.isEmpty()) {
0786: return;
0787: }
0788: myPrivateState.opInfo.advanceStage();
0789: sendGLS();
0790: blackboard.publishChange(myPrivateState);
0791: if (logger.isDebugEnabled()) {
0792: logger.debug(getAgentIdentifier()
0793: + "sendRootGLS: remainingStages are "
0794: + myPrivateState.opInfo.getRemainingStages());
0795: }
0796: }
0797:
0798: private void sendPropagateRegisterServices() {
0799: NewTask task = theLDMF.newTask();
0800: // ensure this is a root level task
0801: task.setPlan(theLDMF.getRealityPlan());
0802: task.setSource(getAgentIdentifier());
0803: task.setDestination(getAgentIdentifier());
0804:
0805: // set prepositional phrases
0806: Vector phrases = new Vector(2);
0807: NewPrepositionalPhrase newpp;
0808:
0809: newpp = theLDMF.newPrepositionalPhrase();
0810: newpp.setPreposition(FOR_ORGANIZATION);
0811: newpp.setIndirectObject(getSelfOrg());
0812: phrases.add(newpp);
0813:
0814: newpp = theLDMF.newPrepositionalPhrase();
0815: newpp.setPreposition(FOR_ROOT);
0816: newpp.setIndirectObject(new Integer(
0817: ++myPrivateState.prsTaskNumber));
0818: phrases.add(newpp);
0819: task.setPrepositionalPhrases(phrases.elements());
0820:
0821: // Set the context
0822: try {
0823: ContextOfOplanIds context = new ContextOfOplanIds(oplanId);
0824: task.setContext(context);
0825: } catch (Exception ex) {
0826: ex.printStackTrace();
0827: }
0828:
0829: // verb
0830: task.setVerb(PROPAGATE_REGISTER_SERVICES);
0831:
0832: blackboard.publishChange(myPrivateState);
0833: blackboard.publishAdd(task);
0834: }
0835:
0836: private void sendPropagateFindProviders() {
0837: NewTask task = theLDMF.newTask();
0838: // ensure this is a root level task
0839: task.setPlan(theLDMF.getRealityPlan());
0840: task.setSource(getAgentIdentifier());
0841: task.setDestination(getAgentIdentifier());
0842:
0843: // set prepositional phrases
0844: Vector phrases = new Vector(3);
0845: NewPrepositionalPhrase newpp;
0846:
0847: newpp = theLDMF.newPrepositionalPhrase();
0848: newpp.setPreposition(FOR_ORGANIZATION);
0849: newpp.setIndirectObject(getSelfOrg());
0850: phrases.add(newpp);
0851:
0852: newpp = theLDMF.newPrepositionalPhrase();
0853: newpp.setPreposition(FOR_ROOT);
0854: newpp.setIndirectObject(new Integer(
0855: ++myPrivateState.pfpTaskNumber));
0856: phrases.add(newpp);
0857: phrases.add(makeForOplanStagesPhrase());
0858:
0859: task.setPrepositionalPhrases(phrases.elements());
0860:
0861: // Set the context
0862: try {
0863: ContextOfOplanIds context = new ContextOfOplanIds(oplanId);
0864: task.setContext(context);
0865: } catch (Exception ex) {
0866: ex.printStackTrace();
0867: }
0868:
0869: // verb
0870: task.setVerb(PROPAGATE_FIND_PROVIDERS);
0871:
0872: blackboard.publishChange(myPrivateState);
0873: blackboard.publishAdd(task);
0874: }
0875:
0876: private void sendGLS() {
0877: NewTask task = theLDMF.newTask();
0878: // ensure this is a root level task
0879: task.setPlan(theLDMF.getRealityPlan());
0880: task.setSource(getAgentIdentifier());
0881: task.setDestination(getAgentIdentifier());
0882:
0883: // set prepositional phrases
0884: Vector phrases = new Vector(4);
0885: NewPrepositionalPhrase newpp;
0886:
0887: newpp = theLDMF.newPrepositionalPhrase();
0888: newpp.setPreposition(FOR_ORGANIZATION);
0889: newpp.setIndirectObject(getSelfOrg());
0890: phrases.add(newpp);
0891:
0892: newpp = theLDMF.newPrepositionalPhrase();
0893: newpp.setPreposition(FOR_ROOT);
0894: newpp.setIndirectObject(new Integer(
0895: ++myPrivateState.glsTaskNumber));
0896: phrases.add(newpp);
0897:
0898: newpp = theLDMF.newPrepositionalPhrase();
0899: newpp.setPreposition(WITH_C0);
0900: newpp.setIndirectObject(new Long(myPrivateState.opInfo
0901: .getCDate().getTime()));
0902: phrases.add(newpp);
0903: phrases.add(makeForOplanStagesPhrase());
0904: blackboard.publishChange(myPrivateState);
0905:
0906: task.setPrepositionalPhrases(phrases.elements());
0907:
0908: // verb
0909: task.setVerb(GET_LOG_SUPPORT);
0910:
0911: // schedule
0912: long startTime = myPrivateState.opInfo.getStartDay().getTime();
0913: long endTime = myPrivateState.opInfo.getEndDay().getTime();
0914:
0915: AspectValue startTav = TimeAspectValue.create(
0916: AspectType.START_TIME, startTime);
0917: AspectValue endTav = TimeAspectValue.create(
0918: AspectType.END_TIME, endTime);
0919:
0920: ScoringFunction myStartScoreFunc = ScoringFunction
0921: .createStrictlyAtValue(startTav);
0922: ScoringFunction myEndScoreFunc = ScoringFunction
0923: .createStrictlyAtValue(endTav);
0924:
0925: Preference startPreference = theLDMF.newPreference(
0926: AspectType.START_TIME, myStartScoreFunc);
0927: Preference endPreference = theLDMF.newPreference(
0928: AspectType.END_TIME, myEndScoreFunc);
0929:
0930: Vector preferenceVector = new Vector(2);
0931: preferenceVector.addElement(startPreference);
0932: preferenceVector.addElement(endPreference);
0933:
0934: task.setPreferences(preferenceVector.elements());
0935:
0936: // Set the context
0937: try {
0938: ContextOfOplanIds context = new ContextOfOplanIds(oplanId);
0939: if (logger.isDebugEnabled()) {
0940: logger.debug("GLSInitPlugin: Setting context to: "
0941: + oplanId);
0942: }
0943: task.setContext(context);
0944: } catch (Exception ex) {
0945: ex.printStackTrace();
0946: }
0947:
0948: blackboard.publishAdd(task);
0949:
0950: if (logger.isDebugEnabled()) {
0951: logger.debug("\n" + formatDate(System.currentTimeMillis())
0952: + " Send Task: " + task);
0953: }
0954: }
0955:
0956: private NewPrepositionalPhrase makeForOplanStagesPhrase() {
0957: NewPrepositionalPhrase newpp = theLDMF.newPrepositionalPhrase();
0958: newpp.setPreposition(FOR_OPLAN_STAGES);
0959: newpp.setIndirectObject(new TreeSet(myPrivateState.opInfo
0960: .getSentStages()));
0961: return newpp;
0962: }
0963:
0964: protected static DateFormat logTimeFormat = new SimpleDateFormat(
0965: "yyyy/MM/dd HH:mm:ss.SSS");
0966:
0967: protected static String formatDate(long when) {
0968: return logTimeFormat.format(new Date(when));
0969: }
0970:
0971: private static class OplanInfo implements java.io.Serializable {
0972: private String opId;
0973: private String opName;
0974: private int min_planning_offset;
0975: private int start_offset;
0976: private int end_offset;
0977: private Date cDate;
0978: private Date startDay;
0979: private Date endDay;
0980: private long start_time;
0981: private SortedSet remainingStages;
0982: private SortedSet sentStages;
0983: private OplanStage displayStage;
0984:
0985: public OplanInfo(String opId, String opName, long start_time,
0986: int min_planning_offset, int start_offset,
0987: int end_offset, SortedSet s) {
0988: this .opId = opId;
0989: this .opName = opName;
0990: this .start_time = start_time;
0991: this .min_planning_offset = min_planning_offset;
0992: this .start_offset = start_offset;
0993: this .end_offset = end_offset;
0994: remainingStages = s;
0995: sentStages = new TreeSet();
0996:
0997: updateDisplayStage();
0998: setCDate();
0999: }
1000:
1001: public String getOpName() {
1002: return opName;
1003: }
1004:
1005: public String getOpId() {
1006: return opId;
1007: }
1008:
1009: public Date getCDate() {
1010: return cDate;
1011: }
1012:
1013: public void setCDate(String c0) {
1014: try {
1015: cDate = cDateFormat.parse(c0);
1016: } catch (ParseException pe) {
1017: pe.printStackTrace();
1018: }
1019: setStartDay();
1020: setEndDay();
1021: }
1022:
1023: public void setCDate() {
1024: long c0calc = start_time
1025: - (min_planning_offset * 86400000L);
1026: cDate = new Date(c0calc);
1027: String cDateFormatted = cDateFormat.format(cDate);
1028: setCDate(cDateFormatted);
1029: }
1030:
1031: public Date getStartDay() {
1032: return startDay;
1033: }
1034:
1035: public Date getEndDay() {
1036: return endDay;
1037: }
1038:
1039: public void setStartDay() {
1040: long startCalc = cDate.getTime()
1041: + (start_offset * 86400000L);
1042: startDay = new Date(startCalc);
1043: }
1044:
1045: public void setEndDay() {
1046: long endCalc = cDate.getTime() + (end_offset * 86400000L);// days in milliseconds
1047: endDay = new Date(endCalc);
1048: }
1049:
1050: public SortedSet getRemainingStages() {
1051: return remainingStages;
1052: }
1053:
1054: public SortedSet getSentStages() {
1055: return sentStages;
1056: }
1057:
1058: public void setDisplayStage(OplanStage dispStage) {
1059: displayStage = dispStage;
1060: }
1061:
1062: public OplanStage getDisplayStage() {
1063: return displayStage;
1064: }
1065:
1066: public void updateDisplayStage() {
1067: for (Iterator i = remainingStages.iterator(); i.hasNext();) {
1068: OplanStage os = (OplanStage) i.next();
1069: //check whether stage is evenly numbered indicating major stage
1070: if ((os.getNumber() & 1) == 0) {
1071: setDisplayStage(os);
1072: break;
1073: }
1074: }
1075: }
1076:
1077: public void advanceStage() {
1078: OplanStage op = (OplanStage) remainingStages.first();
1079: sentStages.add(op);
1080: remainingStages.remove(op);
1081: }
1082:
1083: public void resetStages() {
1084: for (Iterator i = sentStages.iterator(); i.hasNext();) {
1085: remainingStages.add((OplanStage) i.next());
1086: }
1087: }
1088: }
1089:
1090: private class GLSServlet extends HttpServlet {
1091:
1092: protected void doGet(HttpServletRequest request,
1093: HttpServletResponse response) {
1094: String command = request.getParameter("command");
1095: if (logger.isDebugEnabled())
1096: logger.debug("GLSServlet got request command is: "
1097: + command);
1098: response.setContentType("text/html");
1099: try {
1100: PrintWriter out = response.getWriter();
1101: out.println("<html><head></head><body><"
1102: + request.getParameter("command")
1103: + "></body></html>");
1104: out.close();
1105: } catch (java.io.IOException ie) {
1106: ie.printStackTrace();
1107: }
1108:
1109: if (command.equals(GETOPINFO)) {
1110: publishOplan();
1111: }
1112: if (command.equals(PUBLISHGLS)) {
1113: if (logger.isDebugEnabled())
1114: logger.debug("oplanID is "
1115: + request.getParameter("oplanID"));
1116: if (logger.isDebugEnabled())
1117: logger.debug("cDay is "
1118: + request.getParameter("c0_date"));
1119: String oplanID = request.getParameter("oplanID");
1120: String c0 = request.getParameter("c0_date");
1121: PublishRootTask(oplanID, c0);
1122: }
1123: }
1124: }
1125:
1126: private class GLSReplyServlet extends HttpServlet {
1127:
1128: protected void doGet(HttpServletRequest request,
1129: HttpServletResponse response) {
1130: String command = request.getParameter("command");
1131: if (logger.isDebugEnabled()) {
1132: logger.debug("GLSReplyServlet got request " + command);
1133: }
1134: // make this smarter?
1135: ReplyWorker worker = new ReplyWorker(request, response);
1136: worker.execute();
1137: }
1138: }
1139:
1140: private class ReplyWorker {
1141: private HttpServletRequest request;
1142: private HttpServletResponse response;
1143:
1144: public ReplyWorker(HttpServletRequest request,
1145: HttpServletResponse response) {
1146: this .request = request;
1147: this .response = response;
1148: }
1149:
1150: // bug - this keeps writing even if the listener client goes away
1151: public void execute() {
1152: try {
1153: response.setContentType("text/xml");
1154: PrintWriter out = response.getWriter();
1155: // keep writing back to the client
1156: while (true) {
1157: if (logger.isDebugEnabled()) {
1158: logger
1159: .debug("GLSInitServlet: Refreshing GLSClient.");
1160: }
1161: if (myPrivateState.opInfo != null) {
1162: StringBuffer sb = new StringBuffer();
1163: sb.append("<oplan name=");
1164: sb.append(myPrivateState.opInfo.getOpName());
1165: sb.append(" id=");
1166: sb.append(myPrivateState.opInfo.getOpId());
1167: sb.append(" c0_date=");
1168: sb.append(cDateFormat
1169: .format(myPrivateState.opInfo
1170: .getCDate()));
1171: sb.append(" nextStage=");
1172:
1173: SortedSet remaining = myPrivateState.opInfo
1174: .getRemainingStages();
1175: if (remaining.isEmpty()) {
1176: sb.append("All Stages Sent");
1177: sb.append(" stageDesc=");
1178: } else {
1179: sb
1180: .append(((OplanStage) (myPrivateState.opInfo
1181: .getDisplayStage()))
1182: .getName());
1183: sb.append(" stageDesc=");
1184: sb
1185: .append(((OplanStage) (myPrivateState.opInfo
1186: .getDisplayStage()))
1187: .getDescription());
1188: }
1189: sb.append(">");
1190: out.println(sb);
1191: if (logger.isDebugEnabled()) {
1192: logger
1193: .debug("GLSInitServlet: ReplyWorker stringbuffer :"
1194: + sb);
1195: }
1196: }
1197:
1198: out.flush();
1199: synchronized (monitor) {
1200: try {
1201: // sit until notified that gls or oplan has changed
1202: monitor.wait();
1203: } catch (InterruptedException ie) {
1204: ie.printStackTrace();
1205: }
1206: }
1207: }
1208: } catch (java.io.IOException ie) {
1209: ie.printStackTrace();
1210: } catch (Exception ex) {
1211: ex.printStackTrace();
1212: }
1213: }
1214: }
1215: }
|