/** * 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.transfer.sls; import edu.isi.pegasus.planner.classes.PlannerOptions; import edu.isi.pegasus.planner.classes.PegasusBag; import edu.isi.pegasus.planner.transfer.SLS; import edu.isi.pegasus.planner.common.PegasusProperties; import edu.isi.pegasus.common.util.DynamicLoader; import edu.isi.pegasus.planner.classes.Job; import edu.isi.pegasus.planner.common.PegasusConfiguration; import edu.isi.pegasus.planner.namespace.Pegasus; import java.util.HashMap; /** * A factory class to load the appropriate type of SLS Implementation to do * the Second Level Staging. * * @author Karan Vahi * @version $Revision$ */ public class SLSFactory { /** * The default package where the all the implementing classes are supposed to * reside. */ public static final String DEFAULT_PACKAGE_NAME = "edu.isi.pegasus.planner.transfer.sls"; /** * The name of the class implementing the condor code generator. */ public static final String DEFAULT_SLS_IMPL_CLASS = "Transfer"; /** * Name of class implementing condorio */ public static final String CONDORIO_SLS_IMPL_CLASS = "Condor"; /** * The known SLS implementations. */ public static String[] SLS_IMPLEMENTING_CLASSES = { "Transfer", "Condor" }; private final HashMap mSLSImplementationTable; private boolean mInitialized; private PegasusBag mBag; /** * The default constructor. */ public SLSFactory() { mSLSImplementationTable = new HashMap( 3 ); mInitialized = false; } /** * Initializes the factory with known GridStart implementations. * * @param bag the bag of objects that is used for initialization. */ public void initialize( PegasusBag bag ){ mBag = bag; //load all the known implementations and initialize them for( int i = 0; i < SLS_IMPLEMENTING_CLASSES.length; i++){ //load via reflection just once registerSLS( SLS_IMPLEMENTING_CLASSES[i], this.loadInstance( bag,SLS_IMPLEMENTING_CLASSES[i] )); } mInitialized = true; } /** * This method loads the appropriate implementing code generator as specified * by the user at runtime. If the megadag mode is specified in the options, * then that is used to load the implementing class, overriding the submit * mode specified in the properties file. * * * @param bag the bag of initialization objects. * * @return the instance of the class implementing this interface. * * @exception SLSFactoryException that nests any error that * might occur during the instantiation of the implementation. * * @see #DEFAULT_PACKAGE_NAME * * @throws SLSFactoryException */ public SLS loadInstance( Job job ) throws SLSFactoryException{ //sanity checks first if( !mInitialized ){ throw new SLSFactoryException( "SLSFactory needs to be initialized first before using" ); } //determine the short name of SLS implementation String shortName = this.getSLSShortName(job); //try loading on the basis of short name from the cache Object obj = this.mSLSImplementationTable.get( shortName ); if( obj == null ){ //load via reflection and register in the cache obj = this.loadInstance( mBag, shortName ); this.registerSLS( shortName, (SLS)obj ); } return (SLS)obj; } /** * Inserts an entry into the implementing class table. The name is * converted to lower case before being stored. * * @param name the short name for a GridStart implementation * @param implementation the object of the class implementing that style. */ private void registerSLS( String name, SLS implementation){ mSLSImplementationTable.put( name.toLowerCase(), implementation ); } /** * This method loads the appropriate code generator as specified by the * user at runtime. * * * @param bag the bag of initialization objects. * @param className the name of the implementing class. * * @return the instance of the class implementing this interface. * * @see #DEFAULT_PACKAGE_NAME * * @throws SLSFactoryException */ private SLS loadInstance( PegasusBag bag, String className) throws SLSFactoryException{ PegasusProperties properties = bag.getPegasusProperties(); PlannerOptions options = bag.getPlannerOptions(); //sanity check if (properties == null) { throw new SLSFactoryException( "Invalid properties passed" ); } if (className == null) { throw new SLSFactoryException( "Invalid className specified" ); } //prepend the package name if classname is actually just a basename className = (className.indexOf('.') == -1) ? //pick up from the default package DEFAULT_PACKAGE_NAME + "." + className : //load directly className; //try loading the class dynamically SLS sls = null; try { DynamicLoader dl = new DynamicLoader( className ); sls = ( SLS ) dl.instantiate( new Object[0] ); //initialize the loaded code generator sls.initialize( bag ); } catch ( Exception e ) { throw new SLSFactoryException( "Instantiating SLS Implementor ", className, e ); } return sls; } /** * Returns the short name for the job that needs to be loaded. * * @param job * * @return */ private String getSLSShortName(Job job) { String conf = job.vdsNS.getStringValue( Pegasus.DATA_CONFIGURATION_KEY ); return ( conf != null && (conf.equalsIgnoreCase( PegasusConfiguration.CONDOR_CONFIGURATION_VALUE) ))? CONDORIO_SLS_IMPL_CLASS: DEFAULT_SLS_IMPL_CLASS; } }