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: package org.griphyn.cPlanner.toolkit;
016:
017: import org.griphyn.cPlanner.parser.DaxParser;
018:
019: import org.griphyn.cPlanner.parser.dax.Callback;
020: import org.griphyn.cPlanner.parser.dax.DAX2Graph;
021: import org.griphyn.cPlanner.parser.dax.DAX2LabelGraph;
022: import org.griphyn.cPlanner.parser.dax.DAXCallbackFactory;
023:
024: import org.griphyn.cPlanner.partitioner.WriterCallback;
025: import org.griphyn.cPlanner.partitioner.Partitioner;
026: import org.griphyn.cPlanner.partitioner.PartitionerFactory;
027:
028: import org.griphyn.cPlanner.partitioner.graph.GraphNode;
029:
030: import org.griphyn.cPlanner.common.LogManager;
031: import org.griphyn.cPlanner.common.PegasusProperties;
032:
033: import org.griphyn.common.util.FactoryException;
034:
035: import gnu.getopt.Getopt;
036: import gnu.getopt.LongOpt;
037:
038: import java.io.File;
039: import java.util.Date;
040: import java.util.Map;
041:
042: /**
043: * The class ends up partitioning the dax into smaller daxes according to the
044: * various algorithms/criteria, to be used for deferred planning.
045: *
046: *
047: * @author Karan Vahi
048: * @version $Revision: 464 $
049: */
050:
051: public class PartitionDAX extends Executable {
052:
053: /**
054: * The name of the default partitioner that is loaded, if none is specified
055: * by the user.
056: */
057: public static final String DEFAULT_PARTITIONER_TYPE = PartitionerFactory.DEFAULT_PARTITIONING_CLASS;
058:
059: /**
060: * The path to the dax file that is to be partitioned.
061: */
062: private String mDAXFile;
063:
064: /**
065: * The directory in which the partition daxes are generated.
066: */
067: private String mDirectory;
068:
069: /**
070: * The type of the partitioner to be used. Is the same as the name of the
071: * implementing class.
072: */
073: private String mType;
074:
075: /**
076: * The object holding all the properties pertaining to Pegasus.
077: */
078: private PegasusProperties mProps;
079:
080: /**
081: * The default constructor.
082: */
083: public PartitionDAX() {
084: mProps = PegasusProperties.nonSingletonInstance();
085: mDAXFile = null;
086: mDirectory = ".";
087: mType = DEFAULT_PARTITIONER_TYPE;
088: }
089:
090: /**
091: * The main function of the class, that is invoked by the jvm. It calls
092: * the executeCommand function.
093: *
094: * @param args array of arguments.
095: */
096: public static void main(String[] args) {
097: PartitionDAX pdax = new PartitionDAX();
098: pdax.executeCommand(args);
099: }
100:
101: /**
102: * Executes the partition dax on the basis of the options given by the
103: * user.
104: *
105: * @param args the arguments array populated by the user options.
106: */
107: public void executeCommand(String[] args) {
108: int option = 0;
109: LongOpt[] longOptions = generateValidOptions();
110: Getopt g = new Getopt("PartitionDAX", args, "vhVD:d:t:",
111: longOptions, false);
112: boolean help = false;
113: boolean version = false;
114: int status = 0;
115:
116: //log the starting time
117: double starttime = new Date().getTime();
118: int level = 0;
119: while ((option = g.getopt()) != -1) {
120: //System.out.println("Option tag " + option);
121: switch (option) {
122: case 'd': //dax
123: mDAXFile = g.getOptarg();
124: break;
125:
126: case 'D': //dir
127: mDirectory = g.getOptarg();
128: break;
129:
130: case 't': //type
131: mType = g.getOptarg();
132: break;
133:
134: case 'v': //verbose
135: //set the verbose level in the logger
136: level++;
137: break;
138:
139: case 'V': //version
140: version = true;
141: break;
142:
143: case 'h': //help
144: help = true;
145: break;
146:
147: default: //same as help
148: mLogger.log("Unrecognized Option "
149: + Integer.toString(option),
150: LogManager.FATAL_MESSAGE_LEVEL);
151: printShortVersion();
152: System.exit(1);
153: break;
154:
155: }
156: }
157: if (level > 0) {
158: //set the logging level only if -v was specified
159: //else bank upon the the default logging level
160: mLogger.setLevel(level);
161: }
162:
163: if ((help && version) || help) {
164: printLongVersion();
165: System.exit(status);
166: } else if (version) {
167: //print the version message
168: mLogger
169: .log(getGVDSVersion(),
170: LogManager.INFO_MESSAGE_LEVEL);
171: System.exit(status);
172: }
173:
174: try {
175: String pdax = partitionDAX(mProps, mDAXFile, mDirectory,
176: mType);
177: mLogger.log("Partitioned DAX written out " + pdax,
178: LogManager.DEBUG_MESSAGE_LEVEL);
179: } catch (Exception e) {
180: mLogger.log("", e, LogManager.FATAL_MESSAGE_LEVEL);
181: status = 1;
182: }
183: //log the end time and time execute
184: double endtime = new Date().getTime();
185: double execTime = (endtime - starttime) / 1000;
186: mLogger.log(
187: "Time taken to execute is " + execTime + " seconds",
188: LogManager.INFO_MESSAGE_LEVEL);
189:
190: System.exit(status);
191:
192: }
193:
194: /**
195: * @param properties the PegasusProperties
196: * @param daxFile String
197: * @param directory the directory where paritioned daxes reside
198: * @param type the type of partitioning to use.
199: *
200: * @return the path to the pdax file.
201: */
202: public String partitionDAX(PegasusProperties properties,
203: String daxFile, String directory, String type) {
204: int status = 0;
205: //sanity check for the dax file
206: if (daxFile == null || daxFile.length() == 0) {
207: mLogger.log("The dax file that is to be partitioned not "
208: + "specified", LogManager.FATAL_MESSAGE_LEVEL);
209: printShortVersion();
210: status = 1;
211: throw new RuntimeException("Unable to partition");
212: }
213:
214: //always try to make the directory
215: //referred to by the directory
216: File dir = new File(directory);
217: dir.mkdirs();
218:
219: //build up the partition graph
220: String callbackClass = (type.equalsIgnoreCase("label")) ? "DAX2LabelGraph"
221: : //graph with labels populated
222: "DAX2Graph";
223:
224: //load the appropriate partitioner
225: Callback callback = null;
226: Partitioner partitioner = null;
227: String daxName = null;
228: int state = 0;
229: try {
230: callback = DAXCallbackFactory.loadInstance(properties,
231: daxFile, callbackClass);
232:
233: //set the appropriate key that is to be used for picking up the labels
234: if (callback instanceof DAX2LabelGraph) {
235: ((DAX2LabelGraph) callback).setLabelKey(properties
236: .getPartitionerLabelKey());
237: }
238:
239: state = 1;
240: DaxParser d = new DaxParser(daxFile, properties, callback);
241: state = 2;
242: //get the graph map
243: Map graphMap = (Map) callback.getConstructedObject();
244: //get the fake dummy root node
245: GraphNode root = (GraphNode) graphMap
246: .get(DAX2Graph.DUMMY_NODE_ID);
247: daxName = ((DAX2Graph) callback).getNameOfDAX();
248: state = 3;
249: partitioner = PartitionerFactory.loadInstance(properties,
250: root, graphMap, type);
251: } catch (FactoryException fe) {
252: mLogger.log(fe.convertException(),
253: LogManager.FATAL_MESSAGE_LEVEL);
254: System.exit(2);
255: } catch (Exception e) {
256: int errorStatus = 1;
257: switch (state) {
258: case 0:
259: mLogger.log("Unable to load the DAXCallback", e,
260: LogManager.FATAL_MESSAGE_LEVEL);
261: errorStatus = 2;
262: break;
263:
264: case 1:
265: mLogger.log("Error while parsing the DAX file", e,
266: LogManager.FATAL_MESSAGE_LEVEL);
267: errorStatus = 1;
268: break;
269:
270: case 2:
271: mLogger
272: .log(
273: "Error while determining the root of the parsed DAX",
274: e, LogManager.FATAL_MESSAGE_LEVEL);
275: errorStatus = 1;
276: break;
277:
278: case 3:
279: mLogger.log("Unable to load the partitioner", e,
280: LogManager.FATAL_MESSAGE_LEVEL);
281: errorStatus = 2;
282: break;
283:
284: default:
285: mLogger.log("Unknown Error", e,
286: LogManager.FATAL_MESSAGE_LEVEL);
287: errorStatus = 1;
288: break;
289: }
290: status = errorStatus;
291: }
292: if (status > 0) {
293: throw new RuntimeException("Unable to partition");
294: }
295:
296: //load the writer callback that writes out
297: //the partitioned daxes and PDAX
298: WriterCallback cb = new WriterCallback();
299: cb.initialize(properties, daxFile, daxName, directory);
300:
301: //start the partitioning of the graph
302: partitioner.determinePartitions(cb);
303:
304: return cb.getPDAX();
305: }
306:
307: /**
308: * Generates the short version of the help on the stdout.
309: */
310: public void printShortVersion() {
311: String text = "\n $Id: PartitionDAX.java 464 2008-02-07 23:30:44Z vahi $ "
312: + "\n"
313: + getGVDSVersion()
314: + "\n Usage :partitiondax -d <dax file> [-D <dir for partitioned daxes>] "
315: + " -t <type of partitioning to be used> [-v] [-V] [-h]";
316:
317: mLogger.log(text, LogManager.ERROR_MESSAGE_LEVEL);
318:
319: }
320:
321: /**
322: * Generated the long version of the help on the stdout.
323: */
324: public void printLongVersion() {
325: String text = "\n "
326: + getGVDSVersion()
327: + "\n CPlanner/partitiondax - The tool that is used to partition the dax "
328: + "\n into smaller daxes for use in deferred planning."
329: + "\n "
330: + "\n Usage :partitiondax --dax <dax file> [--dir <dir for partitioned daxes>] "
331: + "\n --type <type of partitioning to be used> [--verbose] [--version] "
332: + "\n [--help]"
333: + "\n"
334: + "\n Mandatory Options "
335: + "\n -d|--dax fn the dax file that has to be partitioned into smaller daxes."
336: + "\n Other Options "
337: + "\n -t|--type type the partitioning technique that is to be used for partitioning."
338: + "\n -D|--dir dir the directory in which the partitioned daxes reside (defaults to "
339: + "\n current directory)"
340: + "\n -v|--verbose increases the verbosity of messages about what is going on."
341: + "\n -V|--version displays the version number of the Griphyn Virtual Data System."
342: + "\n -h|--help generates this help";
343:
344: System.out.println(text);
345:
346: }
347:
348: /**
349: * Tt generates the LongOpt which contain the valid options that the command
350: * will accept.
351: *
352: * @return array of <code>LongOpt</code> objects , corresponding to the valid
353: * options
354: */
355: public LongOpt[] generateValidOptions() {
356: LongOpt[] longopts = new LongOpt[6];
357:
358: longopts[0] = new LongOpt("dir", LongOpt.REQUIRED_ARGUMENT,
359: null, 'D');
360: longopts[1] = new LongOpt("dax", LongOpt.REQUIRED_ARGUMENT,
361: null, 'd');
362: longopts[2] = new LongOpt("type", LongOpt.REQUIRED_ARGUMENT,
363: null, 't');
364: longopts[3] = new LongOpt("verbose", LongOpt.NO_ARGUMENT, null,
365: 'v');
366: longopts[4] = new LongOpt("version", LongOpt.NO_ARGUMENT, null,
367: 'V');
368: longopts[5] = new LongOpt("help", LongOpt.NO_ARGUMENT, null,
369: 'h');
370: return longopts;
371:
372: }
373:
374: /**
375: * Loads all the properties that are needed by this class.
376: */
377: public void loadProperties() {
378:
379: }
380:
381: }
|