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.partitioner;
016:
017: import org.griphyn.cPlanner.common.LogManager;
018: import org.griphyn.cPlanner.common.PegasusProperties;
019:
020: import org.griphyn.common.util.DynamicLoader;
021: import org.griphyn.common.util.FactoryException;
022:
023: import java.io.BufferedWriter;
024: import java.io.File;
025: import java.io.FileWriter;
026: import java.io.IOException;
027: import java.io.PrintWriter;
028:
029: /**
030: * The abstract class that identifies the interface for writing out a dax
031: * corresponding to a partition. The interface stipulates that the jobs making
032: * up the partition and relations between those jobs in the partition are
033: * identified when invoking it. However all the job details are to be gotten
034: * by the implementing classes by parsing the original dax.
035: *
036: * @author Karan Vahi
037: * @version $Revision: 50 $
038: */
039: public abstract class DAXWriter {
040:
041: /**
042: * The prefix added to the name of the dax to identify it is a partitioned
043: * dax.
044: */
045: public static final String PARTITION_PREFIX = "partition_";
046:
047: /**
048: * The name of the package in which the writers are implemented.
049: */
050: public static final String PACKAGE_NAME = "org.griphyn.cPlanner.partitioner";
051:
052: /**
053: * The dax file that is being partitioned. The dax file is the repository
054: * for all the jobs in the partitioned daxes.
055: */
056: protected String mDaxFile;
057:
058: /**
059: * The directory in which the daxes corresponding to the partition are
060: * generated.
061: */
062: protected String mPDAXDirectory;
063:
064: /**
065: * The name of the partition dax that are generated.
066: */
067: protected String mPartitionName;
068:
069: /**
070: * The handle to the logging object.
071: */
072: protected LogManager mLogger;
073:
074: /**
075: * The write handle to the xml file being written.
076: */
077: protected PrintWriter mWriteHandle;
078:
079: /**
080: * The default constructor
081: */
082: protected DAXWriter() {
083: mDaxFile = null;
084: mPDAXDirectory = null;
085: mLogger = LogManager.getInstance();
086: mPartitionName = null;
087:
088: }
089:
090: /**
091: * The overloaded constructor.
092: *
093: * @param daxFile the path to the dax file that is being partitioned.
094: * @param directory the directory in which the partitioned daxes are to be
095: * generated.
096: */
097: protected DAXWriter(String daxFile, String directory) {
098: mLogger = LogManager.getInstance();
099: mDaxFile = daxFile;
100: mPDAXDirectory = directory;
101: mPartitionName = null;
102: }
103:
104: /**
105: * It writes out a dax consisting of the jobs as specified in the partition.
106: *
107: * @param partition the partition object containing the relations and id's
108: * of the jobs making up the partition.
109: *
110: * @return boolean true if dax successfully generated and written.
111: * false in case of error.
112: */
113: public boolean writePartitionDax(Partition partition) {
114: return writePartitionDax(partition, partition.getIndex());
115: }
116:
117: /**
118: * It writes out a dax consisting of the jobs as specified in the partition.
119: *
120: * @param partition the partition object containing the relations and id's
121: * of the jobs making up the partition.
122: * @param index the index of the partition.
123: *
124: * @return boolean true if dax successfully generated and written.
125: * false in case of error.
126: */
127: public abstract boolean writePartitionDax(Partition partition,
128: int index);
129:
130: /**
131: * The ends up loading the PDAXWriter. It selects the writer as specified by
132: * the vds.partition.parse.mode property.
133: *
134: * @param properties the handle to the properties visible to Pegasus.
135: * @param daxFile the path to the dax file that is being partitioned.
136: * @param directory the directory in which the partitioned daxes are to be
137: * generated.
138: */
139: public static DAXWriter loadInstance(PegasusProperties properties,
140: String daxFile, String directory) {
141:
142: String className = properties.getPartitionParsingMode();
143: className = (className.equalsIgnoreCase("single")) ? "SingleLook"
144: : (className.equalsIgnoreCase("multiple")) ? "MultipleLook"
145: : className;
146:
147: return loadInstance(className, properties, daxFile, directory);
148: }
149:
150: /**
151: * Loads the implementing PDAXWriter. The name of the class that is to be
152: * loaded is passed and can be complete(with package name) or just the name
153: * of the class, in which case the class is loaded from the default package.
154: *
155: * @param properties the handle to the properties visible to Pegasus.
156: * @param className the name of the class with or without the package name.
157: * @param daxFile the path to the dax file that is being partitioned.
158: * @param directory the directory in which the partitioned daxes are to be
159: * generated.
160: *
161: * @throws FactoryException that nests any error that
162: * might occur during the instantiation of the implementation.
163: */
164: public static DAXWriter loadInstance(String className,
165: PegasusProperties properties, String daxFile,
166: String directory) throws FactoryException {
167:
168: if (className.indexOf('.') == -1) {
169: //prepend the default package name
170: className = PACKAGE_NAME + "." + className;
171: }
172:
173: //sanity and default checks
174: directory = (directory == null) ? "." : directory;
175:
176: //try loading the class dynamically
177: DAXWriter writer = null;
178: DynamicLoader dl = new DynamicLoader(className);
179: try {
180: Object argList[] = new Object[2];
181: argList[0] = daxFile;
182: argList[1] = directory;
183: writer = (DAXWriter) dl.instantiate(argList);
184: } catch (Exception e) {
185: throw new FactoryException("Instantiating DAXWriter",
186: className, e);
187: }
188:
189: return writer;
190:
191: }
192:
193: /**
194: * It constructs the name of the partitioned dax file that has to be written
195: * corresponding to a partition of the dax. The dax name returned has no
196: * prefix added to it.
197: *
198: * @param daxName the name attribute in the adag element of the dax.
199: * @param index the partition number of the partition.
200: */
201: public static String getPDAXFilename(String daxName, int index) {
202: return getPDAXFilename(daxName, index, false);
203: }
204:
205: /**
206: * It constructs the name of the partitioned dax file that has to be written
207: * corresponding to a partition of the dax.
208: *
209: * @param daxName the name attribute in the adag element of the dax.
210: * @param index the partition number of the partition.
211: * @param addPrefix whether you want to addPrefix or not.
212: */
213: public static String getPDAXFilename(String daxName, int index,
214: boolean addPrefix) {
215: StringBuffer sb = new StringBuffer(32);
216:
217: //get the partition name
218: sb.append(constructPartitionName(daxName, addPrefix));
219:
220: //add the suffix
221: sb.append("_").append(index).append(".dax");
222:
223: return sb.toString();
224: }
225:
226: /**
227: * It constructs the partition name given the daxName. It only ends up adding
228: * the prefix if the addPrefix parameter is set.
229: *
230: * @param daxName the name attribute in the adag element of the dax.
231: * @param addPrefix whether to add prefix or not.
232: */
233: private static String constructPartitionName(String daxName,
234: boolean addPrefix) {
235: StringBuffer sb = new StringBuffer();
236:
237: //append the partition prefix to it.
238: if (addPrefix)
239: sb.append(PARTITION_PREFIX);
240:
241: //construct a partition name
242: sb = (daxName == null) ?
243: // set it to the default name
244: sb.append("test")
245: : sb.append(daxName);
246:
247: return sb.toString();
248: }
249:
250: /**
251: * It sets the name of the partition in the dax that is generated. It suffixes
252: * PARTITION_PREFIX to the name of the dax.
253: *
254: * @param daxName the name attribute in the adag element of the dax.
255: */
256: public void setPartitionName(String daxName) {
257: //yes we want the partition prefix to be added
258: mPartitionName = constructPartitionName(daxName, true);
259: }
260:
261: /**
262: * It returns the name of the partitioned dax, that the object is
263: * currently writing or initialized to write. By the name, one means the
264: * value that is set to the name attribute in the adag element.
265: */
266: public String getPartitionName() {
267: return mPartitionName;
268: }
269:
270: /**
271: * This initializes the write handle a file in directory specified
272: * when creating the instance of this class. The name of the file is
273: * constructed by default, by looking at the partition name that is
274: * assigned to the name attribute for the adag element.
275: *
276: * @param index the partition number of the partition.
277: */
278: public void initializeWriteHandle(int index) {
279: //check if partition name is set
280: if (mPartitionName == null) {
281: //set it to default
282: setPartitionName(null);
283: }
284: String name = mPartitionName + "_" + index + ".dax";
285: initializeWriteHandle(name);
286:
287: }
288:
289: /**
290: * This initializes the write handle to the file in directory specified
291: * when creating the instance of this class.
292: *
293: * @param fileName the name of the file that is to be written in the
294: * directory.
295: */
296: public void initializeWriteHandle(String fileName) {
297: String completeName = mPDAXDirectory + File.separator
298: + fileName;
299: try {
300: //if the write handle was not explicitly closed, closing it
301: if (mWriteHandle != null)
302: this .close();
303:
304: mWriteHandle = new PrintWriter(new BufferedWriter(
305: new FileWriter(completeName)));
306: } catch (IOException e) {
307: throw new RuntimeException("Unable to write to file "
308: + completeName + " :", e);
309: }
310:
311: }
312:
313: /**
314: * Writes out to the file.
315: */
316: public void writeln(String st) {
317: mWriteHandle.println(st);
318: }
319:
320: /**
321: * Close the write handle to the file that is written.
322: */
323: public void close() {
324: if (mWriteHandle != null) {
325: mWriteHandle.close();
326: mWriteHandle = null;
327: }
328: }
329:
330: }
|