/** * 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.replica; import edu.isi.pegasus.common.util.DynamicLoader; import edu.isi.pegasus.common.util.CommonProperties; import edu.isi.pegasus.planner.catalog.ReplicaCatalog; import java.lang.reflect.*; import java.io.IOException; import java.util.Properties; import java.util.MissingResourceException; import edu.isi.pegasus.planner.common.PegasusProperties; import java.util.Enumeration; /** * This factory loads a replica 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$ * * @see edu.isi.pegasus.planner.catalog.replica.ReplicaCatalog * @see edu.isi.pegasus.planner.catalog.replica.ReplicaCatalogEntry * @see edu.isi.pegasus.planner.catalog.replica.impl.JDBCRC */ public class ReplicaFactory{ /** * Package to prefix "just" class names with. */ public static final String DEFAULT_PACKAGE = "edu.isi.pegasus.planner.catalog.replica.impl"; /** * Connects the interface with the replica 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 * @see #loadInstance() */ static public ReplicaCatalog loadInstance( PegasusProperties props ) throws ClassNotFoundException, IOException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { return loadInstance( props , props.getPropertiesInSubmitDirectory() ); } /** * Connects the interface with the replica 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. * @param file the physical location of the property file * * @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 * @see #loadInstance() */ static public ReplicaCatalog loadInstance( PegasusProperties props, String file ) throws ClassNotFoundException, IOException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { return loadInstance( props.getVDSProperties() , file ); } /** * Connects the interface with the replica 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 * @see #loadInstance() */ static private ReplicaCatalog loadInstance( CommonProperties props, String file ) throws ClassNotFoundException, IOException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { // sanity check if ( props == null ) throw new NullPointerException("invalid properties"); Properties connect = props.matchingSubset( ReplicaCatalog.c_prefix, false ); //get the default db driver properties in first pegasus.catalog.*.db.driver.* Properties db = props.matchingSubset( ReplicaCatalog.DB_ALL_PREFIX, false ); //now overload with the work catalog specific db properties. //pegasus.catalog.work.db.driver.* db.putAll( props.matchingSubset( ReplicaCatalog.DB_PREFIX , false ) ); //PM-778 properties file location requried for pegasus-db-admin if( file != null ){ connect.put( "properties.file", file ); } //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( ReplicaCatalog.DBDRIVER_PREFIX ); // driver = ( driver == null )? driver = props.getProperty( ReplicaCatalog.DBDRIVER_ALL_PREFIX ): driver; // connect.put( "db.driver", driver ); // determine the class that implements the work catalog return loadInstance( props.getProperty( ReplicaCatalog.c_prefix ), connect ); } /** * Connects the interface with the replica 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 * @see #loadInstance() */ static public ReplicaCatalog loadInstance( String catalogImplementor, Properties props ) throws ClassNotFoundException, IOException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { ReplicaCatalog result = null; /*// PM-1018 commented , as we want default rc.txt to be picked up if ( catalogImplementor == null ) throw new RuntimeException( "You need to specify the " + ReplicaCatalog.c_prefix + " property" ); */ //File also means SimpleFile if( catalogImplementor == null || catalogImplementor.equalsIgnoreCase( "File" ) ){ catalogImplementor = "SimpleFile"; } // 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 = (ReplicaCatalog) dl.instantiate( new Object[0] ); if ( result == null ) throw new RuntimeException( "Unable to load " + catalogImplementor ); if ( ! result.connect( props ) ) throw new RuntimeException( "Unable to connect to replica catalog implementation" ); // done return result; } public static ReplicaCatalog loadInstance(CommonProperties props) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }