001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: /*
028: * File: DMPIClusterStartup.java
029: * Heavily modified from original to be an LDMPlugin
030: */
031:
032: package org.cougaar.mlm.plugin;
033:
034: /*
035: * Imports
036: */
037:
038: import java.io.BufferedReader;
039: import java.io.IOException;
040: import java.io.InputStreamReader;
041: import java.util.Enumeration;
042: import java.util.Vector;
043:
044: import org.cougaar.planning.ldm.LDMPluginServesLDM;
045: import org.cougaar.planning.ldm.LDMServesPlugin;
046: import org.cougaar.planning.ldm.PlanningFactory;
047: import org.cougaar.planning.ldm.asset.Asset;
048: import org.cougaar.planning.plugin.legacy.SimplePlugin;
049: import org.cougaar.util.ConfigFinder;
050:
051: /**
052: * This Data Management Plugin class reads a .ini file and creates a Cluster'
053: * startup data. For the moment the Plugin only instantiates the LDM
054: * classes of interest to this Cluster.
055: * <p>
056: **/
057:
058: public final class DMPIClusterStartup extends SimplePlugin implements
059: LDMPluginServesLDM {
060:
061: private LDMServesPlugin ldm = null;
062: private PlanningFactory ldmf = null;
063:
064: /** The file name for the assets **/
065: private String theFileName;
066: /** The UIC code to parse for **/
067: private String theKey = null;
068:
069: /**
070: * The public constructor wiht no args to set the default values.
071: **/
072: public DMPIClusterStartup() {
073: this ("ClusterAsset.ini");
074: }
075:
076: /**
077: * The public constructor that enables the user to set the sepecific file to use in startup.
078: **/
079: public DMPIClusterStartup(String fileName) {
080: theFileName = fileName;
081: }
082:
083: /**
084: * Method to construct an Assetand add it to the internal BagOfAsset object.
085: * <p><PRE>
086: * PRE CONDITION: The parseDataFile has located the key int he underlying file.
087: * POST CONDITION: begin copying the data into a new vector.
088: * INVARIANCE: The start point of the parsing is the next line in the BufferedReader in.
089: * </PRE>
090: * @param aSpec The string object with the format (Type, NSN, qty, VIN).
091: * @exception NumberFormatException If the qunatitiy can not be converted to a number.
092: * @exception DMPluginException If unable to create the requested Asset.
093: * @exception PlanningFactoryExceptionm I fPlanningFactory throws exception during creation.
094: **/
095: private Asset buildAsset(String aSpec) throws NumberFormatException {
096: Asset myAsset = null;
097: String myClassName = null;
098: String myNSN = null;
099: try {
100: //First we break the string down into the three specific data types.
101:
102: //locate the break points
103: char listDelim = ',';
104: int delim1 = aSpec.indexOf(listDelim);
105: int delim2 = aSpec.indexOf(listDelim, delim1 + 1);
106: int delim3 = aSpec.indexOf(listDelim, delim2 + 1);
107:
108: //now convert then into the three string values
109: myClassName = aSpec.substring(0, delim1).trim();
110: myNSN = aSpec.substring(delim1 + 1, delim2).trim();
111: String myQuantity = null;
112: String myId = null;
113: if (delim3 == -1)
114: myQuantity = aSpec.substring(delim2 + 2).trim();
115: else {
116: myQuantity = aSpec.substring(delim2 + 1, delim3).trim();
117: myId = aSpec.substring(delim3 + 1).trim();
118: }
119:
120: //convert the data types into something more useful
121: int myCount = 0;
122: if (myQuantity != null)
123: myCount = new Integer(myQuantity).intValue();
124:
125: //now we have the data so lets go shopping
126: if (myCount > 0) {
127: Asset myObject = null;
128: // If there's no identifier, this must be an aggregate, i.e., the count must be >= 1
129: if (myId == null) {
130: myObject = ldmf.createAggregate(myClassName,
131: myCount);
132: } else
133: myObject = ldmf.createInstance(myClassName, myId);
134:
135: myAsset = myObject;
136: }
137: } catch (Exception e) {
138: String message = "DMPIClusterStartup.buildAssets(): Caught exception "
139: + e + " while building " + aSpec + ".";
140: System.err.println(message + "\n");
141: e.printStackTrace();
142: }
143:
144: return myAsset;
145: }
146:
147: /**
148: * Method to iterate over the Vector argunmet entries and build the asset.
149: * <p><PRE>
150: * PRE CONDITION: The Vector contains all the data related to this key found in the data source.
151: * POST CONDITION: A new asset is constructed for each of the required Asset objects
152: * INVARIANCE:
153: * </PRE>
154: * @param myParsedData The Vector of strings pulled out of the underlying data source.
155: **/
156: private void createObjects(Vector myParsedData) {
157: int i = 0;
158: for (Enumeration e = myParsedData.elements(); e
159: .hasMoreElements();) {
160: String element = (String) e.nextElement();
161: try {
162: Asset asset = buildAsset(element);
163: if (asset != null) {
164: publishAdd(asset);
165: }
166: } catch (Exception ex) {
167: System.out
168: .println("DMPIClusterStartup.createObjects failed to construct an asset ("
169: + element + ")! " + ex);
170: }
171: i++;
172: }
173: //System.err.println("//DMPIClusterStartup built "+i+" Assets");
174: }
175:
176: /**
177: * Accessor for theFileName.
178: * <p>
179: * @return String The object currently referenced by theFileName variable
180: **/
181: public String getFileName() {
182: return theFileName;
183: }
184:
185: /**
186: * Accessor for theKey.
187: * <p>
188: * @return String The object currently referenced by theKey variable
189: **/
190: private String getKey() {
191: return theKey;
192: }
193:
194: /**
195: * Method to parse the values out of the INI file and construct the node profile.
196: * <p>
197: * This is a temporary method that enables the data to be stored in a simple text file until
198: * we construct the contemporary data source link for construction of cluster assets.
199: * <p><PRE>
200: * PRE CONDITION: The parseDataFile has located the key int he underlying file.
201: * POST CONDITION: begin copying the data into a new vector.
202: * INVARIANCE: The start point of the parsing is the next line in the BufferedReader in.
203: * </PRE>
204: * @param in BufferedReader object that contains the current stream of file data.
205: * @return Vector Object with the Parsed strings in it.
206: **/
207: private Vector parseData(BufferedReader in) {
208: Vector myParsedData = new Vector();
209:
210: try {
211: char openSquare = '[';
212: char equals = '=';
213:
214: while (in.ready()) {
215: String sCheck = in.readLine();
216: int nIndex = sCheck.indexOf(equals);
217: if (nIndex != -1 && nIndex < sCheck.length())
218: myParsedData.addElement(sCheck
219: .substring(nIndex + 1).trim());
220:
221: int closeIn = sCheck.indexOf(openSquare);
222: if (closeIn != -1 && closeIn < sCheck.length())
223: break;
224: }
225: in.close();
226: } catch (IOException e) {
227: System.out.println("Error: " + e);
228: e.printStackTrace();
229: }
230:
231: return myParsedData;
232: }
233:
234: /**
235: * Method to locate the key value in the underlying data source. currently the source is a file but
236: * the future may change this to some other data source and this method provides the hook for changing
237: * the source and only having to rewrite one method. The rest of the class will function properly if
238: * this mehtod comnverts the data source into a BufferedReader stream.
239: * <p>
240: * This is a temporary method that enables the data to be stored in a simple text file until
241: * we construct the contemporary data source link for construction of cluster assets.
242: * <p><PRE>
243: * PRE CONDITION: Runnable target is created and has not been run.
244: * POST CONDITION: Object creates all Assets and notifuies the Componet of each one. Object blocks.
245: * INVARIANCE:
246: * </PRE>
247: * @return Vector The vector object that contains the parsed data.
248: * @exception DMPluginException If the key is not located in the file.
249: **/
250: private Vector parseDataFile() {
251: Vector myParsedData = null;
252: try {
253: BufferedReader in = new BufferedReader(
254: new InputStreamReader(ConfigFinder.getInstance()
255: .open(getFileName())));
256: while (in.ready()) {
257: String sCheck = in.readLine();
258: int locateUic = sCheck.indexOf(getKey());
259: if (locateUic != -1 && locateUic < sCheck.length()) {
260: myParsedData = parseData(in);
261: break;
262: }
263: }
264: in.close();
265: } catch (IOException e) {
266: System.out.println("Error: " + e);
267: e.printStackTrace();
268: }
269:
270: if (myParsedData == null) {
271: System.err
272: .println("DMPIClusterStartup: in parseDataFile could not find section for [Cluster "
273: + getKey() + "]");
274: }
275:
276: return myParsedData;
277:
278: }
279:
280: /**
281: * Load the data from the file synchronously.
282: * We'll not actually do anything later on.
283: **/
284: protected void setupSubscriptions() {
285: ldm = (LDMServesPlugin) getLDM();
286: ldmf = ldm.getFactory();
287: theKey = getMessageAddress().getAddress();
288:
289: if (!didRehydrate()) { // Objects are already created after rehydration
290: //first parse the data from the underlying file
291: Vector myParsedData = parseDataFile();
292: if (myParsedData != null) {
293: //now create all the required objects from the parsed data
294: createObjects(myParsedData);
295: }
296: }
297: }
298:
299: protected void execute() {
300: }
301: }
|