/**
* Copyright 2007-2008 University Of Southern California
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package edu.isi.pegasus.planner.partitioner;
import edu.isi.pegasus.common.logging.LogManagerFactory;
import edu.isi.pegasus.planner.common.PegasusProperties;
import edu.isi.pegasus.common.logging.LogManager;
import java.util.List;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.io.File;
import java.io.IOException;
/**
* This callback writes out a <code>DAX</code> file for each of the partitions,
* and also writes out a <code>PDAX</code> file that captures the relations
* between the partitions.
*
* @author not attributable
* @version $Revision$
*/
public class WriterCallback implements Callback {
/**
* The handle to the partition graph writer.
*/
protected PDAXWriter mPDAXWriter;
/**
* The handle to the dax writer that writes out the dax corresponding to the
* partition identified. The base name of the partition is gotten from it.
*/
protected DAXWriter mDAXWriter;
/**
* The path to the PDAX file written out.
*/
protected String mPDAX;
/**
* Handle to the properties available.
*/
protected PegasusProperties mProps;
/**
* The handle to the logger object.
*/
protected LogManager mLogger;
/**
* A boolean indicating that the partitioning has started. This is set,
* by the first call to the cbPartition( Partition ) callback.
*/
protected boolean mPartitioningStarted;
/**
* The default constructor.
*
*/
public WriterCallback(){
//mLogger = LogManager.getInstance();
}
/**
* Initializes the Writer Callback.
*
* @param properties the properties passed to the planner.
* @param daxFile the path to the DAX file that is being partitioned.
* @param daxName the namelabel of the DAX as set in the root element of the DAX.
* @param directory the directory where the partitioned daxes have to reside.
*/
public void initialize (PegasusProperties properties,
String daxFile,
String daxName,
String directory ){
mProps = properties;
mLogger = LogManagerFactory.loadSingletonInstance( properties );
//load the writer for the partitioned daxes
mDAXWriter = DAXWriter.loadInstance( properties, daxFile, directory );
mDAXWriter.setPartitionName( daxName );
//name of pdax file is same as the dax file
//meaning the name attribute in root element are same.
mPDAXWriter = getHandletoPDAXWriter( daxFile, daxName, directory ) ;
//write out the XML header for the PDAX file
mPDAXWriter.writeHeader();
}
/**
* Callback for when a partitioner determines that partition has been
* constructed. A DAX file is written out for the partition.
*
* @param p the constructed partition.
*
* @throws RuntimeException in case of any error while writing out the DAX or
* the PDAX files.
*/
public void cbPartition( Partition p ) {
mPartitioningStarted = true;
//not sure if we still need it
p.setName( mDAXWriter.getPartitionName() );
//for time being do a localize catch
//till i change the interface
try{
//write out the partition information to the PDAX file
mLogger.log( "Writing to the pdax file for partition " + p.getID(),
LogManager.DEBUG_MESSAGE_LEVEL);
mPDAXWriter.write( p );
mLogger.log( "Writing to the pdax file for partition -DONE" + p.getID(),
LogManager.DEBUG_MESSAGE_LEVEL );
//write out the DAX file
mDAXWriter.writePartitionDax( p );
}
catch( IOException ioe ){
//wrap and throw in Runtime Exception
throw new RuntimeException( "Writer Callback for partition " + p.getID(),
ioe );
}
}
/**
* Callback for when a partitioner determines the relations between partitions
* that it has previously constructed.
*
* @param child the id of a partition.
* @param parents the list of <code>String</code> objects that contain
* the id's of the parents of the partition.
*
*
* @throws RuntimeException in case of any error while writing out the DAX or
* the PDAX files.
*/
public void cbParents( String child, List parents ) {
mPDAXWriter.write( partitionRelation2XML( child, parents ) );
}
/**
* Callback for the partitioner to signal that it is done with the processing.
* This internally closes all the handles to the DAX and PDAX writers.
*
*/
public void cbDone(){
//change internal state to signal
//that we are done with partitioning.
mPartitioningStarted = false;
mPDAXWriter.close();
mDAXWriter.close();
}
/**
* Returns the name of the pdax file written out.
* Will be null if the partitioning has not completed.
*
* @return path to the pdax file.
*/
public String getPDAX(){
return this.mPDAX;
}
/**
* Returns the name of the partition, that needs to be set while creating
* the Partition object corresponding to each partition.
*
* @return the name of the partition.
*/
protected String getPartitionName(){
return mDAXWriter.getPartitionName();
}
/**
* It returns the handle to the writer for writing out the pdax file
* that contains the relations amongst the partitions and the jobs making
* up the partitions.
*
* @param daxFile the path to the DAX file that is being partitioned.
* @param name the name/label that is to be assigned to the pdax file.
* @param directory the directory where the partitioned daxes have to reside.
*
* @return handle to the writer of pdax file.
*/
protected PDAXWriter getHandletoPDAXWriter( String daxFile,
String name,
String directory ){
String pdaxPath;
//get the name of dax file sans the path
String daxName = new java.io.File( daxFile ).getName();
//construct the basename of the pdax file
pdaxPath = (daxName == null)?
"partition":
((daxName.indexOf('.') > 0)?
daxName.substring(0,daxName.indexOf('.')):
daxName)
;
//now the complete path
pdaxPath = directory + File.separator + pdaxPath + ".pdax";
//System.out.println("Name is " + nameOfPDAX);
mPDAX = pdaxPath;
return new PDAXWriter( name, pdaxPath );
}
/**
* Returns the xml description of a relation between 2 partitions.
*
* @param childID the ID of the child.
* @param parentID the ID of the parent.
*
* @return the XML description of child parent relation.
*/
protected String partitionRelation2XML( String childID , String parentID ){
StringBuffer sb = new StringBuffer();
sb.append("\n\t<child ref=\"").append(childID).append("\">");
sb.append("\n\t\t<parent ref=\"").append(parentID).append("\"/>");
sb.append("\n\t</child>");
return sb.toString();
}
/**
* Returns the xml description of a relation between 2 partitions.
*
* @param childID the ID of the child
* @param parentIDs <code>List</code> of parent IDs.
*
* @return the XML description of child parent relations.
*/
protected String partitionRelation2XML( String childID , List parentIDs ){
StringBuffer sb = new StringBuffer();
sb.append("\n\t<child ref=\"").append(childID).append("\">");
for( Iterator it = parentIDs.iterator(); it.hasNext(); ){
sb.append("\n\t\t<parent ref=\"").append(it.next()).append("\"/>");
}
sb.append("\n\t</child>");
return sb.toString();
}
/**
* Returns the xml description of a relation between 2 partitions.
*
* @param childID the ID of the child
* @param parentIDs <code>Set</code> of parent IDs.
*
* @return the XML description of child parent relations.
*/
protected String partitionRelation2XML( String childID , Set parentIDs ){
StringBuffer sb = new StringBuffer();
sb.append("\n\t<child ref=\"").append(childID).append("\">");
for ( Iterator it = parentIDs.iterator(); it.hasNext(); ){
sb.append("\n\t\t<parent ref=\"").append(it.next()).append("\"/>");
}
sb.append("\n\t</child>");
return sb.toString();
}
}