001: /*
002: * This file or a portion of this file is licensed under the terms of
003: * the Globus Toolkit Public License, found in file GTPL, or at
004: * http://www.globus.org/toolkit/download/license.html. This notice must
005: * appear in redistributions of this file, with or without modification.
006: *
007: * Redistributions of this Software, with or without modification, must
008: * reproduce the GTPL in: (1) the Software, or (2) the Documentation or
009: * some other similar material which is provided with the Software (if
010: * any).
011: *
012: * Copyright 1999-2004 University of Chicago and The University of
013: * Southern California. All rights reserved.
014: */
015:
016: package org.griphyn.cPlanner.parser.dax;
017:
018: import org.griphyn.cPlanner.classes.SubInfo;
019:
020: import org.griphyn.cPlanner.partitioner.graph.GraphNode;
021:
022: import org.griphyn.cPlanner.common.PegasusProperties;
023: import org.griphyn.cPlanner.common.LogManager;
024:
025: import java.util.ArrayList;
026: import java.util.Iterator;
027: import java.util.LinkedList;
028: import java.util.List;
029: import java.util.Map;
030:
031: /**
032: * This callback implementation ends up building a detailed structure of the
033: * graph referred to by the abstract plan in dax, that should make the graph
034: * traversals easier. Later on this graph representation would be used
035: * uniformly in the Pegasus code base.
036: *
037: * @author Karan Vahi
038: * @version $Revision: 222 $
039: */
040:
041: public class DAX2Graph implements Callback {
042:
043: /**
044: * The id of the dummy root node added on the top of the graph. Makes
045: * easier the starting of the traversal.
046: */
047: public static final String DUMMY_NODE_ID = "dummy";
048:
049: /**
050: * The map containing the a graph node for each of the jobs referred to in
051: * the dax. The key is the logical id of the job.
052: */
053: protected Map mAbstractGraph;
054:
055: /**
056: * A flag to specify whether the graph has been generated for the partition
057: * or not.
058: */
059: protected boolean mDone;
060:
061: /**
062: * The label of the abstract dax as set by Chimera.
063: */
064: protected String mLabel;
065:
066: /**
067: * The root node for the graph that is constructed.
068: */
069: protected GraphNode mRoot;
070:
071: /**
072: * The handle to the properties object.
073: */
074: protected PegasusProperties mProps;
075:
076: /**
077: * The logging object.
078: */
079: protected LogManager mLogger;
080:
081: /**
082: * The overloaded constructor.
083: *
084: * @param properties the properties passed to the planner.
085: * @param dax the path to the DAX file.
086: */
087: public DAX2Graph(PegasusProperties properties, String dax) {
088: mProps = properties;
089: mAbstractGraph = new java.util.HashMap();
090: mLogger = LogManager.getInstance();
091: mDone = false;
092: mLabel = null;
093: mRoot = null;
094: }
095:
096: /**
097: * Returns a Map indexed by the logical ID of the jobs, and each value being
098: * a GraphNode object.
099: *
100: * @return ADag object containing the abstract plan referred in the dax.
101: */
102: public Object getConstructedObject() {
103: if (!mDone)
104: throw new RuntimeException(
105: "Method called before the abstract dag "
106: + " for the partition was fully generated");
107:
108: return mAbstractGraph;
109: }
110:
111: /**
112: * Callback when the opening tag was parsed. This contains all
113: * attributes and their raw values within a map. It ends up storing
114: * the attributes with the adag element in the internal memory structure.
115: *
116: * @param attributes is a map of attribute key to attribute value
117: */
118: public void cbDocument(Map attributes) {
119: /**@todo Implement this org.griphyn.cPlanner.parser.Callback method*/
120: if (attributes == null
121: || (mLabel = (String) attributes.get("name")) == null) {
122: mLabel = "test";
123: }
124: }
125:
126: /**
127: * This constructs a graph node for the job and ends up storing it in the
128: * internal map.
129: *
130: * @param job the job that was parsed.
131: */
132: public void cbJob(SubInfo job) {
133: GraphNode gn = new GraphNode(job.getLogicalID(), job
134: .getTXName());
135: mLogger.log("Adding job to graph " + job.getName(),
136: LogManager.DEBUG_MESSAGE_LEVEL);
137: put(job.logicalId, gn);
138: }
139:
140: /**
141: * This updates the internal graph nodes of child with references to it's
142: * parents referred to by the list of parents passed. It gets the handle
143: * to the parents graph nodes from it's internal map.
144: *
145: * @param child the logical id of the child node.
146: * @param parents list containing the logical id's of the parents of the
147: * child nodes.
148: */
149: public void cbParents(String child, List parents) {
150: GraphNode childNode = (GraphNode) get(child);
151: Iterator it = parents.iterator();
152: String parentId;
153: ArrayList parentList = new ArrayList(parents.size());
154:
155: mLogger.log("Adding parents for child " + child,
156: LogManager.DEBUG_MESSAGE_LEVEL);
157: //construct the references to the parent nodes
158: while (it.hasNext()) {
159: parentId = (String) it.next();
160: GraphNode parentNode = (GraphNode) get(parentId);
161: parentList.add(parentNode);
162:
163: //add the child to the parent's child list
164: parentNode.addChild(childNode);
165: }
166: childNode.setParents(parentList);
167: }
168:
169: /**
170: * Returns the name of the dax.
171: *
172: * @return name of dax
173: */
174: public String getNameOfDAX() {
175: return mLabel;
176: }
177:
178: /**
179: * Callback to signal that traversal of the DAX is complete. At this point a
180: * dummy root node is added to the graph, that is the parents to all the root
181: * nodes in the existing DAX.
182: */
183: public void cbDone() {
184: //the abstract graph is fully generated
185: mDone = true;
186:
187: //just print out the graph that is generated internally.
188: //find the root nodes from where to start the breadth first
189: //search
190: Iterator it = mAbstractGraph.entrySet().iterator();
191: List rootNodes = new LinkedList();
192:
193: while (it.hasNext()) {
194: GraphNode gn = (GraphNode) ((java.util.Map.Entry) it.next())
195: .getValue();
196: if (gn.getParents() == null || gn.getParents().isEmpty()) {
197: rootNodes.add(gn);
198: }
199: //System.out.println(gn);
200: }
201:
202: //add a dummy node that is a root to all these nodes.
203: String rootId = this .DUMMY_NODE_ID;
204: mRoot = new GraphNode(rootId, rootId);
205: mRoot.setChildren(rootNodes);
206: put(rootId, mRoot);
207: //System.out.println(dummyNode);
208:
209: }
210:
211: /**
212: * It puts the key and the value in the internal map.
213: *
214: * @param key the key to the entry in the map.
215: * @param value the entry in the map.
216: */
217: protected void put(Object key, Object value) {
218: mAbstractGraph.put(key, value);
219: }
220:
221: /**
222: * It returns the value associated with the key in the map.
223: *
224: * @param key the key to the entry in the map.
225: *
226: * @return the object
227: */
228: public Object get(Object key) {
229: return mAbstractGraph.get(key);
230: }
231:
232: }
|