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.cluster;
017:
018: import org.griphyn.cPlanner.classes.ADag;
019: import org.griphyn.cPlanner.classes.PegasusBag;
020:
021: import org.griphyn.cPlanner.common.PegasusProperties;
022:
023: import org.griphyn.cPlanner.partitioner.Partitioner;
024: import org.griphyn.cPlanner.partitioner.PartitionerFactory;
025: import org.griphyn.cPlanner.partitioner.PartitionerFactoryException;
026: import org.griphyn.cPlanner.partitioner.graph.GraphNode;
027:
028: import org.griphyn.common.util.DynamicLoader;
029:
030: import java.util.Map;
031: import java.util.HashMap;
032:
033: /**
034: * A factory class to load the appropriate Partitioner, and Clusterer Callback
035: * for clustering. An abstract factory, as it loads the appropriate partitioner
036: * matching a clustering technique.
037: *
038: *
039: * @author Karan Vahi vahi@isi.edu
040: * @version $Revision: 450 $
041: */
042:
043: public class ClustererFactory {
044:
045: /**
046: * The default package where all the implementations reside.
047: */
048: public static final String DEFAULT_PACKAGE_NAME = "org.griphyn.cPlanner.cluster";
049:
050: /**
051: * The name of the class implementing horizontal clustering.
052: */
053: public static final String HORIZONTAL_CLUSTERING_CLASS = "Horizontal";
054:
055: /**
056: * The name of the class implementing vertical clustering.
057: */
058: public static final String VERTICAL_CLUSTERING_CLASS = "Vertical";
059:
060: /**
061: * The type corresponding to label based clustering.
062: */
063: private static final String LABEL_CLUSTERING_TYPE = "label";
064:
065: /**
066: * The table that maps clustering technique to a partitioner.
067: */
068: private static Map mPartitionerTable;
069:
070: /**
071: * The table that maps a clustering technique to a clustering impelemntation.
072: */
073: private static Map mClustererTable;
074:
075: /**
076: * Loads the appropriate partitioner on the basis of the clustering type
077: * specified in the options passed to the planner.
078: *
079: * @param properties the <code>PegasusProperties</code> object containing all
080: * the properties required by Pegasus.
081: * @param type type of clustering to be used.
082: * @param root the dummy root node of the graph.
083: * @param graph the map containing all the nodes of the graph keyed by
084: * the logical id of the nodes.
085: *
086: * @return the instance of the appropriate partitioner.
087: *
088: * @throws ClustererFactoryException that nests any error that
089: * might occur during the instantiation
090: *
091: * @see #DEFAULT_PACKAGE_NAME
092: */
093: public static Partitioner loadPartitioner(
094: PegasusProperties properties, String type, GraphNode root,
095: Map graph) throws ClustererFactoryException {
096:
097: String clusterer = type;
098:
099: //sanity check
100: if (clusterer == null) {
101: throw new ClustererFactoryException(
102: "No Clustering Technique Specified ");
103: }
104:
105: //try to find the appropriate partitioner
106: Object partitionerClass = partitionerTable().get(clusterer);
107: if (partitionerClass == null) {
108: throw new ClustererFactoryException(
109: "No matching partitioner found for clustering technique "
110: + clusterer);
111: }
112:
113: //now load the partitioner
114: Partitioner partitioner = null;
115: try {
116: partitioner = PartitionerFactory.loadInstance(properties,
117: root, graph, (String) partitionerClass);
118: } catch (PartitionerFactoryException e) {
119: throw new ClustererFactoryException(
120: " Unable to instantiate partitioner "
121: + partitionerClass, e);
122: }
123: return partitioner;
124: }
125:
126: /**
127: * Loads the appropriate clusterer on the basis of the clustering type
128: * specified in the options passed to the planner.
129: *
130: * @param dag the workflow being clustered.
131: * @param bag the bag of initialization objects.
132: * @param type type of clustering to be used.
133: *
134: * @return the instance of the appropriate clusterer.
135: *
136: * @throws ClustererFactoryException that nests any error that
137: * might occur during the instantiation
138: *
139: * @see #DEFAULT_PACKAGE_NAME
140: */
141: public static Clusterer loadClusterer(ADag dag, PegasusBag bag,
142: String type) throws ClustererFactoryException {
143:
144: //sanity check
145: if (type == null) {
146: throw new ClustererFactoryException(
147: "No Clustering Technique Specified ");
148: }
149:
150: //try to find the appropriate clusterer
151: Object clustererClass = clustererTable().get(type);
152: if (clustererClass == null) {
153: throw new ClustererFactoryException(
154: "No matching clusterer found for clustering technique "
155: + type);
156: }
157:
158: //now load the clusterer
159: Clusterer clusterer = null;
160: String className = (String) clustererClass;
161: try {
162:
163: //prepend the package name if required
164: className = (className.indexOf('.') == -1) ?
165: //pick up from the default package
166: DEFAULT_PACKAGE_NAME + "." + className
167: :
168: //load directly
169: className;
170:
171: //try loading the class dynamically
172: DynamicLoader dl = new DynamicLoader(className);
173: clusterer = (Clusterer) dl.instantiate(new Object[0]);
174: clusterer.initialize(dag, bag);
175: } catch (Exception e) {
176: throw new ClustererFactoryException(
177: " Unable to instantiate partitioner ", className, e);
178: }
179: return clusterer;
180: }
181:
182: /**
183: * Returns a table that maps, the clustering technique to an appropriate
184: * class implementing that clustering technique.
185: *
186: * @return a Map indexed by clustering styles, and values as corresponding
187: * implementing Clustering classes.
188: */
189: private static Map clustererTable() {
190: if (mClustererTable == null) {
191: mClustererTable = new HashMap(3);
192: mClustererTable.put(HORIZONTAL_CLUSTERING_CLASS
193: .toLowerCase(), HORIZONTAL_CLUSTERING_CLASS);
194: mClustererTable.put(
195: VERTICAL_CLUSTERING_CLASS.toLowerCase(),
196: VERTICAL_CLUSTERING_CLASS);
197: mClustererTable.put(LABEL_CLUSTERING_TYPE.toLowerCase(),
198: VERTICAL_CLUSTERING_CLASS);
199: }
200: return mClustererTable;
201: }
202:
203: /**
204: * Returns a table that maps, the clustering technique to an appropriate
205: * partitioning technique.
206: *
207: * @return a Map indexed by clustering styles, and values as corresponding
208: * Partitioners.
209: */
210: private static Map partitionerTable() {
211: if (mPartitionerTable == null) {
212: mPartitionerTable = new HashMap(3);
213: mPartitionerTable.put(HORIZONTAL_CLUSTERING_CLASS
214: .toLowerCase(),
215: PartitionerFactory.LEVEL_BASED_PARTITIONING_CLASS);
216: mPartitionerTable.put(VERTICAL_CLUSTERING_CLASS
217: .toLowerCase(),
218: PartitionerFactory.LABEL_BASED_PARTITIONING_CLASS);
219: mPartitionerTable.put(LABEL_CLUSTERING_TYPE.toLowerCase(),
220: PartitionerFactory.LABEL_BASED_PARTITIONING_CLASS);
221: }
222: return mPartitionerTable;
223: }
224:
225: }
|