/** * 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.cluster; import edu.isi.pegasus.planner.classes.ADag; import edu.isi.pegasus.planner.classes.PegasusBag; import edu.isi.pegasus.planner.common.PegasusProperties; import edu.isi.pegasus.planner.partitioner.Partitioner; import edu.isi.pegasus.planner.partitioner.PartitionerFactory; import edu.isi.pegasus.planner.partitioner.PartitionerFactoryException; import edu.isi.pegasus.planner.partitioner.graph.GraphNode; import edu.isi.pegasus.common.util.DynamicLoader; import java.util.Map; import java.util.HashMap; /** * A factory class to load the appropriate Partitioner, and Clusterer Callback * for clustering. An abstract factory, as it loads the appropriate partitioner * matching a clustering technique. * * * @author Karan Vahi vahi@isi.edu * @version $Revision$ */ public class ClustererFactory { /** * The default package where all the implementations reside. */ public static final String DEFAULT_PACKAGE_NAME = "edu.isi.pegasus.planner.cluster"; /** * The name of the class implementing horizontal clustering. */ public static final String HORIZONTAL_CLUSTERING_CLASS = "Horizontal"; /** * The name of the class implementing vertical clustering. */ public static final String VERTICAL_CLUSTERING_CLASS = "Vertical"; /** * The type corresponding to label based clustering. */ private static final String LABEL_CLUSTERING_TYPE = "label"; /** * The table that maps clustering technique to a partitioner. */ private static Map mPartitionerTable; /** * The table that maps a clustering technique to a clustering impelemntation. */ private static Map mClustererTable; /** * Loads the appropriate partitioner on the basis of the clustering type * specified in the options passed to the planner. * * @param properties the <code>PegasusProperties</code> object containing all * the properties required by Pegasus. * @param type type of clustering to be used. * @param root the dummy root node of the graph. * @param graph the map containing all the nodes of the graph keyed by * the logical id of the nodes. * * @return the instance of the appropriate partitioner. * * @throws ClustererFactoryException that nests any error that * might occur during the instantiation * * @see #DEFAULT_PACKAGE_NAME */ public static Partitioner loadPartitioner(PegasusProperties properties, String type, GraphNode root, Map graph ) throws ClustererFactoryException{ String clusterer = type; //sanity check if( clusterer == null ){ throw new ClustererFactoryException( "No Clustering Technique Specified "); } //try to find the appropriate partitioner Object partitionerClass = partitionerTable().get( clusterer ); if ( partitionerClass == null ){ throw new ClustererFactoryException( "No matching partitioner found for clustering technique " + clusterer ); } //now load the partitioner Partitioner partitioner = null; try{ partitioner = PartitionerFactory.loadInstance( properties, root, graph, (String) partitionerClass ); } catch ( PartitionerFactoryException e ){ throw new ClustererFactoryException( " Unable to instantiate partitioner " + partitionerClass, e ); } return partitioner; } /** * Loads the appropriate clusterer on the basis of the clustering type * specified in the options passed to the planner. * * @param dag the workflow being clustered. * @param bag the bag of initialization objects. * @param type type of clustering to be used. * * @return the instance of the appropriate clusterer. * * @throws ClustererFactoryException that nests any error that * might occur during the instantiation * * @see #DEFAULT_PACKAGE_NAME */ public static Clusterer loadClusterer( ADag dag, PegasusBag bag, String type ) throws ClustererFactoryException{ //sanity check if( type == null ){ throw new ClustererFactoryException( "No Clustering Technique Specified "); } //try to find the appropriate clusterer Object clustererClass = clustererTable().get( type ); if ( clustererClass == null ){ throw new ClustererFactoryException( "No matching clusterer found for clustering technique " + type ); } //now load the clusterer Clusterer clusterer = null; String className = ( String )clustererClass; try{ //prepend the package name if required className = ( className.indexOf('.') == -1 )? //pick up from the default package DEFAULT_PACKAGE_NAME + "." + className: //load directly className; //try loading the class dynamically DynamicLoader dl = new DynamicLoader( className ); clusterer = (Clusterer) dl.instantiate( new Object[0] ); clusterer.initialize( dag, bag ); } catch ( Exception e ){ throw new ClustererFactoryException( " Unable to instantiate partitioner ", className, e ); } return clusterer; } /** * Returns a table that maps, the clustering technique to an appropriate * class implementing that clustering technique. * * @return a Map indexed by clustering styles, and values as corresponding * implementing Clustering classes. */ private static Map clustererTable(){ if( mClustererTable == null ){ mClustererTable = new HashMap(3); mClustererTable.put( HORIZONTAL_CLUSTERING_CLASS.toLowerCase(), HORIZONTAL_CLUSTERING_CLASS ); mClustererTable.put( VERTICAL_CLUSTERING_CLASS.toLowerCase(), VERTICAL_CLUSTERING_CLASS ); mClustererTable.put( LABEL_CLUSTERING_TYPE.toLowerCase(), VERTICAL_CLUSTERING_CLASS ); } return mClustererTable; } /** * Returns a table that maps, the clustering technique to an appropriate * partitioning technique. * * @return a Map indexed by clustering styles, and values as corresponding * Partitioners. */ private static Map partitionerTable(){ if( mPartitionerTable == null ){ mPartitionerTable = new HashMap(3); mPartitionerTable.put( HORIZONTAL_CLUSTERING_CLASS.toLowerCase(), PartitionerFactory.LEVEL_BASED_PARTITIONING_CLASS ); mPartitionerTable.put( VERTICAL_CLUSTERING_CLASS.toLowerCase(), PartitionerFactory.LABEL_BASED_PARTITIONING_CLASS ); mPartitionerTable.put( LABEL_CLUSTERING_TYPE.toLowerCase(), PartitionerFactory.LABEL_BASED_PARTITIONING_CLASS ); } return mPartitionerTable; } }