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.xml.parser;
028:
029: import java.lang.reflect.Method;
030:
031: import org.cougaar.core.domain.Factory;
032: import org.cougaar.planning.ldm.LDMServesPlugin;
033: import org.cougaar.planning.ldm.PlanningFactory;
034: import org.cougaar.util.log.Logger;
035: import org.w3c.dom.Node;
036: import org.w3c.dom.NodeList;
037:
038: /**
039: * Parses objects within prototypes or instances.
040: *
041: * Creates the objects.
042: */
043: public class ObjectParser {
044: static final String PG_STRING = "PG";
045:
046: /** creates a field parser */
047: public ObjectParser(Logger l) {
048: logger = l;
049: fieldParser = new FieldParser(l, this );
050: }
051:
052: /**
053: * <pre>
054: * Create an object based on its name defined by <tt>node</tt>.
055: *
056: * Potentially tries a number of different possibilities for
057: * object type when creating the asset/property group.
058: *
059: * Uses FieldParser to populate the fields of the object.
060: *
061: * </pre>
062: * @param node defines the object
063: * @param ldm used to create assets, property groups, etc.
064: */
065: public Object getObject(LDMServesPlugin ldm, Node node) {
066: PlanningFactory ldmFactory = ldm.getFactory();
067: Object obj = null;
068:
069: if (node.getNodeName().equals("object")) {
070: NodeList nlist = node.getChildNodes();
071: int nlength = nlist.getLength();
072:
073: String className = node.getAttributes().getNamedItem(
074: "class").getNodeValue();
075:
076: // Optimization- try to predict whether the object is a PG or an Asset
077: // based on endsWith("PG"); the other will always be tried if the
078: // first one fails, though.
079: if (className.endsWith(PG_STRING)) {
080: // first assume that it is a property or capability
081: try {
082: // logger.debug ("object - " + className + " class " + Class.forName(className));
083: obj = ldmFactory.createPropertyGroup(Class
084: .forName(className));
085: // logger.debug("** OBJECT PARSER CREATED : from create PG " + obj);
086: } catch (Exception e) {
087: if (logger.isInfoEnabled())
088: logger
089: .info("Could not make PG with name ending in PG, exception "
090: + e);
091: obj = null;
092: }
093:
094: // logger.debug ("object - " + className);
095: // now try to see if it is an asset
096: if (obj == null) {
097: try {
098: obj = ldmFactory.createAsset(Class
099: .forName(className));
100: // logger.debug("** OBJECT PARSER CREATED create Asset: " + obj);
101: } catch (Exception e) {
102: if (logger.isInfoEnabled())
103: logger
104: .info("Could not make asset with className "
105: + className);
106: obj = null;
107: }
108: }
109: } else {
110: // logger.debug ("object - " + className);
111: // First try to see if it is an asset
112:
113: // now try the measure classes & Skill
114: if (className
115: .startsWith("org.cougaar.planning.ldm.measure.")
116: || className
117: .equals("org.cougaar.glm.ldm.plan.Skill")) {
118: try {
119: obj = Class.forName(className);
120: // logger.debug("**** OBJECT PARSER CREATED : measure " + obj);
121: } catch (Exception e) {
122: if (logger.isInfoEnabled())
123: logger
124: .info("Could not make measure class from "
125: + className);
126: obj = null;
127: }
128: }
129:
130: // try ldm plan classes
131: if (obj == null
132: && (className
133: .startsWith("org.cougaar.glm.ldm.plan."))) {
134: obj = getGLMObject(ldm, className);
135: }
136:
137: if (obj == null) {
138: try {
139: Class foundClass = Class.forName(className);
140: if (!foundClass.isInterface())
141: obj = ldmFactory.createAsset(foundClass);
142: //logger.debug("** OBJECT PARSER CREATED create Asset: " + obj + ":" + ((Asset)obj).getUID());
143: } catch (Exception e) {
144: if (logger.isInfoEnabled())
145: logger.info(
146: "Could not make asset with className "
147: + className, e);
148: obj = null;
149: }
150: }
151:
152: // now assume that it is a property or capability
153: if (obj == null) {
154: try {
155: // logger.debug ("object - " + className + " class " + Class.forName(className));
156: obj = ldmFactory.createPropertyGroup(Class
157: .forName(className));
158: // logger.debug("** OBJECT PARSER CREATED : from create PG " + obj);
159: } catch (Exception e) {
160: if (logger.isInfoEnabled())
161: logger
162: .info("Could not make PG with className "
163: + className);
164: obj = null;
165: }
166: }
167: }
168:
169: // now assume that it could be built by the cluster object factory
170: // notice that the ldm factory extends the cof.
171: if (obj == null) {
172: try {
173: String method_name = getMethodName(className);
174: Method method = ldmFactory.getClass().getMethod(
175: method_name, null);
176: obj = method.invoke(ldmFactory, null);
177: // logger.debug("*** OBJECT PARSER CREATED : from factory " + obj);
178: } catch (Exception e) {
179: if (logger.isInfoEnabled())
180: logger
181: .info("Could not make object with className "
182: + className
183: + " by doing method.invoke.");
184: if (obj == null)
185: obj = getGLMObject(ldm, className);
186: }
187: }
188:
189: // now assume that it is a property or capability that failed with createPropertyGroup
190: if (obj == null) {
191: try {
192: int last = className.lastIndexOf('.');
193: String first = className.substring(last + 1,
194: last + 4);
195: if (first.equals("New"))
196: className = className.substring(0, last + 1)
197: + className.substring(last + 4,
198: className.length());
199: // logger.debug ("object - " + className);
200: obj = ldmFactory.createPropertyGroup(className);
201: // logger.debug("** OBJECT PARSER CREATED : from create PG 2 " + obj);
202: } catch (Exception e) {
203: if (logger.isInfoEnabled())
204: logger.info("Could not make PG with className "
205: + className
206: + " after failing to do createPG");
207: // logger.debug ("exception " + e);
208: obj = null;
209: }
210: }
211:
212: // now try the measure classes
213: if (obj == null) {
214: try {
215: obj = Class.forName(className);
216: // logger.debug("**** OBJECT PARSER CREATED : measure " + obj);
217: } catch (Exception e) {
218: if (logger.isInfoEnabled())
219: logger
220: .info("Could not make measure class from "
221: + className);
222: obj = null;
223: }
224: }
225:
226: if (obj == null) {
227: // BOZO: need to throw exception here.
228: // perhaps use the new operator (?)
229: logger.error("ObjectParser: Could not create: "
230: + className);
231: return null;
232: }
233:
234: for (int i = 0; i < nlength; i++) {
235: Node child = nlist.item(i);
236: String childname = child.getNodeName();
237:
238: if (child.getNodeType() == Node.ELEMENT_NODE) {
239: if (childname.equals("field")) {
240: // the setField() function returns the object that it set the
241: // field on. In most cases that will be the same as in its
242: // third argument, but in the weird measure classes case that
243: // return value is the actual measure class created.
244: obj = fieldParser.setField(ldm, child, obj);
245: }
246: }
247: }
248: }
249:
250: return obj;
251: }
252:
253: protected Object getGLMObject(LDMServesPlugin ldm, String className) {
254: Object obj = null;
255: try {
256: Factory af = ldm.getFactory("glm");
257: if (af != null) {
258: String method_name = getMethodName(className);
259: Method method = af.getClass().getMethod(method_name,
260: null);
261: obj = method.invoke(af, null);
262: }
263: //logger.debug("*** OBJECT PARSER CREATED : from GLMFactory " + obj);
264: } catch (Exception e2) {
265: if (logger.isInfoEnabled())
266: logger.info("Could not make object with className "
267: + className + " from glm factory", e2);
268: obj = null;
269: }
270: return obj;
271: }
272:
273: /**
274: * try to get a method name that could be used in the
275: * cluster object factory.
276: */
277: public String getMethodName(String name) {
278: char[] name_array = name.toCharArray();
279:
280: int marker = 0;
281:
282: for (int i = name_array.length - 1; i >= 0; i--) {
283: if (name_array[i] == '.') {
284: marker = i + 1;// point to first letter after last '.'
285: break;
286: }
287: }
288:
289: if (name_array[marker] == 'N' && name_array[marker + 1] == 'e'
290: && name_array[marker + 2] == 'w') {
291:
292: name_array[marker] = 'n';
293: } else if (marker >= 3) {
294: name_array[marker - 3] = 'n';
295: name_array[marker - 2] = 'e';
296: name_array[marker - 1] = 'w';
297: marker -= 3;
298: }
299:
300: return new String(name_array, marker, name_array.length
301: - marker);
302:
303: }
304:
305: protected Logger logger;
306: protected FieldParser fieldParser;
307: }
|