You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by kw...@apache.org on 2013/12/03 14:59:20 UTC

svn commit: r1547391 - in /manifoldcf/branches/CONNECTORS-781/framework: agents/src/main/java/org/apache/manifoldcf/agents/interfaces/OutputConnectorFactory.java core/src/main/java/org/apache/manifoldcf/core/interfaces/ConnectorFactory.java

Author: kwright
Date: Tue Dec  3 13:59:19 2013
New Revision: 1547391

URL: http://svn.apache.org/r1547391
Log:
Structure base class as a generic, to reduce casting.

Modified:
    manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/OutputConnectorFactory.java
    manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ConnectorFactory.java

Modified: manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/OutputConnectorFactory.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/OutputConnectorFactory.java?rev=1547391&r1=1547390&r2=1547391&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/OutputConnectorFactory.java (original)
+++ manifoldcf/branches/CONNECTORS-781/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/OutputConnectorFactory.java Tue Dec  3 13:59:19 2013
@@ -27,18 +27,37 @@ import java.lang.reflect.*;
 
 /** This is the factory class for IOutputConnector objects.
 */
-public class OutputConnectorFactory
+public class OutputConnectorFactory extends ConnectorFactory<IOutputConnector>
 {
   public static final String _rcsid = "@(#)$Id: OutputConnectorFactory.java 988245 2010-08-23 18:39:35Z kwright $";
 
-  // Pool hash table.
-  // Keyed by PoolKey; value is Pool
-  protected static Map poolHash = new HashMap();
+  // Static factory
+  protected static OutputConnectorFactory thisFactory = new OutputConnectorFactory();
 
-  // private static HashMap checkedOutConnectors = new HashMap();
+  protected OutputConnectorFactory()
+  {
+  }
 
-  private OutputConnectorFactory()
+  protected boolean isInstalled(IThreadContext tc, String className)
+    throws ManifoldCFException
+  {
+    IOutputConnectorManager connMgr = OutputConnectorManagerFactory.make(tc);
+    return connMgr.isInstalled(className);
+  }
+  
+  /** Get the activities supported by this connector.
+  *@param className is the class name.
+  *@return the list of activities.
+  */
+  public String[] getThisActivitiesList(IThreadContext threadContext, String className)
+    throws ManifoldCFException
   {
+    IOutputConnector connector = getThisConnector(threadContext, className);
+    if (connector == null)
+      return null;
+    String[] values = connector.getActivitiesList();
+    java.util.Arrays.sort(values);
+    return values;
   }
 
   /** Install connector.
@@ -47,8 +66,7 @@ public class OutputConnectorFactory
   public static void install(IThreadContext threadContext, String className)
     throws ManifoldCFException
   {
-    IOutputConnector connector = getConnectorNoCheck(className);
-    connector.install(threadContext);
+    thisFactory.installThis(threadContext,className);
   }
 
   /** Uninstall connector.
@@ -57,8 +75,7 @@ public class OutputConnectorFactory
   public static void deinstall(IThreadContext threadContext, String className)
     throws ManifoldCFException
   {
-    IOutputConnector connector = getConnectorNoCheck(className);
-    connector.deinstall(threadContext);
+    thisFactory.deinstallThis(threadContext,className);
   }
 
   /** Get the activities supported by this connector.
@@ -68,12 +85,7 @@ public class OutputConnectorFactory
   public static String[] getActivitiesList(IThreadContext threadContext, String className)
     throws ManifoldCFException
   {
-    IOutputConnector connector = getConnector(threadContext, className);
-    if (connector == null)
-      return null;
-    String[] values = connector.getActivitiesList();
-    java.util.Arrays.sort(values);
-    return values;
+    return thisFactory.getThisActivitiesList(threadContext,className);
   }
 
   /** Output the configuration header section.
@@ -82,10 +94,7 @@ public class OutputConnectorFactory
     IHTTPOutput out, Locale locale, ConfigParams parameters, ArrayList tabsArray)
     throws ManifoldCFException, IOException
   {
-    IOutputConnector connector = getConnector(threadContext, className);
-    if (connector == null)
-      return;
-    connector.outputConfigurationHeader(threadContext,out,locale,parameters,tabsArray);
+    thisFactory.outputThisConfigurationHeader(threadContext,className,out,locale,parameters,tabsArray);
   }
 
   /** Output the configuration body section.
@@ -94,10 +103,7 @@ public class OutputConnectorFactory
     IHTTPOutput out, Locale locale, ConfigParams parameters, String tabName)
     throws ManifoldCFException, IOException
   {
-    IOutputConnector connector = getConnector(threadContext, className);
-    if (connector == null)
-      return;
-    connector.outputConfigurationBody(threadContext,out,locale,parameters,tabName);
+    thisFactory.outputThisConfigurationBody(threadContext,className,out,locale,parameters,tabName);
   }
 
   /** Process configuration post data for a connector.
@@ -106,10 +112,7 @@ public class OutputConnectorFactory
     IPostParameters variableContext, Locale locale, ConfigParams configParams)
     throws ManifoldCFException
   {
-    IOutputConnector connector = getConnector(threadContext, className);
-    if (connector == null)
-      return null;
-    return connector.processConfigurationPost(threadContext,variableContext,locale,configParams);
+    return thisFactory.processThisConfigurationPost(threadContext,className,variableContext,locale,configParams);
   }
   
   /** View connector configuration.
@@ -118,11 +121,7 @@ public class OutputConnectorFactory
     IHTTPOutput out, Locale locale, ConfigParams configParams)
     throws ManifoldCFException, IOException
   {
-    IOutputConnector connector = getConnector(threadContext, className);
-    // We want to be able to view connections even if they have unregistered connectors.
-    if (connector == null)
-      return;
-    connector.viewConfiguration(threadContext,out,locale,configParams);
+    thisFactory.viewThisConfiguration(threadContext,className,out,locale,configParams);
   }
 
   /** Get an output connector instance, without checking for installed connector.
@@ -132,140 +131,7 @@ public class OutputConnectorFactory
   public static IOutputConnector getConnectorNoCheck(String className)
     throws ManifoldCFException
   {
-    try
-    {
-      Class theClass = ManifoldCF.findClass(className);
-      Class[] argumentClasses = new Class[0];
-      // Look for a constructor
-      Constructor c = theClass.getConstructor(argumentClasses);
-      Object[] arguments = new Object[0];
-      Object o = c.newInstance(arguments);
-      if (!(o instanceof IOutputConnector))
-        throw new ManifoldCFException("Class '"+className+"' does not implement IOutputConnector.");
-      return (IOutputConnector)o;
-    }
-    catch (InvocationTargetException e)
-    {
-      Throwable z = e.getTargetException();
-      if (z instanceof Error)
-        throw (Error)z;
-      else if (z instanceof RuntimeException)
-        throw (RuntimeException)z;
-      else
-        throw (ManifoldCFException)z;
-    }
-    catch (ClassNotFoundException e)
-    {
-      throw new ManifoldCFException("No output connector class '"+className+"' was found.",
-        e);
-    }
-    catch (NoSuchMethodException e)
-    {
-      throw new ManifoldCFException("No appropriate constructor for IOutputConnector implementation '"+
-        className+"'.  Need xxx().",
-        e);
-    }
-    catch (SecurityException e)
-    {
-      throw new ManifoldCFException("Protected constructor for IOutputConnector implementation '"+className+"'",
-        e);
-    }
-    catch (IllegalAccessException e)
-    {
-      throw new ManifoldCFException("Unavailable constructor for IOutputConnector implementation '"+className+"'",
-        e);
-    }
-    catch (IllegalArgumentException e)
-    {
-      throw new ManifoldCFException("Shouldn't happen!!!",e);
-    }
-    catch (InstantiationException e)
-    {
-      throw new ManifoldCFException("InstantiationException for IOutputConnector implementation '"+className+"'",
-        e);
-    }
-    catch (ExceptionInInitializerError e)
-    {
-      throw new ManifoldCFException("ExceptionInInitializerError for IOutputConnector implementation '"+className+"'",
-        e);
-    }
-
-  }
-
-  /** Get an output connector instance.
-  *@param className is the class name.
-  *@return the instance.
-  */
-  protected static IOutputConnector getConnector(IThreadContext threadContext, String className)
-    throws ManifoldCFException
-  {
-    IOutputConnectorManager connMgr = OutputConnectorManagerFactory.make(threadContext);
-    if (connMgr.isInstalled(className) == false)
-      return null;
-
-    try
-    {
-      Class theClass = ManifoldCF.findClass(className);
-      Class[] argumentClasses = new Class[0];
-      // Look for a constructor
-      Constructor c = theClass.getConstructor(argumentClasses);
-      Object[] arguments = new Object[0];
-      Object o = c.newInstance(arguments);
-      if (!(o instanceof IOutputConnector))
-        throw new ManifoldCFException("Class '"+className+"' does not implement IOutputConnector.");
-      return (IOutputConnector)o;
-    }
-    catch (InvocationTargetException e)
-    {
-      Throwable z = e.getTargetException();
-      if (z instanceof Error)
-        throw (Error)z;
-      else if (z instanceof RuntimeException)
-        throw (RuntimeException)z;
-      else
-        throw (ManifoldCFException)z;
-    }
-    catch (ClassNotFoundException e)
-    {
-      // This MAY mean that an existing connector has been uninstalled; check out this possibility!
-      // We return null because that is the signal that we cannot get a connector instance for that reason.
-      if (connMgr.isInstalled(className) == false)
-        return null;
-
-      throw new ManifoldCFException("No output connector class '"+className+"' was found.",
-        e);
-    }
-    catch (NoSuchMethodException e)
-    {
-      throw new ManifoldCFException("No appropriate constructor for IOutputConnector implementation '"+
-        className+"'.  Need xxx(ConfigParams).",
-        e);
-    }
-    catch (SecurityException e)
-    {
-      throw new ManifoldCFException("Protected constructor for IOutputConnector implementation '"+className+"'",
-        e);
-    }
-    catch (IllegalAccessException e)
-    {
-      throw new ManifoldCFException("Unavailable constructor for IOutputConnector implementation '"+className+"'",
-        e);
-    }
-    catch (IllegalArgumentException e)
-    {
-      throw new ManifoldCFException("Shouldn't happen!!!",e);
-    }
-    catch (InstantiationException e)
-    {
-      throw new ManifoldCFException("InstantiationException for IOutputConnector implementation '"+className+"'",
-        e);
-    }
-    catch (ExceptionInInitializerError e)
-    {
-      throw new ManifoldCFException("ExceptionInInitializerError for IOutputConnector implementation '"+className+"'",
-        e);
-    }
-
+    return thisFactory.getThisConnectorNoCheck(className);
   }
 
   /** Get multiple output connectors, all at once.  Do this in a particular order
@@ -275,54 +141,7 @@ public class OutputConnectorFactory
     String[] orderingKeys, String[] classNames, ConfigParams[] configInfos, int[] maxPoolSizes)
     throws ManifoldCFException
   {
-    IOutputConnector[] rval = new IOutputConnector[classNames.length];
-    HashMap orderMap = new HashMap();
-    int i = 0;
-    while (i < orderingKeys.length)
-    {
-      if (orderMap.get(orderingKeys[i]) != null)
-        throw new ManifoldCFException("Found duplicate order key");
-      orderMap.put(orderingKeys[i],new Integer(i));
-      i++;
-    }
-    java.util.Arrays.sort(orderingKeys);
-    i = 0;
-    while (i < orderingKeys.length)
-    {
-      String orderingKey = orderingKeys[i];
-      int index = ((Integer)orderMap.get(orderingKey)).intValue();
-      String className = classNames[index];
-      ConfigParams cp = configInfos[index];
-      int maxPoolSize = maxPoolSizes[index];
-      try
-      {
-        IOutputConnector connector = grab(threadContext,className,cp,maxPoolSize);
-        rval[index] = connector;
-      }
-      catch (Throwable e)
-      {
-        while (i > 0)
-        {
-          i--;
-          orderingKey = orderingKeys[i];
-          index = ((Integer)orderMap.get(orderingKey)).intValue();
-          try
-          {
-            release(rval[index]);
-          }
-          catch (ManifoldCFException e2)
-          {
-          }
-        }
-        if (e instanceof ManifoldCFException)
-          throw (ManifoldCFException)e;
-        else if (e instanceof RuntimeException)
-          throw (RuntimeException)e;
-        throw (Error)e;
-      }
-      i++;
-    }
-    return rval;
+    return thisFactory.grabThisMultiple(threadContext,orderingKeys,classNames,configInfos,maxPoolSizes);
   }
 
   /** Get an output connector.
@@ -336,29 +155,7 @@ public class OutputConnectorFactory
     String className, ConfigParams configInfo, int maxPoolSize)
     throws ManifoldCFException
   {
-    // We want to get handles off the pool and use them.  But the
-    // handles we fetch have to have the right config information.
-
-    // Use the classname and config info to build a pool key.  This
-    // key will be discarded if we actually have to save a key persistently,
-    // since we avoid copying the configInfo unnecessarily.
-    PoolKey pk = new PoolKey(className,configInfo);
-    Pool p;
-    synchronized (poolHash)
-    {
-      p = (Pool)poolHash.get(pk);
-      if (p == null)
-      {
-        pk = new PoolKey(className,configInfo.duplicate());
-        p = new Pool(pk,maxPoolSize);
-        poolHash.put(pk,p);
-      }
-    }
-
-    IOutputConnector rval = p.getConnector(threadContext);
-
-    return rval;
-
+    return thisFactory.grabThis(threadContext,className,configInfo,maxPoolSize);
   }
 
   /** Release multiple output connectors.
@@ -366,23 +163,7 @@ public class OutputConnectorFactory
   public static void releaseMultiple(IOutputConnector[] connectors)
     throws ManifoldCFException
   {
-    int i = 0;
-    ManifoldCFException currentException = null;
-    while (i < connectors.length)
-    {
-      IOutputConnector c = connectors[i++];
-      try
-      {
-        release(c);
-      }
-      catch (ManifoldCFException e)
-      {
-        if (currentException == null)
-          currentException = e;
-      }
-    }
-    if (currentException != null)
-      throw currentException;
+    thisFactory.releaseThisMultiple(connectors);
   }
 
   /** Release an output connector.
@@ -391,25 +172,7 @@ public class OutputConnectorFactory
   public static void release(IOutputConnector connector)
     throws ManifoldCFException
   {
-    // If the connector is null, skip the release, because we never really got the connector in the first place.
-    if (connector == null)
-      return;
-
-    // Figure out which pool this goes on, and put it there
-    PoolKey pk = new PoolKey(connector.getClass().getName(),connector.getConfiguration());
-    Pool p;
-    synchronized (poolHash)
-    {
-      p = (Pool)poolHash.get(pk);
-    }
-
-    p.releaseConnector(connector);
-
-    // synchronized (checkedOutConnectors)
-    // {
-    //      checkedOutConnectors.remove(connector.toString());
-    // }
-
+    thisFactory.releaseThis(connector);
   }
 
   /** Idle notification for inactive output connector handles.
@@ -418,21 +181,7 @@ public class OutputConnectorFactory
   public static void pollAllConnectors(IThreadContext threadContext)
     throws ManifoldCFException
   {
-    // System.out.println("Pool stats:");
-
-    // Go through the whole pool and notify everyone
-    synchronized (poolHash)
-    {
-      Iterator iter = poolHash.values().iterator();
-      while (iter.hasNext())
-      {
-        Pool p = (Pool)iter.next();
-        p.pollAll(threadContext);
-      }
-    }
-
-    // System.out.println("About to check if any output connector instances have been abandoned...");
-    // checkConnectors(System.currentTimeMillis());
+    thisFactory.pollThisAllConnectors(threadContext);
   }
 
   /** Clean up all open output connector handles.
@@ -443,256 +192,7 @@ public class OutputConnectorFactory
   public static void closeAllConnectors(IThreadContext threadContext)
     throws ManifoldCFException
   {
-    // Go through the whole pool and clean it out
-    synchronized (poolHash)
-    {
-      Iterator iter = poolHash.values().iterator();
-      while (iter.hasNext())
-      {
-        Pool p = (Pool)iter.next();
-        p.releaseAll(threadContext);
-      }
-    }
-  }
-
-  /** This is an immutable pool key class, which describes a pool in terms of two independent keys.
-  */
-  public static class PoolKey
-  {
-    protected String className;
-    protected ConfigParams configInfo;
-
-    /** Constructor.
-    */
-    public PoolKey(String className, Map configInfo)
-    {
-      this.className = className;
-      this.configInfo = new ConfigParams(configInfo);
-    }
-
-    public PoolKey(String className, ConfigParams configInfo)
-    {
-      this.className = className;
-      this.configInfo = configInfo;
-    }
-
-    /** Get the class name.
-    *@return the class name.
-    */
-    public String getClassName()
-    {
-      return className;
-    }
-
-    /** Get the config info.
-    *@return the params
-    */
-    public ConfigParams getParams()
-    {
-      return configInfo;
-    }
-
-    /** Hash code.
-    */
-    public int hashCode()
-    {
-      return className.hashCode() + configInfo.hashCode();
-    }
-
-    /** Equals operator.
-    */
-    public boolean equals(Object o)
-    {
-      if (!(o instanceof PoolKey))
-        return false;
-
-      PoolKey pk = (PoolKey)o;
-      return pk.className.equals(className) && pk.configInfo.equals(configInfo);
-    }
-
-  }
-
-  /** This class represents a value in the pool hash, which corresponds to a given key.
-  */
-  public static class Pool
-  {
-    protected ArrayList stack = new ArrayList();
-    protected PoolKey key;
-    protected int numFree;
-
-    /** Constructor
-    */
-    public Pool(PoolKey pk, int maxCount)
-    {
-      key = pk;
-      numFree = maxCount;
-    }
-
-    /** Grab an output connector.
-    * If none exists, construct it using the information in the pool key.
-    *@return the connector, or null if no connector could be connected.
-    */
-    public synchronized IOutputConnector getConnector(IThreadContext threadContext)
-      throws ManifoldCFException
-    {
-      while (numFree == 0)
-      {
-        try
-        {
-          wait();
-        }
-        catch (InterruptedException e)
-        {
-          throw new ManifoldCFException("Interrupted: "+e.getMessage(),e,ManifoldCFException.INTERRUPTED);
-        }
-      }
-
-      if (stack.size() == 0)
-      {
-        String className = key.getClassName();
-        ConfigParams configParams = key.getParams();
-
-        IOutputConnectorManager connMgr = OutputConnectorManagerFactory.make(threadContext);
-        if (connMgr.isInstalled(className) == false)
-          return null;
-
-        try
-        {
-          Class theClass = ManifoldCF.findClass(className);
-          Class[] argumentClasses = new Class[0];
-          // Look for a constructor
-          Constructor c = theClass.getConstructor(argumentClasses);
-          Object[] arguments = new Object[0];
-          Object o = c.newInstance(arguments);
-          if (!(o instanceof IOutputConnector))
-            throw new ManifoldCFException("Class '"+className+"' does not implement IOutputConnector.");
-          IOutputConnector newrc = (IOutputConnector)o;
-          newrc.connect(configParams);
-          stack.add(newrc);
-        }
-        catch (InvocationTargetException e)
-        {
-          Throwable z = e.getTargetException();
-          if (z instanceof Error)
-            throw (Error)z;
-          else if (z instanceof RuntimeException)
-            throw (RuntimeException)z;
-          else
-            throw (ManifoldCFException)z;
-        }
-        catch (ClassNotFoundException e)
-        {
-          // If we see this exception, it COULD mean that the connector was uninstalled, and we happened to get here
-          // after that occurred.
-          // We return null because that is the signal that we cannot get a connector instance for that reason.
-          if (connMgr.isInstalled(className) == false)
-            return null;
-
-          throw new ManifoldCFException("No output connector class '"+className+"' was found.",
-            e);
-        }
-        catch (NoSuchMethodException e)
-        {
-          throw new ManifoldCFException("No appropriate constructor for IOutputConnector implementation '"+
-            className+"'.  Need xxx(ConfigParams).",
-            e);
-        }
-        catch (SecurityException e)
-        {
-          throw new ManifoldCFException("Protected constructor for IOutputConnector implementation '"+className+"'",
-            e);
-        }
-        catch (IllegalAccessException e)
-        {
-          throw new ManifoldCFException("Unavailable constructor for IOutputConnector implementation '"+className+"'",
-            e);
-        }
-        catch (IllegalArgumentException e)
-        {
-          throw new ManifoldCFException("Shouldn't happen!!!",e);
-        }
-        catch (InstantiationException e)
-        {
-          throw new ManifoldCFException("InstantiationException for IOutputConnector implementation '"+className+"'",
-            e);
-        }
-        catch (ExceptionInInitializerError e)
-        {
-          throw new ManifoldCFException("ExceptionInInitializerError for IOutputConnector implementation '"+className+"'",
-            e);
-        }
-      }
-      
-      // Since thread context set can fail, do that before we remove it from the pool.
-      IOutputConnector rc = (IOutputConnector)stack.get(stack.size()-1);
-      rc.setThreadContext(threadContext);
-      stack.remove(stack.size()-1);
-      numFree--;
-      
-      return rc;
-    }
-
-    /** Release an output connector to the pool.
-    *@param connector is the connector.
-    */
-    public synchronized void releaseConnector(IOutputConnector connector)
-      throws ManifoldCFException
-    {
-      if (connector == null)
-        return;
-
-      // Make sure connector knows it's released
-      connector.clearThreadContext();
-      // Append
-      stack.add(connector);
-      numFree++;
-      notifyAll();
-    }
-
-    /** Notify all free connectors.
-    */
-    public synchronized void pollAll(IThreadContext threadContext)
-      throws ManifoldCFException
-    {
-      int i = 0;
-      while (i < stack.size())
-      {
-        IConnector rc = (IConnector)stack.get(i++);
-        // Notify
-        rc.setThreadContext(threadContext);
-        try
-        {
-          rc.poll();
-        }
-        finally
-        {
-          rc.clearThreadContext();
-        }
-      }
-    }
-
-    /** Release all free connectors.
-    */
-    public synchronized void releaseAll(IThreadContext threadContext)
-      throws ManifoldCFException
-    {
-      while (stack.size() > 0)
-      {
-        // Disconnect
-        IConnector rc = (IConnector)stack.get(stack.size()-1);
-        rc.setThreadContext(threadContext);
-        try
-        {
-          rc.disconnect();
-          stack.remove(stack.size()-1);
-        }
-        finally
-        {
-          rc.clearThreadContext();
-        }
-      }
-    }
-
+    thisFactory.closeThisAllConnectors(threadContext);
   }
 
 }

Modified: manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ConnectorFactory.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ConnectorFactory.java?rev=1547391&r1=1547390&r2=1547391&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ConnectorFactory.java (original)
+++ manifoldcf/branches/CONNECTORS-781/framework/core/src/main/java/org/apache/manifoldcf/core/interfaces/ConnectorFactory.java Tue Dec  3 13:59:19 2013
@@ -26,45 +26,45 @@ import java.lang.reflect.*;
 
 /** This is the base factory class for all IConnector objects.
 */
-public class ConnectorFactory
+public abstract class ConnectorFactory<T extends IConnector>
 {
   public static final String _rcsid = "@(#)$Id: OutputConnectorFactory.java 988245 2010-08-23 18:39:35Z kwright $";
 
   // Pool hash table.
   // Keyed by PoolKey; value is Pool
-  protected final static Map<PoolKey,Pool> poolHash = new HashMap<PoolKey,Pool>();
+  protected final Map<PoolKey,Pool> poolHash = new HashMap<PoolKey,Pool>();
 
-  private ConnectorFactory()
+  protected ConnectorFactory()
   {
   }
 
   /** Install connector.
   *@param className is the class name.
   */
-  public static void install(IThreadContext threadContext, String className)
+  protected void installThis(IThreadContext threadContext, String className)
     throws ManifoldCFException
   {
-    IConnector connector = getConnectorNoCheck(className);
+    T connector = getThisConnectorNoCheck(className);
     connector.install(threadContext);
   }
 
   /** Uninstall connector.
   *@param className is the class name.
   */
-  public static void deinstall(IThreadContext threadContext, String className)
+  protected void deinstallThis(IThreadContext threadContext, String className)
     throws ManifoldCFException
   {
-    IConnector connector = getConnectorNoCheck(className);
+    T connector = getThisConnectorNoCheck(className);
     connector.deinstall(threadContext);
   }
 
   /** Output the configuration header section.
   */
-  public static void outputConfigurationHeader(IThreadContext threadContext, String className,
+  protected void outputThisConfigurationHeader(IThreadContext threadContext, String className,
     IHTTPOutput out, Locale locale, ConfigParams parameters, ArrayList tabsArray)
     throws ManifoldCFException, IOException
   {
-    IConnector connector = getConnector(threadContext, className);
+    T connector = getThisConnector(threadContext, className);
     if (connector == null)
       return;
     connector.outputConfigurationHeader(threadContext,out,locale,parameters,tabsArray);
@@ -72,11 +72,11 @@ public class ConnectorFactory
 
   /** Output the configuration body section.
   */
-  public static void outputConfigurationBody(IThreadContext threadContext, String className,
+  protected void outputThisConfigurationBody(IThreadContext threadContext, String className,
     IHTTPOutput out, Locale locale, ConfigParams parameters, String tabName)
     throws ManifoldCFException, IOException
   {
-    IConnector connector = getConnector(threadContext, className);
+    T connector = getThisConnector(threadContext, className);
     if (connector == null)
       return;
     connector.outputConfigurationBody(threadContext,out,locale,parameters,tabName);
@@ -84,11 +84,11 @@ public class ConnectorFactory
 
   /** Process configuration post data for a connector.
   */
-  public static String processConfigurationPost(IThreadContext threadContext, String className,
+  protected String processThisConfigurationPost(IThreadContext threadContext, String className,
     IPostParameters variableContext, Locale locale, ConfigParams configParams)
     throws ManifoldCFException
   {
-    IConnector connector = getConnector(threadContext, className);
+    T connector = getThisConnector(threadContext, className);
     if (connector == null)
       return null;
     return connector.processConfigurationPost(threadContext,variableContext,locale,configParams);
@@ -96,11 +96,11 @@ public class ConnectorFactory
   
   /** View connector configuration.
   */
-  public static void viewConfiguration(IThreadContext threadContext, String className,
+  protected void viewThisConfiguration(IThreadContext threadContext, String className,
     IHTTPOutput out, Locale locale, ConfigParams configParams)
     throws ManifoldCFException, IOException
   {
-    IConnector connector = getConnector(threadContext, className);
+    T connector = getThisConnector(threadContext, className);
     // We want to be able to view connections even if they have unregistered connectors.
     if (connector == null)
       return;
@@ -111,7 +111,7 @@ public class ConnectorFactory
   *@param className is the class name.
   *@return the instance.
   */
-  public static IConnector getConnectorNoCheck(String className)
+  protected T getThisConnectorNoCheck(String className)
     throws ManifoldCFException
   {
     try
@@ -122,9 +122,14 @@ public class ConnectorFactory
       Constructor c = theClass.getConstructor(argumentClasses);
       Object[] arguments = new Object[0];
       Object o = c.newInstance(arguments);
-      if (!(o instanceof IConnector))
+      try
+      {
+        return (T)o;
+      }
+      catch (ClassCastException e)
+      {
         throw new ManifoldCFException("Class '"+className+"' does not implement IConnector.");
-      return (IConnector)o;
+      }
     }
     catch (InvocationTargetException e)
     {
@@ -180,17 +185,14 @@ public class ConnectorFactory
   
   /** Override this method to hook into a connector manager.
   */
-  protected static boolean isInstalled(IThreadContext tc, String className)
-    throws ManifoldCFException
-  {
-    return false;
-  }
+  protected abstract boolean isInstalled(IThreadContext tc, String className)
+    throws ManifoldCFException;
   
   /** Get a connector instance.
   *@param className is the class name.
   *@return the instance.
   */
-  protected static IConnector getConnector(IThreadContext threadContext, String className)
+  protected T getThisConnector(IThreadContext threadContext, String className)
     throws ManifoldCFException
   {
     if (!isInstalled(threadContext,className))
@@ -204,9 +206,14 @@ public class ConnectorFactory
       Constructor c = theClass.getConstructor(argumentClasses);
       Object[] arguments = new Object[0];
       Object o = c.newInstance(arguments);
-      if (!(o instanceof IConnector))
+      try
+      {
+        return (T)o;
+      }
+      catch (ClassCastException e)
+      {
         throw new ManifoldCFException("Class '"+className+"' does not implement IConnector.");
-      return (IConnector)o;
+      }
     }
     catch (InvocationTargetException e)
     {
@@ -266,11 +273,11 @@ public class ConnectorFactory
   /** Get multiple connectors, all at once.  Do this in a particular order
   * so that any connector exhaustion will not cause a deadlock.
   */
-  public static IConnector[] grabMultiple(IThreadContext threadContext,
+  protected T[] grabThisMultiple(IThreadContext threadContext,
     String[] orderingKeys, String[] classNames, ConfigParams[] configInfos, int[] maxPoolSizes)
     throws ManifoldCFException
   {
-    IConnector[] rval = new IConnector[classNames.length];
+    T[] rval = (T[])new IConnector[classNames.length];
     Map<String,Integer> orderMap = new HashMap<String,Integer>();
     for (int i = 0; i < orderingKeys.length; i++)
     {
@@ -288,7 +295,7 @@ public class ConnectorFactory
       int maxPoolSize = maxPoolSizes[index];
       try
       {
-        IConnector connector = grab(threadContext,className,cp,maxPoolSize);
+        T connector = grabThis(threadContext,className,cp,maxPoolSize);
         rval[index] = connector;
       }
       catch (Throwable e)
@@ -300,7 +307,7 @@ public class ConnectorFactory
           index = orderMap.get(orderingKey).intValue();
           try
           {
-            release(rval[index]);
+            releaseThis(rval[index]);
           }
           catch (ManifoldCFException e2)
           {
@@ -326,7 +333,7 @@ public class ConnectorFactory
   *@param configInfo are the name/value pairs constituting configuration info
   * for this class.
   */
-  public static IConnector grab(IThreadContext threadContext,
+  protected T grabThis(IThreadContext threadContext,
     String className, ConfigParams configInfo, int maxPoolSize)
     throws ManifoldCFException
   {
@@ -337,19 +344,19 @@ public class ConnectorFactory
     // key will be discarded if we actually have to save a key persistently,
     // since we avoid copying the configInfo unnecessarily.
     PoolKey pk = new PoolKey(className,configInfo);
-    Pool p;
+    Pool<T> p;
     synchronized (poolHash)
     {
       p = poolHash.get(pk);
       if (p == null)
       {
         pk = new PoolKey(className,configInfo.duplicate());
-        p = new Pool(pk,maxPoolSize);
+        p = new Pool<T>(pk,maxPoolSize);
         poolHash.put(pk,p);
       }
     }
 
-    IConnector rval = p.getConnector(threadContext);
+    T rval = p.getConnector(threadContext);
 
     return rval;
 
@@ -357,17 +364,17 @@ public class ConnectorFactory
 
   /** Release multiple output connectors.
   */
-  public static void releaseMultiple(IConnector[] connectors)
+  protected void releaseThisMultiple(T[] connectors)
     throws ManifoldCFException
   {
     int i = 0;
     ManifoldCFException currentException = null;
     while (i < connectors.length)
     {
-      IConnector c = connectors[i++];
+      T c = connectors[i++];
       try
       {
-        release(c);
+        releaseThis(c);
       }
       catch (ManifoldCFException e)
       {
@@ -382,7 +389,7 @@ public class ConnectorFactory
   /** Release an output connector.
   *@param connector is the connector to release.
   */
-  public static void release(IConnector connector)
+  protected void releaseThis(T connector)
     throws ManifoldCFException
   {
     // If the connector is null, skip the release, because we never really got the connector in the first place.
@@ -409,7 +416,7 @@ public class ConnectorFactory
   /** Idle notification for inactive output connector handles.
   * This method polls all inactive handles.
   */
-  public static void pollAllConnectors(IThreadContext threadContext)
+  protected void pollThisAllConnectors(IThreadContext threadContext)
     throws ManifoldCFException
   {
     // System.out.println("Pool stats:");
@@ -434,7 +441,7 @@ public class ConnectorFactory
   * to free resources.
   *@param threadContext is the local thread context.
   */
-  public static void closeAllConnectors(IThreadContext threadContext)
+  protected void closeThisAllConnectors(IThreadContext threadContext)
     throws ManifoldCFException
   {
     // Go through the whole pool and clean it out
@@ -508,9 +515,9 @@ public class ConnectorFactory
 
   /** This class represents a value in the pool hash, which corresponds to a given key.
   */
-  public static class Pool
+  public class Pool<T extends IConnector>
   {
-    protected final List<IConnector> stack = new ArrayList<IConnector>();
+    protected final List<T> stack = new ArrayList<T>();
     protected final PoolKey key;
     protected int numFree;
 
@@ -526,7 +533,7 @@ public class ConnectorFactory
     * If none exists, construct it using the information in the pool key.
     *@return the connector, or null if no connector could be connected.
     */
-    public synchronized IConnector getConnector(IThreadContext threadContext)
+    public synchronized T getConnector(IThreadContext threadContext)
       throws ManifoldCFException
     {
       while (numFree == 0)
@@ -557,9 +564,15 @@ public class ConnectorFactory
           Constructor c = theClass.getConstructor(argumentClasses);
           Object[] arguments = new Object[0];
           Object o = c.newInstance(arguments);
-          if (!(o instanceof IConnector))
+          T newrc;
+          try
+          {
+            newrc = (T)o;
+          }
+          catch (ClassCastException e)
+          {
             throw new ManifoldCFException("Class '"+className+"' does not implement IConnector.");
-          IConnector newrc = (IConnector)o;
+          }
           newrc.connect(configParams);
           stack.add(newrc);
         }
@@ -619,7 +632,7 @@ public class ConnectorFactory
       }
       
       // Since thread context set can fail, do that before we remove it from the pool.
-      IConnector rc = (IConnector)stack.get(stack.size()-1);
+      T rc = stack.get(stack.size()-1);
       rc.setThreadContext(threadContext);
       stack.remove(stack.size()-1);
       numFree--;
@@ -630,7 +643,7 @@ public class ConnectorFactory
     /** Release a connector to the pool.
     *@param connector is the connector.
     */
-    public synchronized void releaseConnector(IConnector connector)
+    public synchronized void releaseConnector(T connector)
       throws ManifoldCFException
     {
       if (connector == null)
@@ -652,7 +665,7 @@ public class ConnectorFactory
       int i = 0;
       while (i < stack.size())
       {
-        IConnector rc = (IConnector)stack.get(i++);
+        T rc = stack.get(i++);
         // Notify
         rc.setThreadContext(threadContext);
         try
@@ -674,7 +687,7 @@ public class ConnectorFactory
       while (stack.size() > 0)
       {
         // Disconnect
-        IConnector rc = stack.get(stack.size()-1);
+        T rc = stack.get(stack.size()-1);
         rc.setThreadContext(threadContext);
         try
         {