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: package org.cougaar.mlm.plugin.organization;
0027:
0028: import java.io.BufferedReader;
0029: import java.io.InputStreamReader;
0030: import java.io.Reader;
0031: import java.io.StreamTokenizer;
0032: import java.lang.reflect.Constructor;
0033: import java.lang.reflect.Field;
0034: import java.lang.reflect.Method;
0035: import java.util.ArrayList;
0036: import java.util.Calendar;
0037: import java.util.Collection;
0038: import java.util.Date;
0039: import java.util.Enumeration;
0040: import java.util.HashMap;
0041: import java.util.Iterator;
0042: import java.util.List;
0043: import java.util.Vector;
0044:
0045: import org.cougaar.core.mts.MessageAddress;
0046: import org.cougaar.glm.ldm.Constants;
0047: import org.cougaar.glm.ldm.GLMFactory;
0048: import org.cougaar.glm.ldm.asset.AssignedPGImpl;
0049: import org.cougaar.glm.ldm.asset.Facility;
0050: import org.cougaar.glm.ldm.asset.NewAssignedPG;
0051: import org.cougaar.glm.ldm.asset.NewAssignmentPG;
0052: import org.cougaar.glm.ldm.asset.NewPositionPG;
0053: import org.cougaar.glm.ldm.asset.Organization;
0054: import org.cougaar.glm.ldm.asset.OrganizationAdapter;
0055: import org.cougaar.glm.ldm.asset.PositionPGImpl;
0056: import org.cougaar.glm.ldm.asset.TransportationNode;
0057: import org.cougaar.glm.ldm.plan.GLMRelationship;
0058: import org.cougaar.glm.ldm.plan.NewGeolocLocation;
0059: import org.cougaar.glm.ldm.plan.NewPosition;
0060: import org.cougaar.planning.ldm.asset.CommunityPGImpl;
0061: import org.cougaar.planning.ldm.asset.LocationSchedulePG;
0062: import org.cougaar.planning.ldm.asset.LocationSchedulePGImpl;
0063: import org.cougaar.planning.ldm.asset.NewClusterPG;
0064: import org.cougaar.planning.ldm.asset.NewItemIdentificationPG;
0065: import org.cougaar.planning.ldm.asset.NewLocationSchedulePG;
0066: import org.cougaar.planning.ldm.asset.NewPropertyGroup;
0067: import org.cougaar.planning.ldm.asset.NewTypeIdentificationPG;
0068: import org.cougaar.planning.ldm.asset.PropertyGroup;
0069: import org.cougaar.planning.ldm.asset.PropertyGroupSchedule;
0070: import org.cougaar.planning.ldm.plan.AspectType;
0071: import org.cougaar.planning.ldm.plan.AspectValue;
0072: import org.cougaar.planning.ldm.plan.Location;
0073: import org.cougaar.planning.ldm.plan.NewPrepositionalPhrase;
0074: import org.cougaar.planning.ldm.plan.NewRoleSchedule;
0075: import org.cougaar.planning.ldm.plan.NewSchedule;
0076: import org.cougaar.planning.ldm.plan.NewTask;
0077: import org.cougaar.planning.ldm.plan.Preference;
0078: import org.cougaar.planning.ldm.plan.Relationship;
0079: import org.cougaar.planning.ldm.plan.Role;
0080: import org.cougaar.planning.ldm.plan.Schedule;
0081: import org.cougaar.planning.ldm.plan.ScoringFunction;
0082: import org.cougaar.planning.ldm.plan.TaggedLocationScheduleElement;
0083: import org.cougaar.planning.ldm.plan.TimeAspectValue;
0084: import org.cougaar.planning.plugin.legacy.SimplePlugin;
0085: import org.cougaar.util.EmptyEnumeration;
0086: import org.cougaar.util.Reflect;
0087: import org.cougaar.util.TimeSpan;
0088:
0089: /**
0090: * Plugin to create a local asset and the Report tasks
0091: * associated with all the local asset's relationships based on an
0092: * initialization file - <agent-name>-prototype-ini.dat
0093: *
0094: * Local asset must have ClusterPG and
0095: * RelationshipPG, Presumption is that the 'other' assets in all the
0096: * relationships have both Cluster and Relationship PGs.
0097: * Currently assumes that each Agent has exactly 1 local asset.
0098: *
0099: * @deprecated Uses file format which is no longer supported. Use
0100: * OrgDataPlugin or OrgDataParamBasedPlugin insteadt.
0101: *
0102: */
0103:
0104: public class OrgRTDataPlugin extends SimplePlugin {
0105: private static TrivialTimeSpan ETERNITY = new TrivialTimeSpan(
0106: TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE);
0107:
0108: private final static String UTC = "UTC/RTOrg";
0109:
0110: private static Calendar myCalendar = Calendar.getInstance();
0111:
0112: private static long DEFAULT_START_TIME = -1;
0113: private static long DEFAULT_END_TIME = -1;
0114:
0115: static {
0116: myCalendar.set(1990, 0, 1, 0, 0, 0);
0117: DEFAULT_START_TIME = myCalendar.getTime().getTime();
0118:
0119: myCalendar.set(2010, 0, 1, 0, 0, 0);
0120: DEFAULT_END_TIME = myCalendar.getTime().getTime();
0121: }
0122:
0123: private Vector organization_vector = new Vector();
0124: private Organization selfOrg;
0125: private GLMFactory aldmf;
0126:
0127: public void load() {
0128: super .load();
0129:
0130: try {
0131: getBlackboardService().openTransaction();
0132:
0133: aldmf = (GLMFactory) getFactory("glm");
0134: getBlackboardService().setShouldBePersisted(false);
0135:
0136: if (!didRehydrate()) {
0137: processOrganizations(); // Objects should already exist after rehydration
0138: }
0139:
0140: } finally {
0141: getBlackboardService().closeTransaction();
0142: }
0143: }
0144:
0145: protected void setupSubscriptions() {
0146: }
0147:
0148: public void execute() {
0149: }
0150:
0151: /**
0152: * Parses the prototype-ini file and in the process sets up
0153: * the organization_vector with pairs of "relationship"/"organization"
0154: * It then loops through the vector and for each organization
0155: * it parses the appropriate prototype-ini file.
0156: */
0157: protected void processOrganizations() {
0158: try {
0159: String aId = getMessageAddress().getAddress();
0160: String filename = aId + "-prototype-ini.dat";
0161: if (didSpawn())
0162: filename = originalAgentID + "-prototype-ini.dat";
0163:
0164: ParsePrototypeFile(filename, aId, GLMRelationship.SELF);
0165:
0166: // Put the organizations for this agent into array
0167: String organizations[][] = new String[organization_vector
0168: .size()][3];
0169: organization_vector.copyInto(organizations);
0170: // For each organization, parse appropriate prototype-ini file
0171: for (int j = 0; j < organizations.length; j++) {
0172: // 980723 EWD changed second condition to use index 1 instead of 0
0173: if ((organizations[j][0] != null)
0174: && (organizations[j][1] != null)) {
0175: Class r_class = GLMRelationship.class;
0176: Field f = r_class.getField(organizations[j][0]
0177: .toUpperCase());
0178: if ((GLMRelationship.SUPPORTING)
0179: .equals(f.get(null))) {
0180: cloneMe(organizations[j][1],
0181: organizations[j][2]);
0182: } else if ((GLMRelationship.SUPERIOR).equals(f
0183: .get(null))) {
0184: createSuperior(organizations[j][1]);
0185: }
0186: }
0187: }
0188: } catch (Exception e) {
0189: e.printStackTrace();
0190: }
0191: }
0192:
0193: protected void createSuperior(String sup) {
0194: if ((sup == null) || (sup.equals(""))) {
0195: System.err.println("OrgRTDataPlugin@" + getMessageAddress()
0196: + " ignoring Superior specified as \"\"");
0197: return;
0198: }
0199:
0200: Organization super iorOrg = createOrganization(sup);
0201:
0202: if (super iorOrg == null) {
0203: throw new RuntimeException(
0204: "OrgRTDataPlugin: Unable to create superior org asset "
0205: + sup);
0206: } else if (selfOrg == null) {
0207: throw new RuntimeException(
0208: "OrgRTDataPlugin: selfOrg is null in createSuperior");
0209: }
0210:
0211: NewAssignedPG super iorCapability;
0212:
0213: if (!super iorOrg.hasAssignedPG()) {
0214: super iorCapability = (NewAssignedPG) getFactory()
0215: .createPropertyGroup(AssignedPGImpl.class);
0216: } else {
0217: super iorCapability = (NewAssignedPG) super iorOrg
0218: .getAssignedPG().copy();
0219: }
0220:
0221: ArrayList roles = new ArrayList(1);
0222: roles.add(Constants.Role.ADMINISTRATIVESUPERIOR);
0223: super iorCapability.setRoles(roles);
0224: super iorOrg.setAssignedPG(super iorCapability);
0225:
0226: // clone the selfOrg
0227: Organization clone = (Organization) getFactory().cloneInstance(
0228: selfOrg);
0229: NewAssignedPG cloneCapability;
0230:
0231: if (!clone.hasAssignedPG()) {
0232: cloneCapability = (NewAssignedPG) getFactory()
0233: .createPropertyGroup(AssignedPGImpl.class);
0234: } else {
0235: cloneCapability = (NewAssignedPG) clone.getAssignedPG()
0236: .copy();
0237: }
0238: roles.clear();
0239: roles.add(Constants.Role.ADMINISTRATIVESUBORDINATE);
0240: cloneCapability.setRoles(roles);
0241: clone.setAssignedPG(cloneCapability);
0242:
0243: publish(createRFD(super iorOrg, clone, roles));
0244: }
0245:
0246: // creates a copy of my "self" org with special capable roles to send to a
0247: // agent I am supporting.
0248: // Also create a client org in this agent
0249: protected void cloneMe(String sendto, String caproles) {
0250: if (selfOrg == null) {
0251: System.err
0252: .println("OrgRTDataPlugin: selfOrg is null in cloneMe");
0253: return;
0254: }
0255:
0256: if ((sendto == null) || (sendto.equals(""))) {
0257: System.err.println("OrgRTDataPlugin@" + getMessageAddress()
0258: + " ignoring " + caproles
0259: + " customer specified as \"\"");
0260: return;
0261: }
0262:
0263: // clone the selfOrg
0264: Organization clone = (Organization) getFactory().cloneInstance(
0265: selfOrg);
0266: Organization client = createOrganization(sendto);
0267:
0268: if (client == null) {
0269: System.err
0270: .println("OrgRTDataPlugin: Unable to create client "
0271: + sendto);
0272: return;
0273: }
0274:
0275: //To assist in debugging, I've broken the assignement into chunks
0276: NewAssignedPG cloneCapability;
0277:
0278: if (!clone.hasAssignedPG()) {
0279: cloneCapability = (NewAssignedPG) getFactory()
0280: .createPropertyGroup(AssignedPGImpl.class);
0281: } else {
0282: cloneCapability = (NewAssignedPG) clone.getAssignedPG()
0283: .copy();
0284: }
0285:
0286: //To assist in debugging, I've broken the assignement into chunks
0287: NewAssignedPG clientCapability;
0288:
0289: if (!client.hasAssignedPG()) {
0290: clientCapability = (NewAssignedPG) getFactory()
0291: .createPropertyGroup(AssignedPGImpl.class);
0292: } else {
0293: clientCapability = (NewAssignedPG) (client.getAssignedPG()
0294: .copy());
0295: }
0296:
0297: Vector rolestrs = org.cougaar.util.StringUtility
0298: .parseCSV(caproles);
0299: Collection roles = new ArrayList();
0300:
0301: for (Iterator i = rolestrs.iterator(); i.hasNext();) {
0302: Role role = Role.getRole((String) i.next());
0303: roles.add(role);
0304: }
0305: cloneCapability.setRoles(roles);
0306: clone.setAssignedPG(cloneCapability);
0307:
0308: publish(createRFS(client, clone, roles));
0309: }
0310:
0311: protected Organization createOrganization(String orgStr) {
0312: final String uic = orgStr.startsWith("UIC/") ? orgStr : "UIC/"
0313: .concat(orgStr);
0314:
0315: // Use the same domain name for all org assets now
0316: Organization org = (Organization) getFactory().createAsset(
0317: "Organization");
0318: org.initRelationshipSchedule();
0319: org.setLocal(false);
0320:
0321: ((NewTypeIdentificationPG) org.getTypeIdentificationPG())
0322: .setTypeIdentification(UTC);
0323:
0324: NewItemIdentificationPG itemIdProp = (NewItemIdentificationPG) org
0325: .getItemIdentificationPG();
0326: itemIdProp.setItemIdentification(uic);
0327: itemIdProp.setNomenclature(orgStr);
0328: itemIdProp.setAlternateItemIdentification(orgStr);
0329:
0330: NewClusterPG cpg = (NewClusterPG) org.getClusterPG();
0331: cpg.setMessageAddress(MessageAddress.getMessageAddress(orgStr));
0332:
0333: CommunityPGImpl communityPG = (CommunityPGImpl) getFactory()
0334: .createPropertyGroup(CommunityPGImpl.class);
0335: PropertyGroupSchedule schedule = new PropertyGroupSchedule();
0336:
0337: // add in COUGAAR community for default time span
0338: ArrayList communities = new ArrayList(1);
0339: communities.add("COUGAAR");
0340: communityPG.setCommunities(communities);
0341: communityPG.setTimeSpan(DEFAULT_START_TIME, DEFAULT_END_TIME);
0342: schedule.add(communityPG);
0343: org.setCommunityPGSchedule(schedule);
0344:
0345: return org;
0346: }
0347:
0348: //create the RFD task to be sent to myself which will result in an asset transfer
0349: // of myself being sent to the agent I am supporting.
0350: protected NewTask createRFD(Organization sup, Organization sub,
0351: Collection roles) {
0352: NewTask rfdTask = createReportTask(sub, sup, roles,
0353: DEFAULT_START_TIME, DEFAULT_END_TIME);
0354: rfdTask.setVerb(Constants.Verb.ReportForDuty);
0355:
0356: return rfdTask;
0357: }
0358:
0359: //create the RFD task to be sent to myself which will result in an asset transfer
0360: // of myself being sent to the agent I am supporting.
0361: protected NewTask createRFS(Organization client,
0362: Organization reportingOrg, Collection roles) {
0363: NewTask rfsTask = createReportTask(reportingOrg, client, roles,
0364: DEFAULT_START_TIME, DEFAULT_END_TIME);
0365: rfsTask.setVerb(Constants.Verb.ReportForService);
0366:
0367: return rfsTask;
0368: }
0369:
0370: //create the RFS task to be sent to myself which will result in an asset transfer
0371: // of the copyofmyself being sent to the agent I am supporting.
0372: protected NewTask createReportTask(Organization reportingOrg,
0373: OrganizationAdapter sendto, Collection roles,
0374: long startTime, long endTime) {
0375: NewTask reportTask = getFactory().newTask();
0376: reportTask.setDirectObject(reportingOrg);
0377:
0378: Vector prepPhrases = new Vector(2);
0379: NewPrepositionalPhrase newpp = getFactory()
0380: .newPrepositionalPhrase();
0381: newpp.setPreposition(Constants.Preposition.FOR);
0382: newpp.setIndirectObject(sendto);
0383: prepPhrases.add(newpp);
0384:
0385: newpp = getFactory().newPrepositionalPhrase();
0386: newpp.setPreposition(Constants.Preposition.AS);
0387: newpp.setIndirectObject(roles);
0388: prepPhrases.add(newpp);
0389: reportTask.setPrepositionalPhrases(prepPhrases.elements());
0390:
0391: reportTask.setPlan(getFactory().getRealityPlan());
0392: reportTask.setSource(getMessageAddress());
0393:
0394: AspectValue startTAV = TimeAspectValue.create(
0395: AspectType.START_TIME, startTime);
0396: ScoringFunction startScoreFunc = ScoringFunction
0397: .createStrictlyAtValue(startTAV);
0398: Preference startPreference = getFactory().newPreference(
0399: AspectType.START_TIME, startScoreFunc);
0400:
0401: AspectValue endTAV = TimeAspectValue.create(
0402: AspectType.END_TIME, endTime);
0403: ScoringFunction endScoreFunc = ScoringFunction
0404: .createStrictlyAtValue(endTAV);
0405: Preference endPreference = getFactory().newPreference(
0406: AspectType.END_TIME, endScoreFunc);
0407:
0408: Vector preferenceVector = new Vector(2);
0409: preferenceVector.addElement(startPreference);
0410: preferenceVector.addElement(endPreference);
0411:
0412: reportTask.setPreferences(preferenceVector.elements());
0413:
0414: return reportTask;
0415: }
0416:
0417: private void publish(Object o) {
0418: publishAdd(o);
0419: }
0420:
0421: /**
0422: *
0423: */
0424: protected void ParsePrototypeFile(String filename, String agentId,
0425: String relationship) {
0426:
0427: // Use the same domainname for all org assets now
0428: String uic = "";
0429: String className = "";
0430: String unitName = null;
0431: String dataItem = "";
0432: Organization org = null;
0433: int newVal;
0434:
0435: BufferedReader input = null;
0436: Reader fileStream = null;
0437:
0438: try {
0439: fileStream = new InputStreamReader(getConfigFinder().open(
0440: filename));
0441: input = new BufferedReader(fileStream);
0442: StreamTokenizer tokens = new StreamTokenizer(input);
0443: tokens.commentChar('#');
0444: tokens.wordChars('[', ']');
0445: tokens.wordChars('_', '_');
0446: tokens.wordChars('<', '>');
0447: tokens.wordChars('/', '/');
0448: tokens.ordinaryChars('0', '9');
0449: tokens.wordChars('0', '9');
0450:
0451: newVal = tokens.nextToken();
0452: // Parse the prototype-ini file
0453: while (newVal != StreamTokenizer.TT_EOF) {
0454: if (tokens.ttype == StreamTokenizer.TT_WORD) {
0455: dataItem = tokens.sval;
0456: if (dataItem.equals("[Prototype]")) {
0457: tokens.nextToken();
0458: className = tokens.sval;
0459: newVal = tokens.nextToken();
0460: } else if (dataItem.equals("[UniqueId]")) {
0461: tokens.nextToken();
0462: // Dont use unique-id as domain name anymore, just skip it
0463: //utc = tokens.sval;
0464: newVal = tokens.nextToken();
0465: } else if (dataItem.equals("[UnitName]")) {
0466: // This field is optional
0467: tokens.nextToken();
0468: unitName = tokens.sval;
0469: newVal = tokens.nextToken();
0470: } else if (dataItem.equals("[UIC]")) {
0471: if (className != null) {
0472: tokens.nextToken();
0473: uic = tokens.sval;
0474:
0475: if (originalAgentID != null)
0476: uic = getMessageAddress().getAddress();
0477: // This is a silly fix to a dumb bug
0478: if (!uic.startsWith("UIC/")) {
0479: uic = "UIC/" + uic;
0480: }
0481:
0482: org = (Organization) getFactory()
0483: .createAsset("Organization");
0484: org.initRelationshipSchedule();
0485: org.setLocal(false);
0486:
0487: NewTypeIdentificationPG typeIdPG = (NewTypeIdentificationPG) org
0488: .getTypeIdentificationPG();
0489: typeIdPG.setTypeIdentification(UTC);
0490:
0491: NewItemIdentificationPG itemIdPG = (NewItemIdentificationPG) org
0492: .getItemIdentificationPG();
0493: itemIdPG.setItemIdentification(uic);
0494: // Use unitName if it occurred, else use agentId
0495: if (unitName != null) {
0496: itemIdPG.setNomenclature(unitName);
0497: } else {
0498: itemIdPG.setNomenclature(agentId);
0499: }
0500: itemIdPG
0501: .setAlternateItemIdentification(agentId);
0502:
0503: NewClusterPG cpg = (NewClusterPG) org
0504: .getClusterPG();
0505: cpg.setMessageAddress(MessageAddress
0506: .getMessageAddress(agentId));
0507:
0508: CommunityPGImpl communityPG = (CommunityPGImpl) getFactory()
0509: .createPropertyGroup(
0510: CommunityPGImpl.class);
0511: // add in default community
0512: ArrayList communities = new ArrayList(1);
0513: communities.add("COUGAAR");
0514: communityPG.setCommunities(communities);
0515: communityPG.setTimeSpan(DEFAULT_START_TIME,
0516: DEFAULT_END_TIME);
0517: org.setCommunityPG(communityPG);
0518:
0519: } else {
0520: System.err
0521: .println("OrgRTDataPlugin Error: [Prototype] value is null");
0522: }
0523: newVal = tokens.nextToken();
0524: } else if (dataItem.equals("[Relationship]")) {
0525: newVal = FillOrganizationVector(org, newVal,
0526: tokens, relationship);
0527: // ADDED BY TOPS
0528: } else if (dataItem.equals("[AssignmentPG]")) {
0529: newVal = setAssignmentForOrganization(org,
0530: dataItem, newVal, tokens);
0531: // END ADDED BY TOPS
0532: } else if (dataItem.substring(0, 1).equals("[")) {
0533: // We've got a property or capability
0534: newVal = setPropertyForOrganization(org,
0535: dataItem, newVal, tokens);
0536: } else {
0537: // if The token you read is not one of the valid
0538: // choices from above
0539: System.err
0540: .println("OrgRTDataPlugin Incorrect token: "
0541: + dataItem);
0542: }
0543: } else {
0544: throw new RuntimeException("Format error in \""
0545: + filename + "\".");
0546: }
0547: }
0548:
0549: // For each organization, the following code sets
0550: // CapableRoles and Relationship slots for the
0551: // AssignedPG property
0552: // It adds the property to the organization and
0553: // adds the organization to ccv2 collections
0554: NewAssignedPG assignedCap = (NewAssignedPG) getFactory()
0555: .createPropertyGroup(AssignedPGImpl.class);
0556: Collection roles = org.getOrganizationPG().getRoles();
0557: if (roles != null) {
0558: assignedCap.setRoles(new ArrayList(roles));
0559: }
0560:
0561: org.setAssignedPG(assignedCap);
0562:
0563: // set up this asset's available schedule
0564: myCalendar.set(1990, 0, 1, 0, 0, 0);
0565: Date start = myCalendar.getTime();
0566: // set the end date of the available schedule to 01/01/2010
0567: myCalendar.set(2010, 0, 1, 0, 0, 0);
0568: Date end = myCalendar.getTime();
0569: NewSchedule availsched = getFactory().newSimpleSchedule(
0570: start, end);
0571: // set the available schedule
0572: ((NewRoleSchedule) org.getRoleSchedule())
0573: .setAvailableSchedule(availsched);
0574:
0575: if (relationship.equals(GLMRelationship.SELF)) {
0576: Relationship selfRelationship = getFactory()
0577: .newRelationship(Constants.Role.SELF, org, org,
0578: ETERNITY);
0579: org.getRelationshipSchedule().add(selfRelationship);
0580: org.setLocal(true);
0581:
0582: publish(org);
0583: selfOrg = org;
0584: }
0585:
0586: // Closing BufferedReader
0587: if (input != null)
0588: input.close();
0589:
0590: //only generates a NoSuchMethodException for AssetSkeleton because of a coding error
0591: //if we are successul in creating it here it then the AssetSkeletomn will end up with two copies
0592: //the add/search criteria in AssetSkeleton is for a Vecotr and does not gurantee only one instance of
0593: //each class. Thus the Org allocator plugin fails to recognixe the correct set of cpabilities.
0594:
0595: } catch (Exception e) {
0596: e.printStackTrace();
0597: }
0598: }
0599:
0600: private Object parseExpr(String type, String arg) {
0601: int i;
0602: if ((i = type.indexOf("<")) >= 0) {
0603: int j = type.lastIndexOf(">");
0604: String ctype = type.substring(0, i);
0605: String etype = type.substring(i + 1, j);
0606: Collection c = null;
0607: if (ctype.equals("Collection") || ctype.equals("List")) {
0608: c = new ArrayList();
0609: } else {
0610: throw new RuntimeException(
0611: "Unparsable collection type: " + type);
0612: }
0613:
0614: Vector l = org.cougaar.util.StringUtility.parseCSV(arg);
0615: for (Iterator it = l.iterator(); it.hasNext();) {
0616: c.add(parseExpr(etype, (String) it.next()));
0617: }
0618: return c;
0619: } else if ((i = type.indexOf("/")) >= 0) {
0620: String m = type.substring(0, i);
0621: String mt = type.substring(i + 1);
0622: double qty = Double.valueOf(arg).doubleValue();
0623: return createMeasureObject(m, qty, mt);
0624: } else {
0625: Class cl = findClass(type);
0626:
0627: try {
0628: if (cl.isInterface()) {
0629: // interface means try the COF
0630: return parseWithCOF(cl, arg);
0631: } else {
0632: Class ac = getArgClass(cl);
0633: Object[] args = { arg };
0634: Constructor cons = Reflect.getConstructor(ac,
0635: stringArgSpec);
0636: if (cons != null) {
0637: // found a constructor - use it
0638: return cons.newInstance(args);
0639: } else {
0640: Method fm = Reflect.getMethod(ac, "create",
0641: stringArgSpec);
0642: if (fm == null) {
0643: String n = ac.getName();
0644: // remove the package prefix
0645: n = n.substring(n.lastIndexOf('.') + 1);
0646: fm = Reflect.getMethod(ac, "create" + n,
0647: stringArgSpec);
0648: if (fm == null)
0649: fm = Reflect.getMethod(ac, "get" + n,
0650: stringArgSpec);
0651: }
0652: if (fm == null) {
0653: throw new RuntimeException(
0654: "Couldn't figure out how to construct "
0655: + type);
0656: }
0657: return fm.invoke(null, args);
0658: }
0659: }
0660: } catch (Exception e) {
0661: System.err
0662: .println("OrgRTDataPlugin: Exception constructing "
0663: + type + " from \"" + arg + "\":");
0664: e.printStackTrace();
0665: throw new RuntimeException("Construction problem " + e);
0666: }
0667: }
0668: }
0669:
0670: private static Class[] stringArgSpec = { String.class };
0671:
0672: private static Class[][] argClasses = {
0673: { Integer.TYPE, Integer.class },
0674: { Double.TYPE, Double.class },
0675: { Boolean.TYPE, Boolean.class },
0676: { Float.TYPE, Float.class }, { Long.TYPE, Long.class },
0677: { Short.TYPE, Short.class }, { Byte.TYPE, Byte.class },
0678: { Character.TYPE, Character.class } };
0679:
0680: private static Class getArgClass(Class c) {
0681: if (!c.isPrimitive())
0682: return c;
0683: for (int i = 0; i < argClasses.length; i++) {
0684: if (c == argClasses[i][0])
0685: return argClasses[i][1];
0686: }
0687: throw new IllegalArgumentException("Class " + c
0688: + " is an unknown primitive.");
0689: }
0690:
0691: private String getType(String type) {
0692: int i;
0693: if ((i = type.indexOf("<")) > -1) { // deal with collections
0694: int j = type.lastIndexOf(">");
0695: return getType(type.substring(0, i)); // deal with measures
0696: } else if ((i = type.indexOf("/")) > -1) {
0697: return getType(type.substring(0, i));
0698: } else {
0699: return type;
0700: }
0701: }
0702:
0703: protected Object parseWithCOF(Class cl, String val) {
0704: String name = cl.getName();
0705: int dot = name.lastIndexOf('.');
0706: if (dot != -1)
0707: name = name.substring(dot + 1);
0708:
0709: try {
0710: // lookup method on ldmf
0711: Object o = callFactoryMethod(name);
0712:
0713: Vector svs = org.cougaar.util.StringUtility.parseCSV(val);
0714: // svs should be a set of strings like "slot=value" or "slot=type value"
0715: for (Enumeration sp = svs.elements(); sp.hasMoreElements();) {
0716: String ss = (String) sp.nextElement();
0717:
0718: int eq = ss.indexOf('=');
0719: String slotname = ss.substring(0, eq);
0720: String vspec = ss.substring(eq + 1);
0721:
0722: int spi = vspec.indexOf(' ');
0723: Object v;
0724: if (spi == -1) {
0725: v = vspec;
0726: } else {
0727: String st = vspec.substring(0, spi);
0728: String sv = vspec.substring(spi + 1);
0729: v = parseExpr(st, sv);
0730: }
0731: callSetMethod(o, slotname, v);
0732: }
0733: return o;
0734: } catch (Exception e) {
0735: e.printStackTrace();
0736: return null;
0737: }
0738: }
0739:
0740: private Object callFactoryMethod(String ifcname) {
0741: // look up a zero-arg factory method in the ldmf
0742: String newname = "new" + ifcname;
0743:
0744: // try the COUGAAR factory
0745: try {
0746: Class ldmfc = aldmf.getClass();
0747: Method fm = ldmfc.getMethod(newname, nullClassList);
0748: return fm.invoke(aldmf, nullArgList);
0749: } catch (Exception e) {
0750: e.printStackTrace();
0751: }
0752:
0753: // try the main factory
0754: try {
0755: Class ldmfc = getFactory().getClass();
0756: Method fm = ldmfc.getMethod(newname, nullClassList);
0757: return fm.invoke(getFactory(), nullArgList);
0758: } catch (Exception e) {
0759: }
0760: throw new RuntimeException(
0761: "Couldn't find a factory method for " + ifcname);
0762: }
0763:
0764: private static final Class nullClassList[] = {};
0765: private static final Object nullArgList[] = {};
0766:
0767: private void callSetMethod(Object o, String slotname, Object value) {
0768: Class oc = o.getClass();
0769: String setname = "set" + slotname;
0770: Class vc = value.getClass();
0771:
0772: try {
0773: Method ms[] = Reflect.getMethods(oc);
0774: for (int i = 0; i < ms.length; i++) {
0775: Method m = ms[i];
0776: if (setname.equals(m.getName())) {
0777: Class mps[] = m.getParameterTypes();
0778: if (mps.length == 1 && mps[0].isAssignableFrom(vc)) {
0779: Object args[] = { value };
0780: m.invoke(o, args);
0781: return;
0782: }
0783: }
0784: }
0785: } catch (Exception e) {
0786: throw new RuntimeException("Couldn't find set" + slotname
0787: + " for " + o + ", value " + value);
0788: }
0789:
0790: throw new RuntimeException("Couldn't find set" + slotname
0791: + " for " + o + ", value " + value);
0792: }
0793:
0794: /**
0795: * Creates the property, fills in the slots based on what's in the prototype-ini file
0796: * and then sets it for (or adds it to) the organization
0797: */
0798: protected int setPropertyForOrganization(Organization org,
0799: String prop, int newVal, StreamTokenizer tokens) {
0800: String propertyName = prop.substring(1, prop.length() - 1);
0801: if (org != null) {
0802: NewPropertyGroup property = null;
0803: try {
0804: property = (NewPropertyGroup) getFactory()
0805: .createPropertyGroup(propertyName);
0806: } catch (Exception e) {
0807: System.err
0808: .println("OrgRTDataPlugin: Unrecognized keyword for a prototype-ini file: ["
0809: + propertyName + "]");
0810: }
0811: try {
0812: newVal = tokens.nextToken();
0813: String member = tokens.sval;
0814: String propName = "New" + propertyName;
0815: // Parse through the property section of the file
0816: while (newVal != StreamTokenizer.TT_EOF) {
0817: if ((tokens.ttype == StreamTokenizer.TT_WORD)
0818: && !(tokens.sval.substring(0, 1)
0819: .equals("["))) {
0820: newVal = tokens.nextToken();
0821: String dataType = tokens.sval;
0822: newVal = tokens.nextToken();
0823: // Call appropriate setters for the slots of the property
0824: Object arg = parseExpr(dataType, tokens.sval);
0825:
0826: createAndCallSetter(property, propName, "set"
0827: + member, getType(dataType), arg);
0828: newVal = tokens.nextToken();
0829: member = tokens.sval;
0830: } else {
0831: // Reached a left bracket "[", want to exit block
0832: break;
0833: }
0834: } //while
0835:
0836: // Add the property to the organization
0837: try {
0838: // if a setter already exists for the property (such as setTypeIdentificationPG)
0839: // then use it
0840: Class propertyClass = Organization.class;
0841: Class parameters[] = new Class[] { PropertyGroup.class };
0842: Method meth = propertyClass.getMethod("set"
0843: + propertyName, parameters);
0844: Object arguments[] = new Object[] { property };
0845: meth.invoke(org, arguments);
0846: } catch (NoSuchMethodException nsme) {
0847: // else call addOtherPropertyGroup
0848: org.addOtherPropertyGroup(property);
0849: } catch (Exception e) {
0850: e.printStackTrace();
0851: }
0852: } catch (Exception e) {
0853: e.printStackTrace();
0854: }
0855: } else {
0856: System.err.println("OrgRTDataPlugin Error: org is null");
0857: }
0858: return newVal;
0859: }
0860:
0861: /**
0862: * Fills in the organization_vector with arrays of relationship, agentName and capableroles triples.
0863: */
0864: protected int FillOrganizationVector(Organization org, int newVal,
0865: StreamTokenizer tokens, String relationship) {
0866: organization_vector.removeAllElements(); // Clear out the organization_vector
0867:
0868: int x = 0;
0869: if (org != null) {
0870: try {
0871: while (newVal != StreamTokenizer.TT_EOF) {
0872: String organization_array[] = new String[3]; // An array of relationship, agentName and capableroles triples
0873: newVal = tokens.nextToken();
0874: // Parse [Relationship] part of prototype-ini file
0875: if ((tokens.ttype == StreamTokenizer.TT_WORD)
0876: && !(tokens.sval.substring(0, 1)
0877: .equals("["))) {
0878: organization_array[0] = tokens.sval;
0879: newVal = tokens.nextToken();
0880: organization_array[1] = tokens.sval;
0881: newVal = tokens.nextToken();
0882: organization_array[2] = tokens.sval;
0883: // Only add to the organization_vector if
0884: // the relationship is SELF
0885: if (relationship.equals(GLMRelationship.SELF))
0886: organization_vector
0887: .addElement(organization_array);
0888: } else {
0889: // Reached a left bracket "[", want to exit block
0890: break;
0891: }
0892: x++;
0893: } //while
0894: } catch (Exception e) {
0895: e.printStackTrace();
0896: }
0897: } else {
0898: System.err.println("OrgRTDataPlugin Error: org is null");
0899: }
0900:
0901: return newVal;
0902: }
0903:
0904: /**
0905: * Returns the integer value for the appropriate
0906: * unitOfMeasure field in the measureClass
0907: */
0908: protected int getMeasureUnit(String measureClass,
0909: String unitOfMeasure) {
0910: try {
0911: String fullClassName = "org.cougaar.planning.ldm.measure."
0912: + measureClass;
0913: Field f = Class.forName(fullClassName).getField(
0914: unitOfMeasure);
0915: return f.getInt(null);
0916: } catch (Exception e) {
0917: System.err
0918: .println("OrgRTDataPlugin Exception: for measure unit: "
0919: + unitOfMeasure);
0920: e.printStackTrace();
0921: }
0922: return -1;
0923: }
0924:
0925: /**
0926: * Returns a measure object which is an instance of className and has
0927: * a quantity of unitOfMeasure
0928: */
0929: protected Object createMeasureObject(String className,
0930: double quantity, String unitOfMeasure) {
0931: try {
0932: Class classObj = Class
0933: .forName("org.cougaar.planning.ldm.measure."
0934: + className);
0935: String methodName = "new" + className;
0936: Class parameters[] = { double.class, int.class };
0937: Method meth = classObj.getMethod(methodName, parameters);
0938: Object arguments[] = {
0939: new Double(quantity),
0940: new Integer(
0941: getMeasureUnit(className, unitOfMeasure)) };
0942: return meth.invoke(classObj, arguments); // static method call
0943: } catch (Exception e) {
0944: e.printStackTrace();
0945: }
0946: return null;
0947: }
0948:
0949: private static HashMap classes;
0950: protected static final Collection packages;
0951:
0952: static {
0953: // initialize packages:
0954: packages = new ArrayList();
0955: packages.add("org.cougaar.glm.ldm.asset");
0956: packages.add("org.cougaar.glm.ldm.plan");
0957: packages.add("org.cougaar.glm.ldm.oplan");
0958: packages.add("org.cougaar.glm.ldm.policy");
0959:
0960: packages.add("org.cougaar.planning.ldm.measure");
0961: packages.add("org.cougaar.planning.ldm.plan");
0962: packages.add("org.cougaar.planning.ldm.asset");
0963: packages.add("org.cougaar.planning.ldm.oplan");
0964:
0965: packages.add("java.lang"); // extras for fallthrough
0966: packages.add("java.util");
0967:
0968: // initialize the classmap with some common ones
0969: classes = new HashMap();
0970:
0971: classes.put("MessageAddress", MessageAddress.class);
0972:
0973: // precache some builtins
0974: classes.put("long", Long.TYPE);
0975: classes.put("int", Integer.TYPE);
0976: classes.put("integer", Integer.TYPE);
0977: classes.put("boolean", Boolean.TYPE);
0978: classes.put("float", Float.TYPE);
0979: classes.put("double", Double.TYPE);
0980: // and some java.lang
0981: classes.put("Double", Double.class);
0982: classes.put("String", String.class);
0983: classes.put("Integer", Integer.class);
0984: // and some java.util
0985: classes.put("Collection", Collection.class);
0986: classes.put("List", List.class);
0987: // COUGAAR-specific stuff will be looked for
0988: }
0989:
0990: private Class findClass(String name) {
0991: synchronized (classes) {
0992: Class c = (Class) classes.get(name);
0993: // try the cache
0994: if (c != null)
0995: return c;
0996:
0997: for (Iterator i = packages.iterator(); i.hasNext();) {
0998: String pkg = (String) i.next();
0999: try { // Oh so ugly!
1000: c = Class.forName(pkg + "." + name);
1001: if (c != null) { // silly
1002: classes.put(name, c);
1003: return c;
1004: }
1005: } catch (ClassNotFoundException e) {
1006: }
1007: ; // sigh
1008: }
1009: throw new RuntimeException("Could not find a class for '"
1010: + name + "'.");
1011: }
1012: }
1013:
1014: /**
1015: * Creates and calls the appropriate "setter" method for the classInstance
1016: * which is of type className.
1017: */
1018: protected void createAndCallSetter(Object classInstance,
1019: String className, String setterName, String type,
1020: Object value) {
1021: Class parameters[] = new Class[1];
1022: Object arguments[] = new Object[] { value };
1023:
1024: try {
1025: parameters[0] = findClass(type);
1026: Class propertyClass = findClass(className);
1027: //Method meth = propertyClass.getMethod(setterName, parameters);
1028: Method meth = findMethod(propertyClass, setterName,
1029: parameters);
1030: meth.invoke(classInstance, arguments);
1031: } catch (Exception e) {
1032: System.err
1033: .println("OrgRTPlugin Exception: createAndCallSetter("
1034: + classInstance.getClass().getName()
1035: + ", "
1036: + className
1037: + ", "
1038: + setterName
1039: + ", "
1040: + type + ", " + value + " : " + e);
1041: e.printStackTrace();
1042: }
1043: }
1044:
1045: private static Method findMethod(Class c, String name,
1046: Class params[]) {
1047: Method ms[] = Reflect.getMethods(c);
1048: int pl = params.length;
1049: for (int i = 0; i < ms.length; i++) {
1050: Method m = ms[i];
1051: if (name.equals(m.getName())) {
1052: Class mps[] = m.getParameterTypes();
1053: if (mps.length == pl) {
1054: int j;
1055: for (j = 0; j < pl; j++) {
1056: if (!(mps[j].isAssignableFrom(params[j])))
1057: break; // j loop
1058: }
1059: if (j == pl) // all passed
1060: return m;
1061: }
1062: }
1063: }
1064: return null;
1065: }
1066:
1067: /**
1068: * This is not very straight forward due to the way classes were set up
1069: * The goal is to add a GeolocLocation to an Organization
1070: * 1) Organizations have an AssignmentPG
1071: * 2) AssignmentPG contains a Facility object, which is the super
1072: * class of the TransportationNode object
1073: * 3) TransportationNode objects have a PositionPG
1074: * 4) PositionPG contains a Position object, which is the super
1075: * class of the GeolocLocation object
1076: */
1077:
1078: /**
1079: * Creates the Position, fills in the slots based on what's in the prototype-ini file
1080: * and then sets it for (or adds it to) the organization
1081: */
1082: protected int setAssignmentForOrganization(Organization org,
1083: String prop, int newVal, StreamTokenizer tokens) {
1084: if (org != null) {
1085: NewGeolocLocation geoloc = aldmf.newGeolocLocation();
1086: String geolocClassName = "NewGeolocLocation";
1087:
1088: try {
1089: newVal = tokens.nextToken();
1090: String member = tokens.sval;
1091: // Parse through the property section of the file
1092: while (newVal != StreamTokenizer.TT_EOF) {
1093: if ((tokens.ttype == StreamTokenizer.TT_WORD)
1094: && !(tokens.sval.substring(0, 1)
1095: .equals("["))) {
1096: newVal = tokens.nextToken();
1097: String dataType = tokens.sval;
1098:
1099: newVal = tokens.nextToken();
1100: // Call appropriate setters for the slots of the property
1101: if (dataType.equals("String")) {
1102: createAndCallSetter(geoloc,
1103: geolocClassName, "set" + member,
1104: dataType, tokens.sval);
1105: } else {
1106: try {
1107: // If it's a measure class, create the appropriate measure object,
1108: // and call setter with that as one of the parameters
1109: Class
1110: .forName("org.cougaar.planning.ldm.measure."
1111: + dataType);
1112: double qty = ((tokens.ttype == StreamTokenizer.TT_NUMBER) ? tokens.nval
1113: : Double
1114: .parseDouble(tokens.sval));
1115: newVal = tokens.nextToken();
1116: Object o = createMeasureObject(
1117: dataType, qty, tokens.sval);
1118: createAndCallSetter(geoloc,
1119: geolocClassName,
1120: "set" + member, dataType, o);
1121: } catch (Exception e) {
1122: // else it is not a datatype we handle
1123: System.err
1124: .println("OrgRTDataPlugin: Incorrect datatype: "
1125: + dataType);
1126: e.printStackTrace();
1127: }
1128: }
1129: newVal = tokens.nextToken();
1130: member = tokens.sval;
1131: } else {
1132: // Reached a left bracket "[", want to exit block
1133: break;
1134: }
1135: } //while
1136:
1137: // Add the property to the organization
1138: NewAssignmentPG assignProp = (NewAssignmentPG) org
1139: .getAssignmentPG();
1140: TransportationNode tn = (TransportationNode) assignProp
1141: .getHomeStation();
1142: if (tn == null) { // There are no NewFacility or NewTransportationNode objects
1143: tn = (TransportationNode) getFactory().createAsset(
1144: TransportationNode.class);
1145: }
1146: NewPositionPG posProp = (NewPositionPG) getFactory()
1147: .createPropertyGroup(PositionPGImpl.class);
1148: posProp.setPosition((NewPosition) geoloc);
1149: tn.setPositionPG(posProp);
1150: assignProp.setHomeStation((Facility) tn);
1151: org.setAssignmentPG(assignProp);
1152:
1153: // set up the home location element of the locationpg
1154: {
1155: // get the pg
1156: LocationSchedulePG lspg = org
1157: .getLocationSchedulePG();
1158: if (lspg == null) {
1159: org
1160: .setLocationSchedulePG(lspg = new LocationSchedulePGImpl());
1161: }
1162:
1163: // get the schedule
1164: Schedule ls = lspg.getSchedule();
1165: if (ls == null) {
1166: ls = theLDMF
1167: .newLocationSchedule(EmptyEnumeration
1168: .getEnumeration());
1169: ((NewLocationSchedulePG) lspg).setSchedule(ls);
1170: }
1171:
1172: // now that we have it, lock it so nobody bashes it
1173: synchronized (ls) {
1174: /*
1175: ls.add(new LocationScheduleElementImpl(TimeSpan.MIN_VALUE,
1176: TimeSpan.MAX_VALUE,
1177: geoloc));
1178: */
1179: ls.add(new HomeLocationScheduleElement(geoloc));
1180: }
1181: }
1182: } catch (Exception e) {
1183: e.printStackTrace();
1184: }
1185: } else {
1186: System.err.println("OrgRTDataPlugin Error: org is null");
1187: }
1188: return newVal;
1189: }
1190:
1191: private static final MessageAddress originalAgentID = null;
1192:
1193: protected boolean didSpawn() {
1194: // old state-object code (bug 3513)
1195: return false;
1196: }
1197:
1198: public static class HomeLocationScheduleElement extends
1199: TaggedLocationScheduleElement {
1200: public HomeLocationScheduleElement(Location l) {
1201: super (TimeSpan.MIN_VALUE, TimeSpan.MAX_VALUE, l);
1202: }
1203:
1204: /** @return the string "HOME" to indicate that this is the home location
1205: * of the organization.
1206: **/
1207: public Object getOwner() {
1208: return "HOME";
1209: }
1210:
1211: }
1212:
1213: private static class TrivialTimeSpan implements TimeSpan {
1214: long myStart;
1215: long myEnd;
1216:
1217: public TrivialTimeSpan(long start, long end) {
1218: myStart = start;
1219: myEnd = end;
1220: }
1221:
1222: public long getStartTime() {
1223: return myStart;
1224: }
1225:
1226: public long getEndTime() {
1227: return myEnd;
1228: }
1229: }
1230:
1231: }
|