/** * 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.catalog.work; import edu.isi.pegasus.common.util.DynamicLoader; import edu.isi.pegasus.common.util.CommonProperties; import edu.isi.pegasus.planner.catalog.WorkCatalog; import java.util.Properties; import java.util.Enumeration; import edu.isi.pegasus.planner.common.PegasusProperties; /** * This factory loads a work catalog, as specified by the properties. * Each invocation of the factory will result in a new instance of a * connection to the replica catalog. * * @author Karan Vahi * @author Jens-S. Vöckler * @version $Revision: 50 $ * * @see org.griphyn.common.catalog.WorkCatalog */ public class WorkFactory{ /** * Package to prefix "just" class names with. */ public static final String DEFAULT_PACKAGE = "edu.isi.pegasus.planner.catalog.work"; /** * Connects the interface with the work catalog implementation. The * choice of backend is configured through properties. This class is * useful for non-singleton instances that may require changing * properties. * * @param props is an instance of properties to use. * * @exception ClassNotFoundException if the schema for the database * cannot be loaded. You might want to check your CLASSPATH, too. * @exception NoSuchMethodException if the schema's constructor interface * does not comply with the database driver API. * @exception InstantiationException if the schema class is an abstract * class instead of a concrete implementation. * @exception IllegalAccessException if the constructor for the schema * class it not publicly accessible to this package. * @exception InvocationTargetException if the constructor of the schema * throws an exception while being dynamically loaded. * * @see org.griphyn.common.util.CommonProperties */ static public WorkCatalog loadInstance( PegasusProperties props ) throws WorkFactoryException { return loadInstance( props.getVDSProperties() ); } /** * Connects the interface with the work catalog implementation. The * choice of backend is configured through properties. This class is * useful for non-singleton instances that may require changing * properties. * * @param props is an instance of properties to use. * * @exception ClassNotFoundException if the schema for the database * cannot be loaded. You might want to check your CLASSPATH, too. * @exception NoSuchMethodException if the schema's constructor interface * does not comply with the database driver API. * @exception InstantiationException if the schema class is an abstract * class instead of a concrete implementation. * @exception IllegalAccessException if the constructor for the schema * class it not publicly accessible to this package. * @exception InvocationTargetException if the constructor of the schema * throws an exception while being dynamically loaded. * * @see org.griphyn.common.util.CommonProperties */ static public WorkCatalog loadInstance( CommonProperties props ) throws WorkFactoryException { // sanity check if ( props == null ) throw new NullPointerException("invalid properties"); Properties connect = props.matchingSubset( WorkCatalog.c_prefix, false ); //get the default db driver properties in first pegasus.catalog.*.db.driver.* Properties db = props.matchingSubset( WorkCatalog.DB_ALL_PREFIX, false ); //now overload with the work catalog specific db properties. //pegasus.catalog.work.db.driver.* db.putAll( props.matchingSubset( WorkCatalog.DB_PREFIX , false ) ); //to make sure that no confusion happens. //add the db prefix to all the db properties for( Enumeration e = db.propertyNames(); e.hasMoreElements(); ){ String key = (String)e.nextElement(); connect.put( "db." + key, db.getProperty( key )); } //put the driver property back into the DB property // String driver = props.getProperty( WorkCatalog.DBDRIVER_PREFIX ); // if( driver == null ){ driver = props.getProperty( WorkCatalog.DBDRIVER_ALL_PREFIX ); } // connect.put( "db.driver", driver ); // determine the class that implements the work catalog return loadInstance( props.getProperty( WorkCatalog.c_prefix ), connect ); } /** * Connects the interface with the work catalog implementation. The * choice of backend is configured through properties. This class is * useful for non-singleton instances that may require changing * properties. * * @param props is an instance of properties to use. * * @exception ClassNotFoundException if the schema for the database * cannot be loaded. You might want to check your CLASSPATH, too. * @exception NoSuchMethodException if the schema's constructor interface * does not comply with the database driver API. * @exception InstantiationException if the schema class is an abstract * class instead of a concrete implementation. * @exception IllegalAccessException if the constructor for the schema * class it not publicly accessible to this package. * @exception InvocationTargetException if the constructor of the schema * throws an exception while being dynamically loaded. * * @see org.griphyn.common.util.CommonProperties */ static private WorkCatalog loadInstance( String catalogImplementor, Properties props ) throws WorkFactoryException { WorkCatalog result = null; try{ if ( catalogImplementor == null ) throw new RuntimeException( "You need to specify the " + WorkCatalog.c_prefix + " property" ); // syntactic sugar adds absolute class prefix if ( catalogImplementor.indexOf('.') == -1 ) catalogImplementor = DEFAULT_PACKAGE + "." + catalogImplementor; // POSTCONDITION: we have now a fully-qualified classname DynamicLoader dl = new DynamicLoader( catalogImplementor ); result = (WorkCatalog) dl.instantiate( new Object[0] ); if ( ! result.connect( props ) ) throw new RuntimeException( "Unable to connect to work catalog implementation" ); } catch( Exception e ) { throw new WorkFactoryException( " Unable to instantiate Work Catalog ", catalogImplementor, e ); } // done return result; } }