0001: /*
0002: * <copyright>
0003: *
0004: * Copyright 2000-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.tools.csmart.ui.viewer;
0028:
0029: import org.cougaar.core.agent.Agent;
0030: import org.cougaar.tools.csmart.core.db.DBConflictHandler;
0031: import org.cougaar.tools.csmart.core.db.DBUtils;
0032: import org.cougaar.tools.csmart.core.db.ExperimentDB;
0033: import org.cougaar.tools.csmart.core.db.PDbBase;
0034: import org.cougaar.tools.csmart.core.db.PopulateDb;
0035: import org.cougaar.tools.csmart.core.property.BaseComponent;
0036: import org.cougaar.tools.csmart.core.property.Property;
0037: import org.cougaar.tools.csmart.experiment.DBExperiment;
0038: import org.cougaar.tools.csmart.experiment.HostComponent;
0039: import org.cougaar.tools.csmart.experiment.NodeComponent;
0040: import org.cougaar.tools.csmart.experiment.Experiment;
0041: import org.cougaar.tools.csmart.recipe.ComplexRecipeBase;
0042: import org.cougaar.tools.csmart.recipe.RecipeBase;
0043: import org.cougaar.tools.csmart.recipe.RecipeComponent;
0044: import org.cougaar.tools.csmart.society.AgentComponent;
0045: import org.cougaar.tools.csmart.society.SocietyComponent;
0046: import org.cougaar.tools.csmart.society.db.SocietyDBComponent;
0047: import org.cougaar.tools.csmart.society.file.SocietyFileComponent;
0048: import org.cougaar.util.log.Logger;
0049:
0050: import javax.swing.*;
0051: import java.io.File;
0052: import java.io.IOException;
0053: import java.io.ObjectInputStream;
0054: import java.lang.reflect.Constructor;
0055: import java.sql.Connection;
0056: import java.sql.ResultSet;
0057: import java.sql.SQLException;
0058: import java.sql.Statement;
0059: import java.util.ArrayList;
0060: import java.util.Arrays;
0061: import java.util.HashMap;
0062: import java.util.Iterator;
0063: import java.util.List;
0064: import java.util.Map;
0065: import java.util.Properties;
0066: import java.util.TreeMap;
0067:
0068: /**
0069: * Helper functions for manipulating objects in the Organizer
0070: */
0071: public class OrganizerHelper {
0072: private static final String EXPT_DESC_QUERY = "queryExptDescriptions";
0073: private static final String EXPT_ASSEM_QUERY = "queryExperiment";
0074: private static final String EXPT_TRIAL_QUERY = "queryTrials";
0075: private static final String EXPT_NODE_QUERY = "queryNodes";
0076: private static final String EXPT_HOST_QUERY = "queryHosts";
0077: private static final String COMPONENT_ARGS_QUERY = "queryComponentArgs";
0078:
0079: private transient Logger log;
0080:
0081: private static final String CMT_START_STRING = "CMT";
0082: private static final String CSA_START_STRING = "CSA";
0083:
0084: private DBConflictHandler saveToDbConflictHandler = GUIUtils
0085: .createSaveToDbConflictHandler(null);
0086:
0087: private Organizer organizer;
0088:
0089: public OrganizerHelper(Organizer organizer) {
0090: this .organizer = organizer;
0091: }
0092:
0093: /**
0094: * Create an experiment.
0095: * @return Experiment the new experiment or null if any error
0096: */
0097: public DBExperiment createExperiment(String originalExperimentName,
0098: String experimentName, String experimentId, String trialId) {
0099:
0100: createLogger();
0101:
0102: // get assembly ids for trial
0103: ArrayList assemblyIds = getTrialAssemblyIds(experimentId,
0104: trialId);
0105: String assemblyMatch = DBUtils.getAssemblyMatch(assemblyIds);
0106: // get nodes for trial
0107: ArrayList nodes = getNodes(trialId, assemblyMatch);
0108: ArrayList hosts = getHosts(trialId, assemblyMatch);
0109: SocietyDBComponent soc = null;
0110: if (assemblyIds.size() != 0) {
0111: // Get the Society Assembly Id (CMT or CSA).
0112: String id = null;
0113: Iterator iter = assemblyIds.iterator();
0114: while (iter.hasNext()) {
0115: id = (String) iter.next();
0116: if (id.startsWith(CMT_START_STRING)
0117: || id.startsWith(CSA_START_STRING)) {
0118: break;
0119: }
0120: }
0121:
0122: if (id == null
0123: || (!id.startsWith(CMT_START_STRING) && !id
0124: .startsWith(CSA_START_STRING))) {
0125: // PROBLEM! Not a society assembly!
0126: if (log.isErrorEnabled()) {
0127: log
0128: .error("createExpt found no society Assembly for experiment "
0129: + experimentId);
0130: if (id == null)
0131: log.error("Found no assembly at all!");
0132: else
0133: log.error("Found only assembly " + id);
0134: }
0135: return null;
0136: }
0137:
0138: if (id != null) {
0139: String societyName = DBUtils.getSocietyName(id);
0140: SocietyComponent sc = organizer.getSociety(societyName);
0141: if (sc != null && (sc instanceof SocietyDBComponent)) {
0142: if (log.isDebugEnabled()) {
0143: log.debug("Found already loaded society "
0144: + societyName);
0145: }
0146: soc = (SocietyDBComponent) sc;
0147: } else {
0148: if (log.isDebugEnabled()) {
0149: log.debug("Loading society " + societyName
0150: + " from id " + id);
0151: }
0152: soc = new SocietyDBComponent(societyName, id);
0153: soc.initProperties();
0154: }
0155: }
0156: } else { // We need to create a new trial.
0157: // Need to have the experiment id, trial id, and multiplicity
0158: // for the call that will generate the assembly here.
0159: if (log.isWarnEnabled()) {
0160: log.warn("No assemblies for: " + experimentId + " "
0161: + trialId);
0162: }
0163: return null; // creating an experiment from scratch not implemented yet
0164: }
0165:
0166: DBExperiment experiment = new DBExperiment(
0167: (String) experimentName, experimentId, trialId);
0168:
0169: // The following is ugly
0170: setDefaultNodeArguments(experiment, assemblyMatch, PopulateDb
0171: .getSocietyAlibId(originalExperimentName));
0172: // experiment.setCloned(isCloned);
0173:
0174: //to hold all potential agents
0175: List agents = new ArrayList();
0176:
0177: Map experimentNamesMap = ExperimentDB.getExperimentNames();
0178: String origExperimentId = (String) experimentNamesMap
0179: .get(originalExperimentName);
0180: String origTrialId = null;
0181: if (origExperimentId == null) {
0182: if (log.isErrorEnabled()) {
0183: log.error("Found no experiment ID for name "
0184: + originalExperimentName);
0185: log
0186: .error("Will have null trialID, and therefore will lose the recipes that were in this experiment!");
0187: }
0188: } else {
0189: origTrialId = ExperimentDB.getTrialId(origExperimentId);
0190: }
0191:
0192: // This gets all the recipes for the experiment from which this was created
0193: List defaultRecipes = checkForRecipes(origTrialId,
0194: origExperimentId);
0195:
0196: // if (log.isDebugEnabled()) {
0197: // log.debug("default recipes list from OLD exptID has " + defaultRecipes.size() + " items");
0198: // Iterator rI = defaultRecipes.iterator();
0199: // while (rI.hasNext()) {
0200: // DbRecipe rn = (DbRecipe) rI.next();
0201: // log.debug("default recipes list: " + rn.name);
0202: // }
0203: // }
0204:
0205: List recipes = checkForRecipes(trialId, experimentId);
0206:
0207: // if (log.isDebugEnabled()) {
0208: // log.debug("recipes list from this exptID has " + recipes.size() + " items");
0209: // Iterator rI = recipes.iterator();
0210: // while (rI.hasNext()) {
0211: // DbRecipe rn = (DbRecipe) rI.next();
0212: // log.debug("recipes list: " + rn.name);
0213: // }
0214: // }
0215:
0216: // FIXME: Maybe deal with CMT societies & DEFAULT comms
0217: // here??
0218: // And in general, must grab comm stuff from orig ID and resave it
0219: // under a new ID and attach it to the new Expt.
0220: // FIXME: Do something with community stuff here?
0221: // That is, find any comm info, stash it away in new ASB
0222: // ref'ed in Expt, so that save can then save it
0223: // in the correct assembly in the Expt.
0224:
0225: // maybe change this if to be:
0226: // if (! recipes.contains(defaultRecipes)
0227: // except of course, looping over the items....
0228:
0229: // When creating an experiment from one of the base experiments
0230: // copy over the recipes that came with the base
0231: if (origExperimentId != null
0232: && !origExperimentId.equals(experimentId)) {
0233: if (log.isDebugEnabled()) {
0234: log
0235: .debug("Combining old expts recipes with those from this and grabbing Comm info from orig expt");
0236: }
0237: recipes.addAll(defaultRecipes);
0238:
0239: // Now community stuff
0240: // FIXME: I think the old COMM ASB is in the config
0241: // table here already at this point, which I don't really want
0242: PopulateDb pdbc = null;
0243: String commAsb = null;
0244: try {
0245: pdbc = new PopulateDb(experimentId, trialId);
0246: commAsb = pdbc.getNewCommAsbFromExpt(origExperimentId,
0247: origTrialId);
0248: if (commAsb != null)
0249: pdbc.setCommAssemblyId(commAsb);
0250: } catch (SQLException sqle) {
0251: log
0252: .error(
0253: "createExperiment couldnt get new commAsb based on orig expt "
0254: + origExperimentId
0255: + " for new experiment "
0256: + experimentId, sqle);
0257: } catch (IOException ioe) {
0258: log
0259: .error(
0260: "createExperiment couldnt get new commAsb based on orig expt "
0261: + origExperimentId
0262: + " for new experiment "
0263: + experimentId, ioe);
0264: } finally {
0265: try {
0266: if (pdbc != null)
0267: pdbc.close();
0268: } catch (SQLException se) {
0269: }
0270: }
0271: experiment.setCommAsbID(commAsb);
0272: if (log.isDebugEnabled()) {
0273: log
0274: .debug("createExpt got new comm asb based on old expt "
0275: + origExperimentId + " of " + commAsb);
0276: }
0277: } else if (origExperimentId != null
0278: && origExperimentId.equals(experimentId)) {
0279: if (log.isDebugEnabled()) {
0280: log
0281: .debug("createExpt had orig same as this. Try reading previous comm ASB from db");
0282: }
0283:
0284: // just loading a previous experiment from the DB.
0285: // get its comm ASB
0286: PopulateDb pdbc = null;
0287: String commAsb = null;
0288: try {
0289: pdbc = new PopulateDb(experimentId, trialId);
0290: commAsb = pdbc.getCommAsbForExpt(experimentId, trialId);
0291: } catch (SQLException sqle) {
0292: log.error(
0293: "createExperiment couldnt get commAsb for expt "
0294: + experimentId, sqle);
0295: } catch (IOException ioe) {
0296: log.error(
0297: "createExperiment couldnt get commAsb for expt "
0298: + experimentId, ioe);
0299: } finally {
0300: try {
0301: if (pdbc != null)
0302: pdbc.close();
0303: } catch (SQLException se) {
0304: }
0305: }
0306: experiment.setCommAsbID(commAsb);
0307: if (log.isDebugEnabled()) {
0308: log.debug("createExpt got comm asb for expt "
0309: + experimentId + " of " + commAsb);
0310: }
0311: } else if (origExperimentId == null) {
0312: if (log.isDebugEnabled()) {
0313: log
0314: .debug("createExpt got null orig ExptId when loading expt "
0315: + experimentId);
0316: }
0317:
0318: // just re-loading an experiment
0319: // get its comm ASB
0320: PopulateDb pdbc = null;
0321: String commAsb = null;
0322: try {
0323: pdbc = new PopulateDb(experimentId, trialId);
0324: commAsb = pdbc.getCommAsbForExpt(experimentId, trialId);
0325: } catch (SQLException sqle) {
0326: log.error(
0327: "createExperiment couldnt get commAsb for expt "
0328: + experimentId, sqle);
0329: } catch (IOException ioe) {
0330: log.error(
0331: "createExperiment couldnt get commAsb for expt "
0332: + experimentId, ioe);
0333: } finally {
0334: try {
0335: if (pdbc != null)
0336: pdbc.close();
0337: } catch (SQLException se) {
0338: }
0339: }
0340: experiment.setCommAsbID(commAsb);
0341: if (log.isDebugEnabled()) {
0342: log.debug("createExpt got comm asb for expt "
0343: + experimentId + " of " + commAsb);
0344: }
0345: }
0346:
0347: // If somehow still have no comm ASB, create a new one
0348: if (experiment.getCommAsbID() == null) {
0349: if (log.isInfoEnabled()) {
0350: log
0351: .info("createExpt somehow still no Comm ASB. Create a new one. OrigExptID: "
0352: + origExperimentId
0353: + ", exptID: "
0354: + experimentId);
0355: }
0356: PopulateDb pdbc = null;
0357: String commAsb = null;
0358: try {
0359: pdbc = new PopulateDb(experimentId, trialId);
0360: commAsb = pdbc.getNewCommAssembly();
0361: if (commAsb != null)
0362: pdbc.setCommAssemblyId(commAsb);
0363: } catch (SQLException sqle) {
0364: log.error(
0365: "createExperiment couldnt get new commAsb for expt "
0366: + experimentId, sqle);
0367: } catch (IOException ioe) {
0368: log.error(
0369: "createExperiment couldnt get new commAsb for expt "
0370: + experimentId, ioe);
0371: } finally {
0372: try {
0373: if (pdbc != null)
0374: pdbc.close();
0375: } catch (SQLException se) {
0376: }
0377: }
0378: experiment.setCommAsbID(commAsb);
0379: if (log.isDebugEnabled()) {
0380: log.debug("createExpt got comm asb for expt "
0381: + experimentId + " of " + commAsb);
0382: }
0383: }
0384:
0385: if (recipes.size() != 0) {
0386: Iterator metIter = recipes.iterator();
0387: while (metIter.hasNext()) {
0388: DbRecipe dbRecipe = (DbRecipe) metIter.next();
0389: // If recipe is in organizer, use that
0390: // Else, create from db
0391: RecipeComponent mc = getDatabaseRecipe(dbRecipe);
0392: if (mc != null) {
0393: AgentComponent[] recagents = mc.getAgents();
0394: if (recagents != null && recagents.length > 0) {
0395: agents.addAll(Arrays.asList(recagents));
0396: }
0397: if (log.isDebugEnabled()) {
0398: log.debug("Adding recipe to experiment "
0399: + experiment.getExperimentName() + ": "
0400: + mc.getRecipeName());
0401: }
0402: experiment.addRecipeComponent(mc);
0403: }
0404: }
0405: }
0406:
0407: AgentComponent[] socagents = soc.getAgents();
0408: if (socagents != null && socagents.length > 0) {
0409: for (int i = 0; i < socagents.length; i++) {
0410: AgentComponent ac = socagents[i];
0411: setComponentProperties(ac, PopulateDb.getAgentAlibId(ac
0412: .getShortName()), assemblyMatch);
0413: }
0414: agents.addAll(Arrays.asList(socagents));
0415: }
0416: AgentComponent[] allagents = (AgentComponent[]) agents
0417: .toArray(new AgentComponent[agents.size()]);
0418:
0419: experiment.addSocietyComponent((SocietyComponent) soc);
0420:
0421: if (log.isDebugEnabled()) {
0422: log
0423: .debug("createExperiment about to do Agent/Node mapping");
0424: }
0425: // Retrieve the Agent/Node mapping. Add the Nodes to the Experiment
0426: // And set the properties for the Nodes.
0427: // Add all Nodes.
0428: addAgents(experiment, nodes, allagents, trialId, assemblyMatch);
0429:
0430: // Add all Hosts.
0431: Iterator hostIter = hosts.iterator();
0432: while (hostIter.hasNext()) {
0433: String hostName = (String) hostIter.next();
0434: HostComponent hc = experiment.addHost(hostName);
0435: setComponentProperties(hc, PopulateDb
0436: .getHostAlibId(hostName), assemblyMatch);
0437: }
0438: mapNodesToHosts(experiment, assemblyMatch);
0439:
0440: try {
0441: if (!ExperimentDB
0442: .isExperimentNameInDatabase(experimentName)) {
0443: if (log.isDebugEnabled()) {
0444: log.debug("Saving expt " + experimentName
0445: + " not in DB to DB");
0446: }
0447: experiment.save(saveToDbConflictHandler);
0448: } else {
0449: // Add the recipes to the expt_trial_mod_recipe table
0450: List rcs = new ArrayList();
0451: for (int i = 0; i < experiment
0452: .getRecipeComponentCount(); i++) {
0453: rcs.add(experiment.getRecipeComponent(i));
0454: }
0455:
0456: if (log.isDebugEnabled()) {
0457: log.debug("Setting recipes on experiment "
0458: + experiment.getExperimentID() + " in DB");
0459: }
0460:
0461: // Save the recipes on the experiment
0462: // Note that the recipe are not re-saved here
0463: PopulateDb pdb = null;
0464: try {
0465: pdb = new PopulateDb(experiment.getExperimentID(),
0466: experiment.getTrialID());
0467: pdb.setAndCleanModRecipes(rcs);
0468: } catch (Exception e) {
0469: if (log.isErrorEnabled()) {
0470: log.error(
0471: "Problem saving recipes on experiment "
0472: + experiment.getExperimentID(),
0473: e);
0474: }
0475: } finally {
0476: try {
0477: pdb.close();
0478: } catch (Exception e) {
0479: }
0480: }
0481: }
0482: } catch (RuntimeException e) {
0483: if (log.isErrorEnabled()) {
0484: log.error("RuntimeException saving experiment "
0485: + experimentName, e);
0486: }
0487: }
0488: experiment.resetModified(); // the experiment is NOT modified at this point
0489: return experiment;
0490: }
0491:
0492: private void createLogger() {
0493: if (log == null)
0494: log = CSMART.createLogger(this .getClass().getName());
0495: }
0496:
0497: /**
0498: * Get assembly ids for trial.
0499: */
0500: private ArrayList getTrialAssemblyIds(String experimentId,
0501: String trialId) {
0502: ArrayList assemblyIds = new ArrayList();
0503: String query = null;
0504: try {
0505: Connection conn = DBUtils.getConnection();
0506: try {
0507: Map substitutions = new HashMap();
0508: substitutions.put(":expt_id", experimentId);
0509: substitutions.put(":trial_id", trialId);
0510: Statement stmt = conn.createStatement();
0511: query = DBUtils.getQuery(EXPT_ASSEM_QUERY,
0512: substitutions);
0513: ResultSet rs = stmt.executeQuery(query);
0514: while (rs.next()) {
0515: String asmid = rs.getString(1);
0516: assemblyIds.add(asmid);
0517: }
0518: rs.close();
0519: stmt.close();
0520: } finally {
0521: conn.close();
0522: }
0523: } catch (SQLException se) {
0524: if (log.isErrorEnabled()) {
0525: log.error("Caught SQL exception getting Trial pieces: "
0526: + query, se);
0527: }
0528: }
0529:
0530: return assemblyIds;
0531: }
0532:
0533: /**
0534: * Get nodes for a trial.
0535: */
0536: private ArrayList getNodes(String trialId, String assemblyMatch) {
0537: ArrayList nodes = new ArrayList();
0538: String query = null;
0539: try {
0540: Connection conn = DBUtils.getConnection();
0541: try {
0542: Map substitutions = new HashMap();
0543: substitutions.put(":trial_id", trialId);
0544: substitutions.put(":assemblyMatch", assemblyMatch);
0545: Statement stmt = conn.createStatement();
0546: query = DBUtils
0547: .getQuery(EXPT_NODE_QUERY, substitutions);
0548: if (log.isDebugEnabled()) {
0549: log.debug("Organizer: Nodes query: " + query);
0550: }
0551: ResultSet rs = stmt.executeQuery(query);
0552: while (rs.next()) {
0553: nodes.add(rs.getString(1));
0554: }
0555: rs.close();
0556: stmt.close();
0557: } finally {
0558: conn.close();
0559: }
0560: } catch (SQLException se) {
0561: if (log.isErrorEnabled()) {
0562: log.error(
0563: "Caught SQL exception getting Nodes " + query,
0564: se);
0565: }
0566: }
0567: return nodes;
0568: }
0569:
0570: private ArrayList getHosts(String trialId, String assemblyMatch) {
0571: ArrayList hosts = new ArrayList();
0572: String query = null;
0573: try {
0574: Connection conn = DBUtils.getConnection();
0575: try {
0576: Map substitutions = new HashMap();
0577: substitutions.put(":assemblyMatch", assemblyMatch);
0578: Statement stmt = conn.createStatement();
0579: query = DBUtils
0580: .getQuery(EXPT_HOST_QUERY, substitutions);
0581: if (log.isDebugEnabled()) {
0582: log.debug("Organizer: Get hosts query: " + query);
0583: }
0584: ResultSet rs = stmt.executeQuery(query);
0585: while (rs.next()) {
0586: hosts.add(rs.getString(1));
0587: }
0588: rs.close();
0589: stmt.close();
0590: } finally {
0591: conn.close();
0592: }
0593: } catch (SQLException se) {
0594: if (log.isErrorEnabled()) {
0595: log.error("Caught SQL exception getting hosts: "
0596: + query, se);
0597: }
0598: }
0599:
0600: return hosts;
0601: }
0602:
0603: private void setDefaultNodeArguments(Experiment experiment,
0604: String assemblyMatch, String socAlibId) {
0605: try {
0606: Connection conn = DBUtils.getConnection();
0607: try {
0608: Statement stmt = conn.createStatement();
0609: Map substitutions = new HashMap();
0610: substitutions.put(":assemblyMatch", assemblyMatch);
0611: substitutions.put(":comp_alib_id", socAlibId);
0612: getComponentArguments(stmt, substitutions, experiment
0613: .getDefaultNodeArguments());
0614: stmt.close();
0615: } finally {
0616: conn.close();
0617: }
0618: } catch (SQLException se) {
0619: if (log.isErrorEnabled()) {
0620: log.error("Caught SQL exception setting NodeArgs", se);
0621: }
0622: }
0623: }
0624:
0625: private void mapNodesToHosts(Experiment experiment,
0626: String assemblyMatch) {
0627:
0628: // Note that getNodeC will do a node/agent reconcile,
0629: // and getHostC will do it again
0630: // As a result, loading an experiment from the DB, does a lot
0631: // of work trying to match Agents
0632: NodeComponent[] nodeComponents = experiment.getNodeComponents();
0633: HostComponent[] hostComponents = experiment
0634: .getHostComponentsNoReconcile();
0635: String query = null;
0636: try {
0637: Connection conn = DBUtils.getConnection();
0638: try {
0639: Map substitutions = new HashMap();
0640: substitutions.put(":assemblyMatch", assemblyMatch);
0641: Statement stmt = conn.createStatement();
0642: query = DBUtils.getQuery("queryHostNodes",
0643: substitutions);
0644: if (log.isDebugEnabled()) {
0645: log.debug("mapNodesToHosts: " + query);
0646: }
0647: ResultSet rs = stmt.executeQuery(query);
0648: while (rs.next()) {
0649: String hostName = rs.getString(1);
0650: String nodeName = rs.getString(2);
0651: for (int i = 0; i < hostComponents.length; i++) {
0652: HostComponent hc = hostComponents[i];
0653: if (hc.getShortName().equals(hostName)) {
0654: for (int j = 0; j < nodeComponents.length; j++) {
0655: NodeComponent nc = nodeComponents[j];
0656: if (nc.getShortName().equals(nodeName)) {
0657: hc.addNode(nc);
0658: break;
0659: }
0660: }
0661: break;
0662: }
0663: }
0664: }
0665: rs.close();
0666: stmt.close();
0667: } finally {
0668: conn.close();
0669: }
0670: } catch (SQLException se) {
0671: if (log.isErrorEnabled()) {
0672: log.error("Caught SQL exception getting HN map "
0673: + query, se);
0674: }
0675: }
0676: }
0677:
0678: private void addAgents(Experiment experiment, ArrayList nodes,
0679: AgentComponent[] agents, String trialId,
0680: String assemblyMatch) {
0681: Iterator iter = nodes.iterator();
0682: String query = null;
0683: try {
0684: Connection conn = DBUtils.getConnection();
0685: try {
0686: Map substitutions = new HashMap();
0687: substitutions.put(":trial_id", trialId);
0688: substitutions.put(":assemblyMatch", assemblyMatch);
0689: substitutions.put(":insertion_point",
0690: Agent.INSERTION_POINT);
0691: Statement stmt = conn.createStatement();
0692: NodeComponent nodeComponent = null;
0693: while (iter.hasNext()) {
0694: query = null;
0695: ResultSet rs;
0696: String nodeName = (String) iter.next();
0697: nodeComponent = experiment.addNode(nodeName);
0698: // if (log.isDebugEnabled()) {
0699: // log.debug("Adding node " + nodeName + " to experiment");
0700: // }
0701: setComponentProperties(nodeComponent, PopulateDb
0702: .getNodeAlibId(nodeName), assemblyMatch);
0703: substitutions.put(":parent_name", nodeName);
0704: substitutions.put(":comp_alib_id", PopulateDb
0705: .getNodeAlibId(nodeName));
0706: // Get args of the node
0707: Properties nodeProps = nodeComponent.getArguments();
0708: getComponentArguments(stmt, substitutions,
0709: nodeProps);
0710: // Query All Agents for each node.
0711: // Loop Query for every node.
0712: query = DBUtils.getQuery("queryComponents",
0713: substitutions);
0714: // if(log.isDebugEnabled()) {
0715: // log.debug("Organizer: Get agents: " + query);
0716: // }
0717: rs = stmt.executeQuery(query);
0718: while (rs.next()) {
0719: // Find AgentComponent.
0720: String aName = rs.getString(1);
0721: for (int i = 0; i < agents.length; i++) {
0722: AgentComponent ac = agents[i];
0723: if (ac.getShortName().equals(aName)) {
0724: nodeComponent.addAgent(ac);
0725: // if(log.isDebugEnabled()) {
0726: // log.debug("OrganizerHelper: Adding agent named: " + ac.getShortName() + " to Node " + nodeComponent.getShortName());
0727: // }
0728: break;
0729: }
0730: }
0731: }
0732: rs.close();
0733: }
0734: stmt.close();
0735: } finally {
0736: conn.close();
0737: }
0738: } catch (SQLException se) {
0739: if (log.isErrorEnabled()) {
0740: log.error("Caught SQL exception getting agents "
0741: + query, se);
0742: }
0743: }
0744: }
0745:
0746: private void getComponentArguments(Statement stmt,
0747: Map substitutions, Properties props) throws SQLException {
0748: boolean first = true;
0749: String query = DBUtils.getQuery(COMPONENT_ARGS_QUERY,
0750: substitutions);
0751: ResultSet rs = stmt.executeQuery(query);
0752: while (rs.next()) {
0753: String arg = rs.getString(1);
0754: if (arg.startsWith("-D")) {
0755: if (first) {
0756: props.clear();
0757: first = false;
0758: }
0759: int equalsIx = arg.indexOf('=', 2);
0760: String pname = arg.substring(2, equalsIx);
0761: String value = arg.substring(equalsIx + 1);
0762: props.setProperty(pname, value);
0763: }
0764: }
0765: rs.close();
0766: }
0767:
0768: private void setComponentProperties(BaseComponent cc,
0769: String comp_alib_id, String assemblyMatch) {
0770: String query = null;
0771: try {
0772: Connection conn = DBUtils.getConnection();
0773: try {
0774: Map substitutions = new HashMap();
0775: substitutions.put(":assemblyMatch", assemblyMatch);
0776: substitutions.put(":comp_alib_id", comp_alib_id);
0777: Statement stmt = conn.createStatement();
0778: query = DBUtils.getQuery(COMPONENT_ARGS_QUERY,
0779: substitutions);
0780: // if(log.isDebugEnabled()) {
0781: // log.debug("OrganizerHelper " + COMPONENT_ARGS_QUERY + ": " + query);
0782: // }
0783:
0784: ResultSet rs = stmt.executeQuery(query);
0785: while (rs.next()) {
0786: String param = rs.getString(1);
0787: if (param.startsWith(Experiment.PROP_PREFIX)) {
0788: int ix1 = Experiment.PROP_PREFIX.length();
0789: int ix2 = param.indexOf('=', ix1);
0790: String pname = param.substring(ix1, ix2);
0791: String pvalue = param.substring(ix2 + 1);
0792: Property prop = cc.getProperty(pname);
0793: if (prop == null) {
0794: // if(log.isDebugEnabled()) {
0795: // log.debug("adding " + pname + "=" + pvalue);
0796: // }
0797: cc.addProperty(pname, pvalue);
0798: } else {
0799: // if(log.isDebugEnabled()) {
0800: // log.debug("setting " + pname + "=" + pvalue);
0801: // }
0802: prop.setValue(pvalue);
0803: }
0804: }
0805: }
0806: rs.close();
0807: stmt.close();
0808: } finally {
0809: conn.close();
0810: }
0811: } catch (SQLException se) {
0812: if (log.isErrorEnabled()) {
0813: log.error("Caught SQL exception getting compArgs "
0814: + query, se);
0815: }
0816: }
0817: }
0818:
0819: // Get a list of DBRecipe objects for the recipes in an Experiment/Trial
0820: private List checkForRecipes(String trialId, String exptId) {
0821: List recipeList = new ArrayList();
0822: if (trialId == null || exptId == null) {
0823: if (log.isWarnEnabled())
0824: log
0825: .warn("Null trialId or ExptId when looking for recipes. Returning none.");
0826: return recipeList;
0827: }
0828: String query = null;
0829: try {
0830: Connection conn = DBUtils.getConnection();
0831: try {
0832: Map substitutions = new HashMap();
0833: substitutions.put(":trial_id", trialId);
0834: substitutions.put(":expt_id", exptId);
0835: Statement stmt = conn.createStatement();
0836: query = DBUtils.getQuery("queryRecipes", substitutions);
0837: ResultSet rs = stmt.executeQuery(query);
0838: while (rs.next()) {
0839: try {
0840: DbRecipe dbRecipe = new DbRecipe(rs
0841: .getString(2), Class.forName(rs
0842: .getString(3)));
0843: String recipeId = rs.getString(1);
0844: dbRecipe.id = recipeId;
0845: substitutions.put(":recipe_id", recipeId);
0846: getRecipeProperties(dbRecipe, conn,
0847: substitutions);
0848: recipeList.add(dbRecipe);
0849: } catch (ClassNotFoundException cnfe) {
0850: if (log.isErrorEnabled()) {
0851: log.error("for recipe", cnfe);
0852: }
0853: }
0854: }
0855: rs.close();
0856: stmt.close();
0857: } finally {
0858: conn.close();
0859: }
0860: } catch (SQLException se) {
0861: if (log.isErrorEnabled()) {
0862: log.error("Caught SQL exception getting recipes "
0863: + query, se);
0864: }
0865: }
0866:
0867: return recipeList;
0868: }
0869:
0870: /**
0871: * Get the available recipe names from the database for user selection.
0872: * @return Map of Recipe names to database IDs
0873: **/
0874: public static Map getRecipeNamesFromDatabase() {
0875: Logger log = CSMART
0876: .createLogger("org.cougaar.tools.csmart.ui.viewer.OrganizerHelper");
0877:
0878: Map recipes = new TreeMap();
0879: String query = null;
0880: try {
0881: Connection conn = DBUtils.getConnection();
0882: try {
0883: Statement stmt = conn.createStatement();
0884: Map substitutions = new HashMap();
0885: query = DBUtils.getQuery("queryLibRecipes",
0886: substitutions);
0887: ResultSet rs = stmt.executeQuery(query);
0888: while (rs.next()) {
0889: String id = rs.getString(1).trim();
0890: String name = rs.getString(2).trim();
0891:
0892: // Ignore bad Recipe name / IDs
0893: if (id == null || id.equals("") || name == null
0894: || name.equals("")) {
0895: if (log.isWarnEnabled()) {
0896: log
0897: .warn("getRecipeNames: Got bad Recipe name / ID: "
0898: + name + "/ " + id);
0899: }
0900: continue;
0901: }
0902: recipes.put(name, id);
0903: }
0904: rs.close();
0905: stmt.close();
0906: } finally {
0907: conn.close();
0908: }
0909: } catch (SQLException se) {
0910: if (log.isErrorEnabled()) {
0911: log.error("Caught SQL exception getting recipe names "
0912: + query, se);
0913: }
0914: }
0915:
0916: return recipes;
0917: }
0918:
0919: // This must match PDbBase.isRecipeEqual
0920: private void getRecipeProperties(DbRecipe dbRecipe,
0921: Connection conn, Map substitutions) throws SQLException {
0922: Statement stmt = conn.createStatement();
0923: String query = DBUtils.getQuery("queryRecipeProperties",
0924: substitutions);
0925: ResultSet rs = stmt.executeQuery(query);
0926:
0927: while (rs.next()) {
0928: String rs1 = rs.getString(1);
0929: if (rs1.equalsIgnoreCase(ComplexRecipeBase.ASSEMBLY_PROP)) {
0930: // Query the Assembly Table for the correct data.
0931: continue;
0932: } else {
0933: String rs2 = rs.getString(2);
0934: // FIXME: This loses the ordering of the recipe properties!
0935: dbRecipe.props.put(rs1, rs2);
0936: }
0937: }
0938: rs.close();
0939: }
0940:
0941: // Get a recipe whose ID and name are as specified in the enclosed
0942: // object, using following method
0943: protected RecipeComponent getDatabaseRecipe(DbRecipe dbr) {
0944: if (dbr == null)
0945: return null;
0946: if (dbr.id == null)
0947: return null;
0948: if (dbr.name == null)
0949: return null;
0950: return getDatabaseRecipe(dbr.id, dbr.name);
0951: }
0952:
0953: // If we have a recipe by this name in the workspace, return it
0954: // Otherwise, get it from the DB
0955: // The ID is one that exists in the DB, and the name
0956: // is the new one we want, possibly same as the one in the DB
0957: protected RecipeComponent getDatabaseRecipe(String recipeId,
0958: String recipeName) {
0959: createLogger();
0960:
0961: String query = null;
0962: RecipeComponent rc = null;
0963:
0964: // Right up here, try to get the recipe from the workspace,
0965: // and return it if its there
0966: rc = organizer.getRecipe(recipeName);
0967: if (rc != null)
0968: return rc;
0969:
0970: try {
0971: Connection conn = DBUtils.getConnection();
0972: try {
0973: Map substitutions = new HashMap();
0974: substitutions.put(":recipe_id", recipeId);
0975: Statement stmt = conn.createStatement();
0976: query = DBUtils.getQuery("queryRecipe", substitutions);
0977: ResultSet rs = stmt.executeQuery(query);
0978: String name = null; // the original recipe name
0979: String className = null;
0980: if (rs.next()) {
0981: name = rs.getString(2);
0982: className = rs.getString(3);
0983: }
0984:
0985: // Done with these DB resources - close them up
0986: try {
0987: rs.close();
0988: stmt.close();
0989: } catch (SQLException sqe) {
0990: }
0991:
0992: // If we found the recipe in the DB
0993: if (name != null) {
0994: // get the Class
0995: Class recipeClass = null;
0996: if (className != null) {
0997: try {
0998: recipeClass = Class.forName(className);
0999: } catch (ClassNotFoundException cnfe) {
1000: if (log.isErrorEnabled())
1001: log.error("Creating recipe from "
1002: + recipeId, cnfe);
1003: }
1004: }
1005:
1006: // Is it complex?
1007: if (isComplexRecipe(conn, substitutions)) {
1008: if (log.isDebugEnabled()) {
1009: log
1010: .debug("Creating Complex Recipe from Database");
1011: }
1012: String assemblyId = getRecipeAssembly(conn,
1013: substitutions);
1014:
1015: if (assemblyId == null) {
1016: if (log.isErrorEnabled()) {
1017: log
1018: .error("Cannot locate proper assemblyId loading RecipeID "
1019: + recipeId
1020: + ". Load Failed");
1021: }
1022: rc = null;
1023: }
1024:
1025: // FIXME: Save it before returning it?
1026: // FIXME: Use name (original) or recipeName (new)??
1027: // if dont use orig, cant correctly load comps
1028: // if dont use new then we're getting potentially 2nd
1029: // copy of existing recipe
1030: if (recipeName.equals(name)) {
1031: rc = createRecipeUsingCon(new String[] {
1032: recipeName, assemblyId, recipeId },
1033: recipeClass, threeStringConstructor);
1034: } else {
1035: rc = createRecipeUsingCon(new String[] {
1036: recipeName, assemblyId, recipeId,
1037: name }, recipeClass,
1038: fourStringConstructor);
1039: if (rc != null)
1040: rc.saveToDatabase();
1041: }
1042:
1043: } else {
1044: if (log.isDebugEnabled()) {
1045: log.debug("Creating Simple Recipe "
1046: + recipeName + " from ID "
1047: + recipeId + " from Database");
1048: }
1049: // Start with the old name for getting the recipe props
1050: DbRecipe dbRecipe = new DbRecipe(name,
1051: recipeClass);
1052: dbRecipe.id = recipeId;
1053: getRecipeProperties(dbRecipe, conn,
1054: substitutions);
1055: // Now set the new name
1056: dbRecipe.name = recipeName;
1057: rc = createRecipe(dbRecipe.name, dbRecipe.cls);
1058: if (rc != null) {
1059: setRecipeComponentProperties(dbRecipe, rc);
1060: rc.saveToDatabase();
1061: }
1062: } // end of SimpleRecipe handling
1063: } // end of block for found the recipe
1064:
1065: if (rc == null && log.isErrorEnabled()) {
1066: log.error("Recipe not found: " + recipeId);
1067: }
1068: } finally {
1069: conn.close();
1070: }
1071: } catch (SQLException se) {
1072: if (log.isErrorEnabled()) {
1073: log.error("Caught SQL exception getting DBRecipe "
1074: + query, se);
1075: }
1076: }
1077: return rc;
1078: }
1079:
1080: // Is the recipe whose ID is in the substitutions Complex?
1081: private boolean isComplexRecipe(Connection conn, Map substitutions) {
1082: boolean retVal = false;
1083: try {
1084: Statement stmt = conn.createStatement();
1085: try {
1086: String query = DBUtils.getQuery(
1087: "queryRecipeProperties", substitutions);
1088: ResultSet rs = stmt.executeQuery(query);
1089:
1090: // If the recipe has an Assembly, it is Complex
1091: while (rs.next()) {
1092: if (rs.getString(1).equalsIgnoreCase(
1093: ComplexRecipeBase.ASSEMBLY_PROP)) {
1094: retVal = true;
1095: break;
1096: }
1097: }
1098: rs.close();
1099: stmt.close();
1100: } catch (SQLException sqle) {
1101: if (log.isErrorEnabled()) {
1102: log
1103: .error("SQLException checking recipe type",
1104: sqle);
1105: }
1106: }
1107: } catch (SQLException sqe) {
1108: if (log.isErrorEnabled()) {
1109: log.error("SQLException checking recipe type", sqe);
1110: }
1111: }
1112:
1113: return retVal;
1114: }
1115:
1116: private String getRecipeAssembly(Connection conn, Map substitutions) {
1117: String assemblyId = null;
1118: try {
1119: Statement stmt = conn.createStatement();
1120: try {
1121: String query = DBUtils.getQuery(
1122: "queryRecipeProperties", substitutions);
1123: ResultSet rs = stmt.executeQuery(query);
1124:
1125: while (rs.next()) {
1126: if (rs.getString(1).equalsIgnoreCase(
1127: ComplexRecipeBase.ASSEMBLY_PROP)) {
1128: assemblyId = rs.getString(2);
1129: }
1130: }
1131: rs.close();
1132: } catch (SQLException sqle) {
1133: if (log.isErrorEnabled()) {
1134: log.error(
1135: "SQLException getting recipe Assembly Id",
1136: sqle);
1137: }
1138: }
1139: } catch (SQLException sqe) {
1140: if (log.isErrorEnabled()) {
1141: log.error("SQLException getting recipe Assembly Id",
1142: sqe);
1143: }
1144: }
1145:
1146: return assemblyId;
1147: }
1148:
1149: private void setRecipeComponentProperties(DbRecipe dbRecipe,
1150: RecipeComponent rc) {
1151: if (rc != null && dbRecipe != null && dbRecipe.props != null)
1152: rc.setProperties(dbRecipe.props);
1153: }
1154:
1155: private static Class[] singleStringConstructor = { String.class };
1156:
1157: private static Class[] twoStringConstructor = { String.class,
1158: String.class };
1159:
1160: private static Class[] threeStringConstructor = { String.class,
1161: String.class, String.class };
1162:
1163: private static Class[] fourStringConstructor = { String.class,
1164: String.class, String.class, String.class };
1165:
1166: private static Class[] multiConstructor = { String.class,
1167: String[].class };
1168:
1169: // Warning: only use this for _simple_ recipes or for
1170: // and empty Complex recipe
1171: protected RecipeComponent createRecipe(String name, Class cls) {
1172: return createRecipeUsingCon(new String[] { name }, cls,
1173: singleStringConstructor);
1174: }
1175:
1176: // Generic method to create a recipe. Takes an array of strings
1177: // suitable for passing to the given constructor
1178: protected RecipeComponent createRecipeUsingCon(String[] names,
1179: Class cls, Class[] con) {
1180: if (cls == null)
1181: return null;
1182:
1183: if (names == null || names.length == 0 || names[0] == null)
1184: return null;
1185:
1186: if (con == null)
1187: return null;
1188:
1189: createLogger();
1190:
1191: try {
1192: Constructor constructor = cls.getConstructor(con);
1193: RecipeComponent recipe = (RecipeComponent) constructor
1194: .newInstance(names);
1195: recipe.initProperties();
1196: ((RecipeBase) recipe).resetModified();
1197: ((RecipeBase) recipe).installListeners();
1198: return recipe;
1199: } catch (Exception e) {
1200: if (log.isErrorEnabled()) {
1201: log.error("Exception creating recipe " + names[0]
1202: + " of class " + cls.getName(), e);
1203: }
1204: return null;
1205: }
1206: }
1207:
1208: /**
1209: * Load a recipe by name. Note that the returned recipe may be null
1210: * if no such recipe exists.
1211: *
1212: * @param name a <code>String</code> recipe name to try to load from teh DB
1213: * @return a <code>RecipeComponent</code> with that name from the DB, possibly null if none found
1214: */
1215: protected RecipeComponent loadRecipeNamed(String name) {
1216: if (name == null || name.trim().equals(""))
1217: return null;
1218: // First, get any recipe assembly ID for the Recipe
1219: Map names = getRecipeNamesFromDatabase();
1220: String recipeId = (String) names.get(name);
1221: if (recipeId == null || recipeId.trim().equals(""))
1222: return null;
1223: return getDatabaseRecipe(recipeId, name);
1224: }
1225:
1226: /**
1227: * Delete the named recipe from the database.
1228: * @param name the name of the recipe to delete
1229: */
1230: public void deleteRecipe(String name) throws Exception {
1231: // First, get any recipe assembly ID for the Recipe
1232: Map names = getRecipeNamesFromDatabase();
1233: String recipeId = (String) names.get(name);
1234: String asb = null;
1235: if (recipeId != null && !recipeId.trim().equals("")) {
1236: try {
1237: Connection conn = DBUtils.getConnection();
1238: try {
1239: Map subs = new HashMap();
1240: subs.put(":recipe_id", recipeId);
1241: asb = getRecipeAssembly(conn, subs);
1242: } catch (Exception sqe) {
1243: if (log.isWarnEnabled()) {
1244: log.warn(
1245: "deleteRecipe failed getting recipe assemblyID for recipe "
1246: + name, sqe);
1247: }
1248: } finally {
1249: conn.close();
1250: }
1251: } catch (SQLException sqe) {
1252: if (log.isInfoEnabled()) {
1253: log.info(
1254: "Error getting connection in deleteRecipe",
1255: sqe);
1256: }
1257: }
1258: }
1259:
1260: // Now delete the basic definition of the recipe.
1261: PDbBase pdb = new PDbBase();
1262: try {
1263: pdb.removeLibRecipeNamed(name);
1264: } finally {
1265: pdb.close();
1266: }
1267:
1268: // Finally, delete the assembly portion of the recipe
1269: // (now that the assembly is not used anymore)
1270: if (asb != null) {
1271: try {
1272: PopulateDb.deleteSociety(asb);
1273: } catch (SQLException sqe) {
1274: if (log.isWarnEnabled())
1275: log.warn("deleteSoc failed removing asb " + asb
1276: + " for recipe " + name, sqe);
1277: } catch (IOException ioe) {
1278: if (log.isWarnEnabled())
1279: log.warn("deleteSoc failed removing asb " + asb
1280: + " for recipe " + name, ioe);
1281: }
1282: }
1283: } // end of deleteRecipe
1284:
1285: /**
1286: * Create a new society from a node file which enumerates
1287: * the names of the agents in the society.
1288: * @param name a <code>String</code> node file name
1289: * @param socName a <code>String</code> name for the new society
1290: * @param cls a <code>Class</code> Class of Society to create
1291: * @return a <code>SocietyComponent</code>
1292: */
1293: public SocietyComponent createSociety(String name, String socName,
1294: Class cls) {
1295: createLogger();
1296:
1297: try {
1298: Constructor constructor = cls
1299: .getConstructor(twoStringConstructor);
1300: SocietyComponent sc = (SocietyComponent) constructor
1301: .newInstance(new String[] { name, socName });
1302: sc.initProperties();
1303: sc.saveToDatabase();
1304: return sc;
1305: } catch (Exception e) {
1306: if (log.isErrorEnabled()) {
1307: log.error("Exception creating society " + name + " of "
1308: + cls.toString(), e);
1309: }
1310: return null;
1311: }
1312: }
1313:
1314: /**
1315: * Create a society from files, each of which defines an agent.
1316: * @param name the name of the society
1317: * @param filenames the names of files, each of which defines an agent
1318: * @param cls the class to create
1319: */
1320:
1321: public SocietyComponent createSociety(String name,
1322: String[] filenames, Class cls) {
1323: createLogger();
1324:
1325: try {
1326: Constructor constructor = cls
1327: .getConstructor(multiConstructor);
1328: SocietyComponent sc = (SocietyComponent) constructor
1329: .newInstance(new Object[] { name, filenames });
1330: sc.initProperties();
1331: sc.saveToDatabase();
1332: return sc;
1333: } catch (Exception e) {
1334: if (log.isErrorEnabled()) {
1335: log.error("Exception creating society " + name + " of "
1336: + cls.toString(), e);
1337: }
1338: return null;
1339: }
1340: }
1341:
1342: protected SocietyComponent createSocietyFromFile() {
1343: // display file chooser to allow user to select file that defines society
1344: JFileChooser chooser = new JFileChooser(System
1345: .getProperty("org.cougaar.install.path"));
1346: chooser
1347: .setDialogTitle("Select directory of Agent INI files or a single Node INI to load");
1348: chooser
1349: .setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
1350: File file = null;
1351: SocietyComponent sc = null;
1352: while (file == null) {
1353: int result = chooser.showDialog(organizer, "OK");
1354: if (result != JFileChooser.APPROVE_OPTION)
1355: return null;
1356: file = chooser.getSelectedFile();
1357: if (file != null && !file.canRead())
1358: file = null;
1359: }
1360:
1361: // create society from agent files or single node file
1362: String name = "";
1363: name = file.getName();
1364: if (name.endsWith(".ini"))
1365: name = name.substring(0, name.length() - 4);
1366: if (!organizer.isUniqueSocietyName(name))
1367: name = organizer.getUniqueSocietyName(name, false);
1368: if (name == null)
1369: return null;
1370:
1371: if (file.isDirectory()) {
1372: String[] filenames = SocietyFinder.getInstance()
1373: .getAgentFilenames(file);
1374:
1375: if (filenames == null || filenames.length == 0) {
1376: // Found no Agents
1377: if (log.isWarnEnabled()) {
1378: log.warn("Found no agent in dir " + file.getPath());
1379: }
1380: return null;
1381: }
1382:
1383: sc = createSociety(name, filenames,
1384: SocietyFileComponent.class);
1385: } else {
1386: sc = createSociety(file.getPath(), name,
1387: SocietyFileComponent.class);
1388: }
1389: return sc;
1390: }
1391:
1392: // Class for holding name/Class pairs in UIs
1393: // TODO: this is defined in Organizer as well
1394: // possibly needs to be in some utility class
1395: // it's not really UI related at all;
1396: // it's simply a way to store both a name and class
1397: private static class NameClassItem {
1398: public String name;
1399: public Class cls;
1400:
1401: public NameClassItem(String name, Class cls) {
1402: this .cls = cls;
1403: this .name = name;
1404: }
1405:
1406: public String toString() {
1407: return name;
1408: }
1409:
1410: // 2 NameClassItems are equals if they have the same name & class
1411: public boolean equals(Object o) {
1412: if (o instanceof NameClassItem) {
1413: NameClassItem nci = (NameClassItem) o;
1414: if (name != null && name.equals(nci.name)) {
1415: if (cls != null && cls.equals(nci.cls))
1416: return true;
1417: else if (cls == null && nci.cls == null)
1418: return true;
1419: else
1420: return false;
1421: } else if (name == null && nci.name == null) {
1422: if (cls != null && cls.equals(nci.cls))
1423: return true;
1424: else if (cls == null && nci.cls == null)
1425: return true;
1426: else
1427: return false;
1428: }
1429: }
1430: return false;
1431: }
1432: }
1433:
1434: private static class DbRecipe extends NameClassItem {
1435: public Map props = new TreeMap();
1436: public String id = null;
1437:
1438: public DbRecipe(String name, Class cls) {
1439: super (name, cls);
1440: }
1441: }
1442:
1443: private void readObject(ObjectInputStream ois) throws IOException,
1444: ClassNotFoundException {
1445: ois.defaultReadObject();
1446: createLogger();
1447: }
1448:
1449: }
|