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: package org.cougaar.lib.plugin;
028:
029: import java.io.InputStream;
030: import java.util.Enumeration;
031: import java.util.List;
032: import java.util.Vector;
033:
034: import org.apache.xerces.parsers.DOMParser;
035: import org.cougaar.core.service.LoggingService;
036: import org.cougaar.lib.param.Param;
037: import org.cougaar.lib.xml.parser.AggregateAssetParser;
038: import org.cougaar.lib.xml.parser.InstanceParser;
039: import org.cougaar.lib.xml.parser.ParamParser;
040: import org.cougaar.lib.xml.parser.PrototypeParser;
041: import org.cougaar.planning.ldm.LDMPluginServesLDM;
042: import org.cougaar.planning.ldm.asset.AggregateAsset;
043: import org.cougaar.planning.ldm.asset.Asset;
044: import org.cougaar.planning.plugin.legacy.SimplePlugin;
045: import org.cougaar.util.ConfigFinder;
046: import org.w3c.dom.Document;
047: import org.w3c.dom.Node;
048: import org.w3c.dom.NodeList;
049: import org.xml.sax.InputSource;
050: import org.xml.sax.SAXParseException;
051:
052: /**
053: * <pre>
054: * Reads an ldm xml file and populates the Cluster with the assets
055: * found there.
056: *
057: * By default, looks for files of the form <ClusterName>.ldm.xml
058: *
059: * The xml files can be anywhere the ConfigFinder looks.
060: *
061: * For example, for TOPS, the files are in the data directory, e.g.
062: *
063: * /opt/alp/plugins/TOPS/data/TRANSCOM.ldm.xml
064: *
065: * This is not on the default ConfigFinder path, so you have to add a
066: * system parameter like this to setarguments.csh:
067: *
068: * -Dorg.cougaar.config.path=$COUGAAR_INSTALL_PATH/plugins/TOPS/data;
069: *
070: * NOTE : the trailing semi-colon is ABSOLUTELY necessary.
071: *
072: * Parameters :
073: * debug - when true, tells of each items published to log plan
074: * ldmFile - lets you specify the ldm xml file to be anything you want
075: *
076: * </pre>
077: */
078:
079: public class UTILLdmXMLPlugin extends SimplePlugin implements
080: LDMPluginServesLDM {
081: private boolean debug = "true".equals(System.getProperty(
082: "UTILLdmXMLPlugin.debug", "false"));
083: private boolean showParserFeatures = "true"
084: .equals(System.getProperty(
085: "UTILLdmXMLPlugin.showParserFeatures", "false"));
086:
087: LoggingService logger;
088:
089: // rely upon load-time introspection to set these services -
090: // don't worry about revokation.
091: public final void setLoggingService(LoggingService bs) {
092: logger = bs;
093:
094: paramParser = new ParamParser();
095: prototypeParser = new PrototypeParser(logger);
096: instanceParser = new InstanceParser(logger);
097: aggregateAssetParser = new AggregateAssetParser(logger);
098: }
099:
100: /**
101: * Get the logging service, for subclass use.
102: */
103: protected LoggingService getLoggingService() {
104: return logger;
105: }
106:
107: protected boolean didSpawn() {
108: // old state-object code (bug 3513)
109: return false;
110: }
111:
112: /**
113: * Load the data from the file synchronously.
114: * We'll not actually do anything later on.
115: *
116: * Does not create assets if being rehydrated.
117: */
118: protected void setupSubscriptions() {
119: // if we just rehydrated, all the assets created before persisting should already be
120: // in the logplan
121: // if (!didRehydrate () && !didSpawn())
122: createAssets();
123: }
124:
125: /**
126: * Do nothing function
127: */
128: protected void execute() {
129: }
130:
131: /**
132: * <pre>
133: * Parses the ldm.xml file and creates the objects
134: * that are represented in that file. The objects are then
135: * published to the cluster.
136: *
137: * If the debug parameter exists and is set to true, will tell of
138: * each object published to log plan.
139: * </pre>
140: */
141: private void createAssets() {
142: Document doc = getParsedDocument();
143:
144: Enumeration assets = getAssets(doc);
145: while (assets.hasMoreElements()) {
146: Asset asset = (Asset) assets.nextElement();
147: publishAdd(asset);
148: if (logger.isDebugEnabled())
149: logger
150: .debug("UTILLdmXMLPlugin.createAssets - Publishing "
151: + asset + " to the log plan");
152: }
153:
154: // please garbage collect!
155: paramParser = null;
156: prototypeParser = null;
157: instanceParser = null;
158: aggregateAssetParser = null;
159: }
160:
161: /**
162: * <pre>
163: * Returns a document that represents the parsed xml file returned by getFileName.
164: * Uses ConfigFileFinder to find the .ldm.xml file and any xml entity references within
165: * the file.
166: *
167: * Need to provide an entity resolver to the parser.
168: * The entity resolver is just a wrapper of the ConfigFinder.
169: *
170: * </pre>
171: * @see #getFileName
172: * @see org.cougaar.lib.plugin.UTILEntityResolver#resolveEntity
173: * @see org.cougaar.util.ConfigFinder#open
174: * @return document that we can query for assets
175: */
176: protected Document getParsedDocument() {
177: String dfile = getFileName();
178: DOMParser parser = new DOMParser();
179: InputStream inputStream = null;
180: try {
181: inputStream = ConfigFinder.getInstance().open(dfile);
182: if (logger.isDebugEnabled())
183: logger
184: .debug("UTILLdmXMLPlugin.getParsedDocument - Opened "
185: + dfile
186: + " input stream "
187: + inputStream);
188:
189: if (showParserFeatures) {
190: logger
191: .debug("UTILLdmXMLPlugin.getParsedDocument - parser features:");
192: /* // xerces2
193: String []features = parser.getFeaturesRecognized();
194: for (int i = 0; i < features.length; i++) {
195: try {
196: logger.debug ("Feature " + i + " " + features[i] + " = " + parser.getFeature(features[i]));
197: } catch (SAXNotRecognizedException saxnre) {
198: logger.debug ("Feature " + i + " " + features[i] + " = not recognized excep?");
199: }
200: }
201: */
202: }
203:
204: parser
205: .setFeature(
206: "http://apache.org/xml/features/allow-java-encodings",
207: true);
208:
209: // by default set to true, adds another node to tree that confuses getAssets below,
210: // since it's not expecting a entity ref node
211: parser
212: .setFeature(
213: "http://apache.org/xml/features/dom/create-entity-ref-nodes",
214: false);
215: /* // xerces2
216: if (logger.isDebugEnabled())
217: logger.debug ("UTILLdmXMLPlugin.getParsedDocument - setting parser create entity node to "+
218: parser.getCreateEntityReferenceNodes());
219: */
220: parser.setEntityResolver(new UTILEntityResolver(logger));
221: InputSource is = new InputSource(inputStream);
222: is.setSystemId(dfile);
223: parser.parse(is);
224: } catch (SAXParseException saxe) {
225: logger.error(
226: "UTILLdmXMLPlugin.getParsedDocument - got SAX Parse exception in file "
227: + saxe.getSystemId() + " line "
228: + saxe.getLineNumber() + " col "
229: + saxe.getColumnNumber() + "\n"
230: + "Exception was :", saxe);
231: } catch (Exception e) {
232: if (inputStream == null) {
233: logger.error(
234: "UTILLdmXMLPlugin.getParsedDocument - could not find "
235: + dfile
236: + ". Please check config path.", e);
237: }
238: } finally {
239: if (inputStream != null) {
240: try {
241: inputStream.close();
242: } catch (Exception ioe) {
243: logger.error("got exception " + ioe
244: + " closing input stream for " + dfile);
245: }
246: }
247: }
248:
249: return parser.getDocument();
250: }
251:
252: /**
253: * <pre>
254: * Looks for a file called <ClusterName>.ldm.xml OR optionally a
255: * a file with the same name as the ldmFile variable.
256: *
257: * Optionally prepends the "envDir" directory to the path, which
258: * can be used for finer control over finding of files (usually not needed).
259: *
260: * Subclass to look for a file with a different extension
261: * This file will probably be in the "data" directory.
262: * </pre>
263: */
264: protected String getFileName() {
265: String dfile = getStringParam("envDir");
266: if (dfile == null)
267: dfile = "";
268:
269: String ldmFile = getStringParam("ldmFile");
270: if (ldmFile == null)
271: ldmFile = getMessageAddress().getAddress() + ".ldm.xml";
272:
273: dfile = dfile + ldmFile;
274: return dfile;
275: }
276:
277: /**
278: * <pre>
279: * Get the value of the parameter from those that are defined in the
280: * <Cluster>.ini after each plugin.
281: *
282: * </pre>
283: * @param the name of the parameter
284: * @return the parameter named <code>name</code>, if there is one defined
285: */
286: String getStringParam(String name) {
287: Vector envParams = getParameters();
288: String paramValue = null;
289: Enumeration ps = envParams.elements();
290: while (ps.hasMoreElements() && (paramValue == null)) {
291: String envS = (String) ps.nextElement();
292: Param p = paramParser.getParam(envS);
293: if (p != null) {
294: String n = p.getName();
295: try {
296: if (n.equals(name)) {
297: paramValue = p.getStringValue();
298: }
299: } catch (Exception e) {
300: logger.error("got error getting string param", e);
301: }
302: }
303: }
304: return paramValue;
305: }
306:
307: /**
308: * Uses the PrototypeParser, InstanceParser, and AggregateAsset parser to
309: * create assets as specified in the <ClusterName>.ldm.xml file.
310: *
311: * @see org.cougaar.lib.xml.parser.PrototypeParser#cachePrototype
312: * @see org.cougaar.lib.xml.parser.InstanceParser#getInstance
313: * @see org.cougaar.lib.xml.parser.AggregateAssetParser#getAggregate
314: * @param doc - the input xml document (from an .ldm.xml file)
315: * @return an enumeration of the created assets.
316: */
317: private Enumeration getAssets(Document doc) {
318:
319: Node root = doc.getDocumentElement();
320: Vector assets = new Vector();
321:
322: if (root.getNodeName().equals("AssetList")) {
323: NodeList nlist = root.getChildNodes();
324: int nlength = nlist.getLength();
325: for (int i = 0; i < nlength; i++) {
326: Node child = nlist.item(i);
327: if (child.getNodeType() == Node.ELEMENT_NODE) {
328: String childname = child.getNodeName();
329: if (logger.isDebugEnabled())
330: logger
331: .debug("UTILLdmXMLPlugin.getAssets - childname "
332: + childname);
333:
334: if (childname.equals("prototype")) {
335: //logger.debug("Parsing Prototype");
336: prototypeParser.cachePrototype(getLDM(), child);
337: } else if (childname.equals("instance")
338: && !didRehydrate()) {
339: //logger.debug("Parsing Instance");
340: List newassets = instanceParser.getInstance(
341: getLDM(), child);
342: assets.addAll(newassets);
343: } else if (childname.equals("AggregateAsset")
344: && !didRehydrate()) {
345: // logger.debug("Parsing AggregateAsset.");
346: AggregateAsset newasset = aggregateAssetParser
347: .getAggregate(getLDM(), child);
348: assets.addElement(newasset);
349: }
350: /*
351: else if(childname.equals("network")){
352: Vector net_assets = NetworkParser.getTransportationNetwork(getLDM(),
353: getClusterObjectFactory(),
354: child);
355: for(int j = 0; j < net_assets.size(); j++){
356: assets.addElement(net_assets.elementAt(j));
357: }
358: }
359: */
360: } else {
361: // if (logger.isDebugEnabled())
362: // logger.debug ("UTILLdmXMLPlugin.getAssets - got non-element node " + child);
363: }
364: }
365: }
366: return assets.elements();
367: }
368:
369: ParamParser paramParser;
370: PrototypeParser prototypeParser;
371: InstanceParser instanceParser;
372: AggregateAssetParser aggregateAssetParser;
373: }
|