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 2014/05/30 13:31:55 UTC

svn commit: r1598556 [1/2] - in /manifoldcf/branches/CONNECTORS-946/framework: agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/ agents/src/main/java/org/apache/manifoldcf/...

Author: kwright
Date: Fri May 30 11:31:55 2014
New Revision: 1598556

URL: http://svn.apache.org/r1598556
Log:
Add database tables and managers supporting transformation connectors

Added:
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnection.java   (with props)
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectionManager.java   (with props)
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectorManager.java   (with props)
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectionManagerFactory.java   (with props)
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorFactory.java   (with props)
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorManagerFactory.java   (with props)
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnection.java   (with props)
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnectionManager.java   (with props)
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnmgr/
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnmgr/TransformationConnectorManager.java   (with props)
Modified:
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/AgentManagerFactory.java
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/CacheKeyFactory.java
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IAgent.java
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java
    manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java
    manifoldcf/branches/CONNECTORS-946/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/CrawlerAgent.java
    manifoldcf/branches/CONNECTORS-946/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java

Modified: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/AgentManagerFactory.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/AgentManagerFactory.java?rev=1598556&r1=1598555&r2=1598556&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/AgentManagerFactory.java (original)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/AgentManagerFactory.java Fri May 30 11:31:55 2014
@@ -125,6 +125,77 @@ public class AgentManagerFactory
     }
   }
 
+    /** Request permission from all registered agents to delete a transformation connection.
+  *@param threadContext is the thread context.
+  *@param connName is the name of the output connection.
+  *@return true if the connection is in use, false otherwise.
+  */
+  public static boolean isTransformationConnectionInUse(IThreadContext threadContext, String connName)
+    throws ManifoldCFException
+  {
+    // Instantiate the list of IAgent objects
+    IAgent[] theAgents = instantiateAllAgents(threadContext);
+    int i = 0;
+    while (i < theAgents.length)
+    {
+      if (theAgents[i++].isTransformationConnectionInUse(threadContext, connName))
+        return true;
+    }
+    return false;
+  }
+
+  /**  Note to all registered agents the deregistration of a transformation connector used by the specified connections.
+  * This method will be called when the connector is deregistered.
+  *@param threadContext is the thread context.
+  *@param connectionNames is the set of connection names.
+  */
+  public static void noteTransformationConnectorDeregistration(IThreadContext threadContext, String[] connectionNames)
+    throws ManifoldCFException
+  {
+    // Instantiate the list of IAgent objects
+    IAgent[] theAgents = instantiateAllAgents(threadContext);
+    int i = 0;
+    while (i < theAgents.length)
+    {
+      theAgents[i++].noteTransformationConnectorDeregistration(threadContext, connectionNames);
+    }
+  }
+
+  /** Note to all registered agents the registration of a transformation connector used by the specified connections.
+  * This method will be called when a connector is registered, on which the specified
+  * connections depend.
+  *@param threadContext is the thread context.
+  *@param connectionNames is the set of connection names.
+  */
+  public static void noteTransformationConnectorRegistration(IThreadContext threadContext, String[] connectionNames)
+    throws ManifoldCFException
+  {
+    // Instantiate the list of IAgent objects
+    IAgent[] theAgents = instantiateAllAgents(threadContext);
+    int i = 0;
+    while (i < theAgents.length)
+    {
+      theAgents[i++].noteTransformationConnectorRegistration(threadContext, connectionNames);
+    }
+  }
+
+  /** Note to all registered agents the change of configuration of a transformation connection.
+  * This method will be called when the connection's xml is modified.
+  *@param threadContext is the thread context.
+  *@param connectionName is the connection name.
+  */
+  public static void noteTransformationConnectionChange(IThreadContext threadContext, String connectionName)
+    throws ManifoldCFException
+  {
+    // Instantiate the list of IAgent objects
+    IAgent[] theAgents = instantiateAllAgents(threadContext);
+    int i = 0;
+    while (i < theAgents.length)
+    {
+      theAgents[i++].noteTransformationConnectionChange(threadContext, connectionName);
+    }
+  }
+
   /** Instantiate the complete set of IAgent objects.
   *@param threadContext is the thread context.
   *@return the array of such objects.

Modified: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/CacheKeyFactory.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/CacheKeyFactory.java?rev=1598556&r1=1598555&r2=1598556&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/CacheKeyFactory.java (original)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/CacheKeyFactory.java Fri May 30 11:31:55 2014
@@ -46,4 +46,21 @@ public class CacheKeyFactory extends org
     return "OUTPUTCONNECTION_"+connectionName;
   }
 
+  /** Construct a key which represents the general list of transformation connectors.
+  *@return the cache key.
+  */
+  public static String makeTransformationConnectionsKey()
+  {
+    return "TRANSCONNECTIONS";
+  }
+
+  /** Construct a key which represents an individual transformation connection.
+  *@param connectionName is the name of the connector.
+  *@return the cache key.
+  */
+  public static String makeTransformationConnectionKey(String connectionName)
+  {
+    return "TRANSCONNECTION_"+connectionName;
+  }
+
 }

Modified: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IAgent.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IAgent.java?rev=1598556&r1=1598555&r2=1598556&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IAgent.java (original)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/IAgent.java Fri May 30 11:31:55 2014
@@ -122,5 +122,30 @@ public interface IAgent
   */
   public void noteOutputConnectionChange(IThreadContext threadContext, String connectionName)
     throws ManifoldCFException;
-  
+
+  /** Request permission from agent to delete a transformation connection.
+  *@param connName is the name of the transformation connection.
+  *@return true if the connection is in use, false otherwise.
+  */
+  public boolean isTransformationConnectionInUse(IThreadContext threadContext, String connName)
+    throws ManifoldCFException;
+
+  /** Note the deregistration of a set of transformation connections.
+  *@param connectionNames are the names of the connections being deregistered.
+  */
+  public void noteTransformationConnectorDeregistration(IThreadContext threadContext, String[] connectionNames)
+    throws ManifoldCFException;
+
+  /** Note the registration of a set of transformation connections.
+  *@param connectionNames are the names of the connections being registered.
+  */
+  public void noteTransformationConnectorRegistration(IThreadContext threadContext, String[] connectionNames)
+    throws ManifoldCFException;
+
+  /** Note a change in configuration for a transformation connection.
+  *@param connectionName is the name of the connection being changed.
+  */
+  public void noteTransformationConnectionChange(IThreadContext threadContext, String connectionName)
+    throws ManifoldCFException;
+
 }

Added: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnection.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnection.java?rev=1598556&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnection.java (added)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnection.java Fri May 30 11:31:55 2014
@@ -0,0 +1,85 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.manifoldcf.agents.interfaces;
+
+import org.apache.manifoldcf.core.interfaces.*;
+
+/** An instance of this interface represents a paper object that describes a transformation connection.
+* This is the paper object meant for editing and manipulation.
+*/
+public interface ITransformationConnection
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  /** Set 'isnew' condition.
+  *@param isnew true if this is a new instance.
+  */
+  public void setIsNew(boolean isnew);
+  
+  /** Get 'isnew' condition.
+  *@return true if this is a new connection, false otherwise.
+  */
+  public boolean getIsNew();
+  
+  /** Set name.
+  *@param name is the name.
+  */
+  public void setName(String name);
+
+  /** Get name.
+  *@return the name
+  */
+  public String getName();
+
+  /** Set description.
+  *@param description is the description.
+  */
+  public void setDescription(String description);
+
+  /** Get description.
+  *@return the description
+  */
+  public String getDescription();
+
+  /** Set the class name.
+  *@param className is the class name.
+  */
+  public void setClassName(String className);
+
+  /** Get the class name.
+  *@return the class name
+  */
+  public String getClassName();
+
+  /** Get the configuration parameters.
+  *@return the map.  Can be modified.
+  */
+  public ConfigParams getConfigParams();
+
+  /** Set the maximum size of the connection pool.
+  *@param maxCount is the maximum connection count per JVM.
+  */
+  public void setMaxConnections(int maxCount);
+
+  /** Get the maximum size of the connection pool.
+  *@return the maximum size.
+  */
+  public int getMaxConnections();
+
+}

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnection.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectionManager.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectionManager.java?rev=1598556&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectionManager.java (added)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectionManager.java Fri May 30 11:31:55 2014
@@ -0,0 +1,114 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.manifoldcf.agents.interfaces;
+
+import org.apache.manifoldcf.core.interfaces.*;
+
+/** Manager classes of this kind use the database to contain a human description of a transformation connection.
+*/
+public interface ITransformationConnectionManager
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  /** Install the manager.
+  */
+  public void install()
+    throws ManifoldCFException;
+
+  /** Uninstall the manager.
+  */
+  public void deinstall()
+    throws ManifoldCFException;
+
+  /** Export configuration */
+  public void exportConfiguration(java.io.OutputStream os)
+    throws java.io.IOException, ManifoldCFException;
+
+  /** Import configuration */
+  public void importConfiguration(java.io.InputStream is)
+    throws java.io.IOException, ManifoldCFException;
+
+  /** Obtain a list of the transformation connections, ordered by name.
+  *@return an array of connection objects.
+  */
+  public ITransformationConnection[] getAllConnections()
+    throws ManifoldCFException;
+
+  /** Load an transformation connection by name.
+  *@param name is the name of the transformation connection.
+  *@return the loaded connection object, or null if not found.
+  */
+  public ITransformationConnection load(String name)
+    throws ManifoldCFException;
+
+  /** Load a set of transformation connections.
+  *@param names are the names of the transformation connections.
+  *@return the descriptors of the transformation connections, with null
+  * values for those not found.
+  */
+  public ITransformationConnection[] loadMultiple(String[] names)
+    throws ManifoldCFException;
+
+  /** Create a new transformation connection object.
+  *@return the new object.
+  */
+  public ITransformationConnection create()
+    throws ManifoldCFException;
+
+  /** Save a transformation connection object.
+  *@param object is the object to save.
+  *@return true if the object was created, false otherwise.
+  */
+  public boolean save(ITransformationConnection object)
+    throws ManifoldCFException;
+
+  /** Delete a transformation connection.
+  *@param name is the name of the connection to delete.  If the
+  * name does not exist, no error is returned.
+  */
+  public void delete(String name)
+    throws ManifoldCFException;
+
+  /** Get a list of transformation connections that share the same connector.
+  *@param className is the class name of the connector.
+  *@return the transformation connections that use that connector.
+  */
+  public String[] findConnectionsForConnector(String className)
+    throws ManifoldCFException;
+
+  /** Check if underlying connector exists.
+  *@param name is the name of the connection to check.
+  *@return true if the underlying connector is registered.
+  */
+  public boolean checkConnectorExists(String name)
+    throws ManifoldCFException;
+
+  // Schema related
+
+  /** Return the primary table name.
+  *@return the table name.
+  */
+  public String getTableName();
+
+  /** Return the name column.
+  *@return the name column.
+  */
+  public String getConnectionNameColumn();
+
+}

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectionManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectionManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectorManager.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectorManager.java?rev=1598556&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectorManager.java (added)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectorManager.java Fri May 30 11:31:55 2014
@@ -0,0 +1,84 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.manifoldcf.agents.interfaces;
+
+import org.apache.manifoldcf.core.interfaces.*;
+
+/** This interface describes a manager for the registry of transformation connectors.
+* Use this to register or remove a connector from the list of available choices.
+*/
+public interface ITransformationConnectorManager
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  /** Install.
+  */
+  public void install()
+    throws ManifoldCFException;
+
+  /** Uninstall.  This also unregisters all connectors.
+  */
+  public void deinstall()
+    throws ManifoldCFException;
+
+  /** Register a new connector.
+  * The connector's install method will also be called.
+  *@param description is the description to use in the UI.
+  *@param className is the class name.
+  */
+  public void registerConnector(String description, String className)
+    throws ManifoldCFException;
+
+  /** Unregister a connector.
+  * The connector's deinstall method will also be called.
+  *@param className is the connector class to unregister.
+  */
+  public void unregisterConnector(String className)
+    throws ManifoldCFException;
+
+  /** Remove a connector.
+  * Use this method when the connector doesn't seem to be in the
+  * classpath, so deregistration cannot occur.
+  *@param className is the connector class to remove.
+  */
+  public void removeConnector(String className)
+    throws ManifoldCFException;
+
+  /** Get ordered list of connectors.
+  *@return a resultset with the columns "description" and "classname".
+  * These will be ordered by description.
+  */
+  public IResultSet getConnectors()
+    throws ManifoldCFException;
+
+  /** Get a description given a class name.
+  *@param className is the class name.
+  *@return the description, or null if the class is not registered.
+  */
+  public String getDescription(String className)
+    throws ManifoldCFException;
+
+  /** Check if a particular connector is installed or not.
+  *@param className is the class name of the connector.
+  *@return true if installed, false otherwise.
+  */
+  public boolean isInstalled(String className)
+    throws ManifoldCFException;
+
+}

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectorManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/ITransformationConnectorManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectionManagerFactory.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectionManagerFactory.java?rev=1598556&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectionManagerFactory.java (added)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectionManagerFactory.java Fri May 30 11:31:55 2014
@@ -0,0 +1,90 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.manifoldcf.agents.interfaces;
+
+import org.apache.manifoldcf.core.interfaces.*;
+import org.apache.manifoldcf.agents.system.ManifoldCF;
+
+import java.util.*;
+
+/** Transformation connection manager factory.
+*/
+public class TransformationConnectionManagerFactory
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  // name to use in thread context pool of objects
+  private final static String objectName = "_TransformationConnectionMgr_";
+
+  private TransformationConnectionManagerFactory()
+  {
+  }
+
+  /** Make a transformation connection manager handle.
+  *@param tc is the thread context.
+  *@return the handle.
+  */
+  public static ITransformationConnectionManager make(IThreadContext tc)
+    throws ManifoldCFException
+  {
+    Object o = tc.get(objectName);
+    if (o == null || !(o instanceof ITransformationConnectionManager))
+    {
+      IDBInterface database = DBInterfaceFactory.make(tc,
+        ManifoldCF.getMasterDatabaseName(),
+        ManifoldCF.getMasterDatabaseUsername(),
+        ManifoldCF.getMasterDatabasePassword());
+
+      o = new org.apache.manifoldcf.agents.transformationconnection.TransformationConnectionManager(tc,database);
+      tc.save(objectName,o);
+    }
+    return (ITransformationConnectionManager)o;
+  }
+
+  /** Compile a list of all pertinent activities, across all existing transformation connections.
+  *@param tc is the thread context.
+  *@return the sorted list of transformation connection activities.
+  */
+  public static String[] getAllTransformationActivities(IThreadContext tc)
+    throws ManifoldCFException
+  {
+    ITransformationConnectionManager manager = make(tc);
+    ITransformationConnection[] connections = manager.getAllConnections();
+    Set<String> map = new HashSet<String>();
+    for (ITransformationConnection connection : connections)
+    {
+      String connectionName = connection.getName();
+      String[] activities = TransformationConnectorFactory.getActivitiesList(tc,connection.getClassName());
+      for (String baseActivity : activities)
+      {
+        String activity = baseActivity + " ("+connectionName+")";
+        map.add(activity);
+      }
+    }
+    String[] rval = new String[map.size()];
+    int i = 0;
+    Iterator<String> iter = map.iterator();
+    while (iter.hasNext())
+    {
+      rval[i++] = iter.next();
+    }
+    java.util.Arrays.sort(rval);
+    return rval;
+  }
+}

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectionManagerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectionManagerFactory.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorFactory.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorFactory.java?rev=1598556&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorFactory.java (added)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorFactory.java Fri May 30 11:31:55 2014
@@ -0,0 +1,138 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.manifoldcf.agents.interfaces;
+
+import org.apache.manifoldcf.core.interfaces.*;
+import org.apache.manifoldcf.agents.system.ManifoldCF;
+
+import java.util.*;
+import java.io.*;
+import java.lang.reflect.*;
+
+/** This is the factory class for ITransformationConnector objects.
+*/
+public class TransformationConnectorFactory extends ConnectorFactory<ITransformationConnector>
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  // Static factory
+  protected final static TransformationConnectorFactory thisFactory = new TransformationConnectorFactory();
+
+  protected TransformationConnectorFactory()
+  {
+  }
+
+  @Override
+  protected boolean isInstalled(IThreadContext tc, String className)
+    throws ManifoldCFException
+  {
+    ITransformationConnectorManager connMgr = TransformationConnectorManagerFactory.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
+  {
+    ITransformationConnector connector = getThisConnector(threadContext, className);
+    if (connector == null)
+      return null;
+    String[] values = connector.getActivitiesList();
+    java.util.Arrays.sort(values);
+    return values;
+  }
+
+  /** Install connector.
+  *@param className is the class name.
+  */
+  public static void install(IThreadContext threadContext, String className)
+    throws ManifoldCFException
+  {
+    thisFactory.installThis(threadContext,className);
+  }
+
+  /** Uninstall connector.
+  *@param className is the class name.
+  */
+  public static void deinstall(IThreadContext threadContext, String className)
+    throws ManifoldCFException
+  {
+    thisFactory.deinstallThis(threadContext,className);
+  }
+
+  /** Get the activities supported by this connector.
+  *@param className is the class name.
+  *@return the list of activities.
+  */
+  public static String[] getActivitiesList(IThreadContext threadContext, String className)
+    throws ManifoldCFException
+  {
+    return thisFactory.getThisActivitiesList(threadContext,className);
+  }
+
+  /** Output the configuration header section.
+  */
+  public static void outputConfigurationHeader(IThreadContext threadContext, String className,
+    IHTTPOutput out, Locale locale, ConfigParams parameters, ArrayList tabsArray)
+    throws ManifoldCFException, IOException
+  {
+    thisFactory.outputThisConfigurationHeader(threadContext,className,out,locale,parameters,tabsArray);
+  }
+
+  /** Output the configuration body section.
+  */
+  public static void outputConfigurationBody(IThreadContext threadContext, String className,
+    IHTTPOutput out, Locale locale, ConfigParams parameters, String tabName)
+    throws ManifoldCFException, IOException
+  {
+    thisFactory.outputThisConfigurationBody(threadContext,className,out,locale,parameters,tabName);
+  }
+
+  /** Process configuration post data for a connector.
+  */
+  public static String processConfigurationPost(IThreadContext threadContext, String className,
+    IPostParameters variableContext, Locale locale, ConfigParams configParams)
+    throws ManifoldCFException
+  {
+    return thisFactory.processThisConfigurationPost(threadContext,className,variableContext,locale,configParams);
+  }
+  
+  /** View connector configuration.
+  */
+  public static void viewConfiguration(IThreadContext threadContext, String className,
+    IHTTPOutput out, Locale locale, ConfigParams configParams)
+    throws ManifoldCFException, IOException
+  {
+    thisFactory.viewThisConfiguration(threadContext,className,out,locale,configParams);
+  }
+
+  /** Get an output connector instance, without checking for installed connector.
+  *@param className is the class name.
+  *@return the instance.
+  */
+  public static ITransformationConnector getConnectorNoCheck(String className)
+    throws ManifoldCFException
+  {
+    return thisFactory.getThisConnectorNoCheck(className);
+  }
+
+}

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorFactory.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorManagerFactory.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorManagerFactory.java?rev=1598556&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorManagerFactory.java (added)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorManagerFactory.java Fri May 30 11:31:55 2014
@@ -0,0 +1,58 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.manifoldcf.agents.interfaces;
+
+import org.apache.manifoldcf.core.interfaces.*;
+import org.apache.manifoldcf.agents.system.*;
+
+/** Factory for transformation connector manager.
+*/
+public class TransformationConnectorManagerFactory
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  protected static final String connMgr = "_TransformationConnectorManager_";
+
+  private TransformationConnectorManagerFactory()
+  {
+  }
+
+  /** Construct an output connector manager.
+  *@param tc is the thread context.
+  *@return the output connector manager handle.
+  */
+  public static ITransformationConnectorManager make(IThreadContext tc)
+    throws ManifoldCFException
+  {
+    Object o = tc.get(connMgr);
+    if (o == null || !(o instanceof ITransformationConnectorManager))
+    {
+
+      IDBInterface database = DBInterfaceFactory.make(tc,
+        ManifoldCF.getMasterDatabaseName(),
+        ManifoldCF.getMasterDatabaseUsername(),
+        ManifoldCF.getMasterDatabasePassword());
+
+      o = new org.apache.manifoldcf.agents.transformationconnmgr.TransformationConnectorManager(tc,database);
+      tc.save(connMgr,o);
+    }
+    return (ITransformationConnectorManager)o;
+  }
+
+}

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorManagerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/interfaces/TransformationConnectorManagerFactory.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java?rev=1598556&r1=1598555&r2=1598556&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java (original)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/outputconnection/OutputConnectionManager.java Fri May 30 11:31:55 2014
@@ -58,12 +58,10 @@ public class OutputConnectionManager ext
   protected final static String maxCountField = "maxcount";
   protected final static String configField = "configxml";
 
-  protected static Random random = new Random();
-
   // Cache manager
-  ICacheManager cacheManager;
+  protected final ICacheManager cacheManager;
   // Thread context
-  IThreadContext threadContext;
+  protected final IThreadContext threadContext;
 
   /** Constructor.
   *@param threadContext is the thread context.
@@ -165,7 +163,7 @@ public class OutputConnectionManager ext
   {
     int version = ManifoldCF.readDword(is);
     if (version != 1)
-      throw new java.io.IOException("Unknown repository connection configuration version: "+Integer.toString(version));
+      throw new java.io.IOException("Unknown output connection configuration version: "+Integer.toString(version));
     int count = ManifoldCF.readDword(is);
     int i = 0;
     while (i < count)

Modified: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java?rev=1598556&r1=1598555&r2=1598556&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java (original)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/system/ManifoldCF.java Fri May 30 11:31:55 2014
@@ -107,9 +107,13 @@ public class ManifoldCF extends org.apac
     IIncrementalIngester igstmgr = IncrementalIngesterFactory.make(threadcontext);
     IOutputConnectorManager outputConnMgr = OutputConnectorManagerFactory.make(threadcontext);
     IOutputConnectionManager outputConnectionManager = OutputConnectionManagerFactory.make(threadcontext);
+    ITransformationConnectorManager transConnMgr = TransformationConnectorManagerFactory.make(threadcontext);
+    ITransformationConnectionManager transConnectionManager = TransformationConnectionManagerFactory.make(threadcontext);
     mgr.install();
     outputConnMgr.install();
     outputConnectionManager.install();
+    transConnMgr.install();
+    transConnectionManager.install();
     igstmgr.install();
   }
 
@@ -123,7 +127,11 @@ public class ManifoldCF extends org.apac
     IIncrementalIngester igstmgr = IncrementalIngesterFactory.make(threadcontext);
     IOutputConnectorManager outputConnMgr = OutputConnectorManagerFactory.make(threadcontext);
     IOutputConnectionManager outputConnectionManager = OutputConnectionManagerFactory.make(threadcontext);
+    ITransformationConnectorManager transConnMgr = TransformationConnectorManagerFactory.make(threadcontext);
+    ITransformationConnectionManager transConnectionManager = TransformationConnectionManagerFactory.make(threadcontext);
     igstmgr.deinstall();
+    transConnectionManager.deinstall();
+    transConnMgr.deinstall();
     outputConnectionManager.deinstall();
     outputConnMgr.deinstall();
     mgr.deinstall();

Added: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnection.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnection.java?rev=1598556&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnection.java (added)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnection.java Fri May 30 11:31:55 2014
@@ -0,0 +1,148 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.manifoldcf.agents.transformationconnection;
+
+import org.apache.manifoldcf.core.interfaces.*;
+import org.apache.manifoldcf.agents.interfaces.*;
+import java.util.*;
+
+/** An instance of this class represents a persistently-stored transformation connection description.
+* This is the paper object meant for editing and manipulation.
+*/
+public class TransformationConnection implements ITransformationConnection
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  // data
+  protected boolean isNew = true;
+  protected String name = null;
+  protected String description = null;
+  protected String className = null;
+  protected ConfigParams configParams = new ConfigParams();
+  protected int maxCount = 100;
+
+  /** Constructor.
+  */
+  public TransformationConnection()
+  {
+  }
+
+  /** Clone this object.
+  *@return the cloned object.
+  */
+  public TransformationConnection duplicate()
+  {
+    TransformationConnection rval = new TransformationConnection();
+    rval.isNew = isNew;
+    rval.name = name;
+    rval.description = description;
+    rval.className = className;
+    rval.maxCount = maxCount;
+    rval.configParams = configParams.duplicate();
+    return rval;
+  }
+
+  /** Set 'isnew' condition.
+  *@param isnew true if this is a new instance.
+  */
+  public void setIsNew(boolean isnew)
+  {
+    this.isNew = isnew;
+  }
+  
+  /** Get 'isnew' condition.
+  *@return true if this is a new connection, false otherwise.
+  */
+  public boolean getIsNew()
+  {
+    return isNew;
+  }
+  
+  /** Set name.
+  *@param name is the name.
+  */
+  public void setName(String name)
+  {
+    this.name = name;
+  }
+
+  /** Get name.
+  *@return the name
+  */
+  public String getName()
+  {
+    return name;
+  }
+
+  /** Set description.
+  *@param description is the description.
+  */
+  public void setDescription(String description)
+  {
+    this.description = description;
+  }
+
+  /** Get description.
+  *@return the description
+  */
+  public String getDescription()
+  {
+    return description;
+  }
+
+  /** Set the class name.
+  *@param className is the class name.
+  */
+  public void setClassName(String className)
+  {
+    this.className = className;
+  }
+
+  /** Get the class name.
+  *@return the class name
+  */
+  public String getClassName()
+  {
+    return className;
+  }
+
+  /** Get the configuration parameters.
+  *@return the map.  Can be modified.
+  */
+  public ConfigParams getConfigParams()
+  {
+    return configParams;
+  }
+
+  /** Set the maximum size of the connection pool.
+  *@param maxCount is the maximum connection count per JVM.
+  */
+  public void setMaxConnections(int maxCount)
+  {
+    this.maxCount = maxCount;
+  }
+
+  /** Get the maximum size of the connection pool.
+  *@return the maximum size.
+  */
+  public int getMaxConnections()
+  {
+    return maxCount;
+  }
+}

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnection.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnection.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnectionManager.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnectionManager.java?rev=1598556&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnectionManager.java (added)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnectionManager.java Fri May 30 11:31:55 2014
@@ -0,0 +1,770 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.manifoldcf.agents.transformationconnection;
+
+import java.util.*;
+import org.apache.manifoldcf.core.interfaces.*;
+import org.apache.manifoldcf.agents.interfaces.*;
+import org.apache.manifoldcf.agents.interfaces.CacheKeyFactory;
+import org.apache.manifoldcf.agents.system.ManifoldCF;
+
+
+/** This class is the manager of the transformation connection description.  Inside, a database table is managed,
+* with appropriate caching.
+* Note well: The database handle is instantiated here using the DBInterfaceFactory.  This is acceptable because the
+* actual database that this table is located in is fixed.
+* 
+* <br><br>
+* <b>transformationconnections</b>
+* <table border="1" cellpadding="3" cellspacing="0">
+* <tr class="TableHeadingColor">
+* <th>Field</th><th>Type</th><th>Description&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th>
+* <tr><td>connectionname</td><td>VARCHAR(32)</td><td>Primary Key</td></tr>
+* <tr><td>description</td><td>VARCHAR(255)</td><td></td></tr>
+* <tr><td>classname</td><td>VARCHAR(255)</td><td></td></tr>
+* <tr><td>maxcount</td><td>BIGINT</td><td></td></tr>
+* <tr><td>configxml</td><td>LONGTEXT</td><td></td></tr>
+* </table>
+* <br><br>
+* 
+*/
+public class TransformationConnectionManager extends org.apache.manifoldcf.core.database.BaseTable implements ITransformationConnectionManager
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  // Special field suffix
+  private final static String passwordSuffix = "password";
+
+  // Database fields
+  protected final static String nameField = "connectionname";
+  protected final static String descriptionField = "description";
+  protected final static String classNameField = "classname";
+  protected final static String maxCountField = "maxcount";
+  protected final static String configField = "configxml";
+
+  // Cache manager
+  protected final ICacheManager cacheManager;
+  // Thread context
+  protected final IThreadContext threadContext;
+
+  /** Constructor.
+  *@param threadContext is the thread context.
+  */
+  public TransformationConnectionManager(IThreadContext threadContext, IDBInterface database)
+    throws ManifoldCFException
+  {
+    super(database,"transformationconnections");
+
+    cacheManager = CacheManagerFactory.make(threadContext);
+    this.threadContext = threadContext;
+  }
+
+  /** Install the manager.
+  */
+  public void install()
+    throws ManifoldCFException
+  {
+    // Always have an outer loop, in case retries required
+    while (true)
+    {
+      Map existing = getTableSchema(null,null);
+      if (existing == null)
+      {
+        // Install the table.
+        HashMap map = new HashMap();
+        map.put(nameField,new ColumnDescription("VARCHAR(32)",true,false,null,null,false));
+        map.put(descriptionField,new ColumnDescription("VARCHAR(255)",false,true,null,null,false));
+        map.put(classNameField,new ColumnDescription("VARCHAR(255)",false,false,null,null,false));
+        map.put(maxCountField,new ColumnDescription("BIGINT",false,false,null,null,false));
+        map.put(configField,new ColumnDescription("LONGTEXT",false,true,null,null,false));
+        performCreate(map,null);
+      }
+      else
+      {
+        // Upgrade code, if needed, goes here.
+      }
+
+      // Index management
+      IndexDescription classIndex = new IndexDescription(false,new String[]{classNameField});
+      
+      // Get rid of indexes that shouldn't be there
+      Map indexes = getTableIndexes(null,null);
+      Iterator iter = indexes.keySet().iterator();
+      while (iter.hasNext())
+      {
+        String indexName = (String)iter.next();
+        IndexDescription id = (IndexDescription)indexes.get(indexName);
+
+        if (classIndex != null && id.equals(classIndex))
+          classIndex = null;
+        else if (indexName.indexOf("_pkey") == -1)
+          // This index shouldn't be here; drop it
+          performRemoveIndex(indexName);
+      }
+
+      // Add the ones we didn't find
+      if (classIndex != null)
+        performAddIndex(null,classIndex);
+
+      break;
+    }
+  }
+
+  /** Uninstall the manager.
+  */
+  public void deinstall()
+    throws ManifoldCFException
+  {
+    performDrop(null);
+  }
+
+  /** Export configuration */
+  public void exportConfiguration(java.io.OutputStream os)
+    throws java.io.IOException, ManifoldCFException
+  {
+    // Write a version indicator
+    ManifoldCF.writeDword(os,1);
+    // Get the authority list
+    ITransformationConnection[] list = getAllConnections();
+    // Write the number of authorities
+    ManifoldCF.writeDword(os,list.length);
+    // Loop through the list and write the individual repository connection info
+    int i = 0;
+    while (i < list.length)
+    {
+      ITransformationConnection conn = list[i++];
+      ManifoldCF.writeString(os,conn.getName());
+      ManifoldCF.writeString(os,conn.getDescription());
+      ManifoldCF.writeString(os,conn.getClassName());
+      ManifoldCF.writeString(os,conn.getConfigParams().toXML());
+      ManifoldCF.writeDword(os,conn.getMaxConnections());
+    }
+  }
+
+  /** Import configuration */
+  public void importConfiguration(java.io.InputStream is)
+    throws java.io.IOException, ManifoldCFException
+  {
+    int version = ManifoldCF.readDword(is);
+    if (version != 1)
+      throw new java.io.IOException("Unknown transformation connection configuration version: "+Integer.toString(version));
+    int count = ManifoldCF.readDword(is);
+    int i = 0;
+    while (i < count)
+    {
+      ITransformationConnection conn = create();
+      conn.setName(ManifoldCF.readString(is));
+      conn.setDescription(ManifoldCF.readString(is));
+      conn.setClassName(ManifoldCF.readString(is));
+      conn.getConfigParams().fromXML(ManifoldCF.readString(is));
+      conn.setMaxConnections(ManifoldCF.readDword(is));
+      // Attempt to save this connection
+      save(conn);
+      i++;
+    }
+  }
+
+  /** Obtain a list of the transformation connections, ordered by name.
+  *@return an array of connection objects.
+  */
+  public ITransformationConnection[] getAllConnections()
+    throws ManifoldCFException
+  {
+    beginTransaction();
+    try
+    {
+      // Read all the tools
+      StringSetBuffer ssb = new StringSetBuffer();
+      ssb.add(getTransformationConnectionsKey());
+      StringSet localCacheKeys = new StringSet(ssb);
+      IResultSet set = performQuery("SELECT "+nameField+",lower("+nameField+") AS sortfield FROM "+getTableName()+" ORDER BY sortfield ASC",null,
+        localCacheKeys,null);
+      String[] names = new String[set.getRowCount()];
+      int i = 0;
+      while (i < names.length)
+      {
+        IResultRow row = set.getRow(i);
+        names[i] = row.getValue(nameField).toString();
+        i++;
+      }
+      return loadMultiple(names);
+    }
+    catch (ManifoldCFException e)
+    {
+      signalRollback();
+      throw e;
+    }
+    catch (Error e)
+    {
+      signalRollback();
+      throw e;
+    }
+    finally
+    {
+      endTransaction();
+    }
+  }
+
+  /** Load a transformation connection by name.
+  *@param name is the name of the transformation connection.
+  *@return the loaded connection object, or null if not found.
+  */
+  public ITransformationConnection load(String name)
+    throws ManifoldCFException
+  {
+    return loadMultiple(new String[]{name})[0];
+  }
+
+  /** Load multiple transformation connections by name.
+  *@param names are the names to load.
+  *@return the loaded connection objects.
+  */
+  public ITransformationConnection[] loadMultiple(String[] names)
+    throws ManifoldCFException
+  {
+    // Build description objects
+    TransformationConnectionDescription[] objectDescriptions = new TransformationConnectionDescription[names.length];
+    int i = 0;
+    StringSetBuffer ssb = new StringSetBuffer();
+    while (i < names.length)
+    {
+      ssb.clear();
+      ssb.add(getTransformationConnectionKey(names[i]));
+      objectDescriptions[i] = new TransformationConnectionDescription(names[i],new StringSet(ssb));
+      i++;
+    }
+
+    TransformationConnectionExecutor exec = new TransformationConnectionExecutor(this,objectDescriptions);
+    cacheManager.findObjectsAndExecute(objectDescriptions,null,exec,getTransactionID());
+    return exec.getResults();
+  }
+
+  /** Create a new transformation connection object.
+  *@return the new object.
+  */
+  public ITransformationConnection create()
+    throws ManifoldCFException
+  {
+    TransformationConnection rval = new TransformationConnection();
+    return rval;
+  }
+
+  /** Save a transformation connection object.
+  *@param object is the object to save.
+  *@return true if the object is being created, false otherwise.
+  */
+  public boolean save(ITransformationConnection object)
+    throws ManifoldCFException
+  {
+    StringSetBuffer ssb = new StringSetBuffer();
+    ssb.add(getTransformationConnectionsKey());
+    ssb.add(getTransformationConnectionKey(object.getName()));
+    StringSet cacheKeys = new StringSet(ssb);
+    while (true)
+    {
+      // Catch deadlock condition
+      long sleepAmt = 0L;
+      try
+      {
+        ICacheHandle ch = cacheManager.enterCache(null,cacheKeys,getTransactionID());
+        try
+        {
+          beginTransaction();
+          try
+          {
+            //performLock();
+            // Notify of a change to the configuration
+            ManifoldCF.noteConfigurationChange();
+            boolean isNew = object.getIsNew();
+            // See whether the instance exists
+            ArrayList params = new ArrayList();
+            String query = buildConjunctionClause(params,new ClauseDescription[]{
+              new UnitaryClause(nameField,object.getName())});
+            IResultSet set = performQuery("SELECT * FROM "+getTableName()+" WHERE "+
+              query+" FOR UPDATE",params,null,null);
+            HashMap values = new HashMap();
+            values.put(descriptionField,object.getDescription());
+            values.put(classNameField,object.getClassName());
+            values.put(maxCountField,new Long((long)object.getMaxConnections()));
+            String configXML = object.getConfigParams().toXML();
+            values.put(configField,configXML);
+            boolean notificationNeeded = false;
+            boolean isCreated;
+            
+            if (set.getRowCount() > 0)
+            {
+              // If the object is supposedly new, it is bad that we found one that already exists.
+              if (isNew)
+                throw new ManifoldCFException("Transformation connection '"+object.getName()+"' already exists");
+              isCreated = false;
+              IResultRow row = set.getRow(0);
+              String oldXML = (String)row.getValue(configField);
+              if (oldXML == null || !oldXML.equals(configXML))
+                notificationNeeded = true;
+
+              // Update
+              params.clear();
+              query = buildConjunctionClause(params,new ClauseDescription[]{
+                new UnitaryClause(nameField,object.getName())});
+              performUpdate(values," WHERE "+query,params,null);
+            }
+            else
+            {
+              // If the object is not supposed to be new, it is bad that we did not find one.
+              if (!isNew)
+                throw new ManifoldCFException("Transformation connection '"+object.getName()+"' no longer exists");
+              isCreated = true;
+              // Insert
+              values.put(nameField,object.getName());
+              // We only need the general key because this is new.
+              performInsert(values,null);
+            }
+            
+            // If notification required, do it.
+            if (notificationNeeded)
+              AgentManagerFactory.noteTransformationConnectionChange(threadContext,object.getName());
+
+            cacheManager.invalidateKeys(ch);
+            return isCreated;
+          }
+          catch (ManifoldCFException e)
+          {
+            signalRollback();
+            throw e;
+          }
+          catch (Error e)
+          {
+            signalRollback();
+            throw e;
+          }
+          finally
+          {
+            endTransaction();
+          }
+        }
+        finally
+        {
+          cacheManager.leaveCache(ch);
+        }
+      }
+      catch (ManifoldCFException e)
+      {
+        // Is this a deadlock exception?  If so, we want to try again.
+        if (e.getErrorCode() != ManifoldCFException.DATABASE_TRANSACTION_ABORT)
+          throw e;
+        sleepAmt = getSleepAmt();
+      }
+      finally
+      {
+        sleepFor(sleepAmt);
+      }
+    }
+  }
+
+  /** Delete an output connection.
+  *@param name is the name of the connection to delete.  If the
+  * name does not exist, no error is returned.
+  */
+  public void delete(String name)
+    throws ManifoldCFException
+  {
+    StringSetBuffer ssb = new StringSetBuffer();
+    ssb.add(getTransformationConnectionsKey());
+    ssb.add(getTransformationConnectionKey(name));
+    StringSet cacheKeys = new StringSet(ssb);
+    ICacheHandle ch = cacheManager.enterCache(null,cacheKeys,getTransactionID());
+    try
+    {
+      beginTransaction();
+      try
+      {
+        // Check if anything refers to this connection name
+        if (AgentManagerFactory.isTransformationConnectionInUse(threadContext,name))
+          throw new ManifoldCFException("Can't delete transformation connection '"+name+"': existing entities refer to it");
+        ManifoldCF.noteConfigurationChange();
+        ArrayList params = new ArrayList();
+        String query = buildConjunctionClause(params,new ClauseDescription[]{
+          new UnitaryClause(nameField,name)});
+        performDelete("WHERE "+query,params,null);
+        cacheManager.invalidateKeys(ch);
+      }
+      catch (ManifoldCFException e)
+      {
+        signalRollback();
+        throw e;
+      }
+      catch (Error e)
+      {
+        signalRollback();
+        throw e;
+      }
+      finally
+      {
+        endTransaction();
+      }
+    }
+    finally
+    {
+      cacheManager.leaveCache(ch);
+    }
+
+  }
+
+  /** Get a list of output connections that share the same connector.
+  *@param className is the class name of the connector.
+  *@return the repository connections that use that connector.
+  */
+  public String[] findConnectionsForConnector(String className)
+    throws ManifoldCFException
+  {
+    StringSetBuffer ssb = new StringSetBuffer();
+    ssb.add(getTransformationConnectionsKey());
+    StringSet localCacheKeys = new StringSet(ssb);
+    ArrayList params = new ArrayList();
+    String query = buildConjunctionClause(params,new ClauseDescription[]{
+      new UnitaryClause(classNameField,className)});
+    IResultSet set = performQuery("SELECT "+nameField+" FROM "+getTableName()+" WHERE "+query,params,
+      localCacheKeys,null);
+    String[] rval = new String[set.getRowCount()];
+    int i = 0;
+    while (i < rval.length)
+    {
+      IResultRow row = set.getRow(i);
+      rval[i] = (String)row.getValue(nameField);
+      i++;
+    }
+    java.util.Arrays.sort(rval);
+    return rval;
+  }
+
+  /** Check if underlying connector exists.
+  *@param name is the name of the connection to check.
+  *@return true if the underlying connector is registered.
+  */
+  public boolean checkConnectorExists(String name)
+    throws ManifoldCFException
+  {
+    beginTransaction();
+    try
+    {
+      StringSetBuffer ssb = new StringSetBuffer();
+      ssb.add(getTransformationConnectionKey(name));
+      StringSet localCacheKeys = new StringSet(ssb);
+      ArrayList params = new ArrayList();
+      String query = buildConjunctionClause(params,new ClauseDescription[]{
+        new UnitaryClause(nameField,name)});
+      IResultSet set = performQuery("SELECT "+classNameField+" FROM "+getTableName()+" WHERE "+query,params,
+        localCacheKeys,null);
+      if (set.getRowCount() == 0)
+        throw new ManifoldCFException("No such connection: '"+name+"'");
+      IResultRow row = set.getRow(0);
+      String className = (String)row.getValue(classNameField);
+      ITransformationConnectorManager cm = TransformationConnectorManagerFactory.make(threadContext);
+      return cm.isInstalled(className);
+    }
+    catch (ManifoldCFException e)
+    {
+      signalRollback();
+      throw e;
+    }
+    catch (Error e)
+    {
+      signalRollback();
+      throw e;
+    }
+    finally
+    {
+      endTransaction();
+    }
+  }
+
+  // Schema related
+  /** Return the name column.
+  *@return the name column.
+  */
+  public String getConnectionNameColumn()
+  {
+    return nameField;
+  }
+
+  // Caching strategy: Individual connection descriptions are cached, and there is a global cache key for the list of
+  // output connections.
+
+  /** Construct a key which represents the general list of transformation connectors.
+  *@return the cache key.
+  */
+  protected static String getTransformationConnectionsKey()
+  {
+    return CacheKeyFactory.makeTransformationConnectionsKey();
+  }
+
+  /** Construct a key which represents an individual transformation connection.
+  *@param connectionName is the name of the connector.
+  *@return the cache key.
+  */
+  protected static String getTransformationConnectionKey(String connectionName)
+  {
+    return CacheKeyFactory.makeTransformationConnectionKey(connectionName);
+  }
+
+  // Other utility methods.
+
+  /** Fetch multiple output connections at a single time.
+  *@param connectionNames are a list of connection names.
+  *@return the corresponding output connection objects.
+  */
+  protected TransformationConnection[] getTransformationConnectionsMultiple(String[] connectionNames)
+    throws ManifoldCFException
+  {
+    TransformationConnection[] rval = new TransformationConnection[connectionNames.length];
+    Map<String,Integer> returnIndex = new HashMap<String,Integer>();
+    int i = 0;
+    while (i < connectionNames.length)
+    {
+      rval[i] = null;
+      returnIndex.put(connectionNames[i],new Integer(i));
+      i++;
+    }
+    beginTransaction();
+    try
+    {
+      i = 0;
+      ArrayList params = new ArrayList();
+      int j = 0;
+      int maxIn = maxClauseGetTransformationConnectionsChunk();
+      while (i < connectionNames.length)
+      {
+        if (j == maxIn)
+        {
+          getTransformationConnectionsChunk(rval,returnIndex,params);
+          params.clear();
+          j = 0;
+        }
+        params.add(connectionNames[i]);
+        i++;
+        j++;
+      }
+      if (j > 0)
+        getTransformationConnectionsChunk(rval,returnIndex,params);
+      return rval;
+    }
+    catch (Error e)
+    {
+      signalRollback();
+      throw e;
+    }
+    catch (ManifoldCFException e)
+    {
+      signalRollback();
+      throw e;
+    }
+    finally
+    {
+      endTransaction();
+    }
+  }
+
+  /** Calculate max number of clauses to send to getTransformationConnectionsChunk.
+  */
+  protected int maxClauseGetTransformationConnectionsChunk()
+  {
+    return findConjunctionClauseMax(new ClauseDescription[]{});
+  }
+    
+  /** Read a chunk of transformation connections.
+  *@param rval is the place to put the read policies.
+  *@param returnIndex is a map from the object id (resource id) and the rval index.
+  *@param params is the set of parameters.
+  */
+  protected void getTransformationConnectionsChunk(TransformationConnection[] rval, Map<String,Integer> returnIndex, ArrayList params)
+    throws ManifoldCFException
+  {
+    ArrayList list = new ArrayList();
+    String query = buildConjunctionClause(list,new ClauseDescription[]{
+      new MultiClause(nameField,params)});
+    IResultSet set = performQuery("SELECT * FROM "+getTableName()+" WHERE "+
+      query,list,null,null);
+    int i = 0;
+    while (i < set.getRowCount())
+    {
+      IResultRow row = set.getRow(i++);
+      String name = row.getValue(nameField).toString();
+      int index = returnIndex.get(name).intValue();
+      TransformationConnection rc = new TransformationConnection();
+      rc.setIsNew(false);
+      rc.setName(name);
+      rc.setDescription((String)row.getValue(descriptionField));
+      rc.setClassName((String)row.getValue(classNameField));
+      rc.setMaxConnections((int)((Long)row.getValue(maxCountField)).longValue());
+      String xml = (String)row.getValue(configField);
+      if (xml != null && xml.length() > 0)
+        rc.getConfigParams().fromXML(xml);
+      rval[index] = rc;
+    }
+
+  }
+
+  // The cached instance will be a TransformationConnection.  The cached version will be duplicated when it is returned
+  // from the cache.
+  //
+  // The description object is based completely on the name.
+
+  /** This is the object description for a transformation connection object.
+  */
+  protected static class TransformationConnectionDescription extends org.apache.manifoldcf.core.cachemanager.BaseDescription
+  {
+    protected String connectionName;
+    protected String criticalSectionName;
+    protected StringSet cacheKeys;
+
+    public TransformationConnectionDescription(String connectionName, StringSet invKeys)
+    {
+      super("transformationconnectioncache");
+      this.connectionName = connectionName;
+      criticalSectionName = getClass().getName()+"-"+connectionName;
+      cacheKeys = invKeys;
+    }
+
+    public String getConnectionName()
+    {
+      return connectionName;
+    }
+
+    public int hashCode()
+    {
+      return connectionName.hashCode();
+    }
+
+    public boolean equals(Object o)
+    {
+      if (!(o instanceof TransformationConnectionDescription))
+        return false;
+      TransformationConnectionDescription d = (TransformationConnectionDescription)o;
+      return d.connectionName.equals(connectionName);
+    }
+
+    public String getCriticalSectionName()
+    {
+      return criticalSectionName;
+    }
+
+    /** Get the cache keys for an object (which may or may not exist yet in
+    * the cache).  This method is called in order for cache manager to throw the correct locks.
+    * @return the object's cache keys, or null if the object should not
+    * be cached.
+    */
+    public StringSet getObjectKeys()
+    {
+      return cacheKeys;
+    }
+
+  }
+
+  /** This is the executor object for locating transformation connection objects.
+  */
+  protected static class TransformationConnectionExecutor extends org.apache.manifoldcf.core.cachemanager.ExecutorBase
+  {
+    // Member variables
+    protected TransformationConnectionManager thisManager;
+    protected TransformationConnection[] returnValues;
+    protected HashMap returnMap = new HashMap();
+
+    /** Constructor.
+    *@param manager is the TransformationConnectionManager.
+    *@param objectDescriptions are the object descriptions.
+    */
+    public TransformationConnectionExecutor(TransformationConnectionManager manager, TransformationConnectionDescription[] objectDescriptions)
+    {
+      super();
+      thisManager = manager;
+      returnValues = new TransformationConnection[objectDescriptions.length];
+      int i = 0;
+      while (i < objectDescriptions.length)
+      {
+        returnMap.put(objectDescriptions[i].getConnectionName(),new Integer(i));
+        i++;
+      }
+    }
+
+    /** Get the result.
+    *@return the looked-up or read cached instances.
+    */
+    public TransformationConnection[] getResults()
+    {
+      return returnValues;
+    }
+
+    /** Create a set of new objects to operate on and cache.  This method is called only
+    * if the specified object(s) are NOT available in the cache.  The specified objects
+    * should be created and returned; if they are not created, it means that the
+    * execution cannot proceed, and the execute() method will not be called.
+    * @param objectDescriptions is the set of unique identifier of the object.
+    * @return the newly created objects to cache, or null, if any object cannot be created.
+    *  The order of the returned objects must correspond to the order of the object descriptinos.
+    */
+    public Object[] create(ICacheDescription[] objectDescriptions) throws ManifoldCFException
+    {
+      // Turn the object descriptions into the parameters for the ToolInstance requests
+      String[] connectionNames = new String[objectDescriptions.length];
+      int i = 0;
+      while (i < connectionNames.length)
+      {
+        TransformationConnectionDescription desc = (TransformationConnectionDescription)objectDescriptions[i];
+        connectionNames[i] = desc.getConnectionName();
+        i++;
+      }
+
+      return thisManager.getTransformationConnectionsMultiple(connectionNames);
+    }
+
+
+    /** Notify the implementing class of the existence of a cached version of the
+    * object.  The object is passed to this method so that the execute() method below
+    * will have it available to operate on.  This method is also called for all objects
+    * that are freshly created as well.
+    * @param objectDescription is the unique identifier of the object.
+    * @param cachedObject is the cached object.
+    */
+    public void exists(ICacheDescription objectDescription, Object cachedObject) throws ManifoldCFException
+    {
+      // Cast what came in as what it really is
+      TransformationConnectionDescription objectDesc = (TransformationConnectionDescription)objectDescription;
+      TransformationConnection ci = (TransformationConnection)cachedObject;
+
+      // Duplicate it!
+      if (ci != null)
+        ci = ci.duplicate();
+
+      // In order to make the indexes line up, we need to use the hashtable built by
+      // the constructor.
+      returnValues[((Integer)returnMap.get(objectDesc.getConnectionName())).intValue()] = ci;
+    }
+
+    /** Perform the desired operation.  This method is called after either createGetObject()
+    * or exists() is called for every requested object.
+    */
+    public void execute() throws ManifoldCFException
+    {
+      // Does nothing; we only want to fetch objects in this cacher.
+    }
+
+
+  }
+
+}

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnectionManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnection/TransformationConnectionManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Added: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnmgr/TransformationConnectorManager.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnmgr/TransformationConnectorManager.java?rev=1598556&view=auto
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnmgr/TransformationConnectorManager.java (added)
+++ manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnmgr/TransformationConnectorManager.java Fri May 30 11:31:55 2014
@@ -0,0 +1,305 @@
+/* $Id$ */
+
+/**
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. See the NOTICE file distributed with
+* this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You 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 org.apache.manifoldcf.agents.transformationconnmgr;
+
+import org.apache.manifoldcf.core.interfaces.*;
+import org.apache.manifoldcf.agents.interfaces.*;
+import org.apache.manifoldcf.agents.interfaces.CacheKeyFactory;
+import java.util.*;
+
+/** Implementation of ITransformationConnectorManager.
+ * 
+ * <br><br>
+ * <b>transformationconnectors</b>
+ * <table border="1" cellpadding="3" cellspacing="0">
+ * <tr class="TableHeadingColor">
+ * <th>Field</th><th>Type</th><th>Description&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ * <tr><td>description</td><td>VARCHAR(255)</td><td></td></tr>
+ * <tr><td>classname</td><td>VARCHAR(255)</td><td>Primary Key</td></tr>
+ * </table>
+ * <br><br>
+ * 
+ */
+public class TransformationConnectorManager extends org.apache.manifoldcf.core.database.BaseTable implements ITransformationConnectorManager
+{
+  public static final String _rcsid = "@(#)$Id$";
+
+  // Fields
+  protected static final String descriptionField = "description";
+  protected static final String classNameField = "classname";
+
+  // Thread context
+  protected IThreadContext threadContext;
+
+  /** Constructor.
+  *@param threadContext is the thread context.
+  *@param database is the database handle.
+  */
+  public TransformationConnectorManager(IThreadContext threadContext, IDBInterface database)
+    throws ManifoldCFException
+  {
+    super(database,"transformationconnectors");
+    this.threadContext = threadContext;
+  }
+
+
+  /** Install or upgrade.
+  */
+  public void install()
+    throws ManifoldCFException
+  {
+    // Always have an outer loop, in case upgrade needs it.
+    while (true)
+    {
+      Map existing = getTableSchema(null,null);
+      if (existing == null)
+      {
+        HashMap map = new HashMap();
+        map.put(descriptionField,new ColumnDescription("VARCHAR(255)",false,false,null,null,false));
+        map.put(classNameField,new ColumnDescription("VARCHAR(255)",true,false,null,null,false));
+
+        performCreate(map,null);
+      }
+      else
+      {
+        // Schema upgrade goes here.
+      }
+
+      // Index management
+      IndexDescription descriptionIndex = new IndexDescription(true,new String[]{descriptionField});
+
+      // Get rid of indexes that shouldn't be there
+      Map indexes = getTableIndexes(null,null);
+      Iterator iter = indexes.keySet().iterator();
+      while (iter.hasNext())
+      {
+        String indexName = (String)iter.next();
+        IndexDescription id = (IndexDescription)indexes.get(indexName);
+
+        if (descriptionIndex != null && id.equals(descriptionIndex))
+          descriptionIndex = null;
+        else if (indexName.indexOf("_pkey") == -1)
+          // This index shouldn't be here; drop it
+          performRemoveIndex(indexName);
+      }
+
+      // Add the ones we didn't find
+      if (descriptionIndex != null)
+        performAddIndex(null,descriptionIndex);
+
+      break;
+    }
+  }
+
+
+  /** Uninstall.  This also unregisters all connectors.
+  */
+  public void deinstall()
+    throws ManifoldCFException
+  {
+    StringSet invKeys = new StringSet(getCacheKey());
+
+    // First, go through all registered connectors.  This is all inside a transaction.
+    beginTransaction();
+    try
+    {
+      IResultSet set = performQuery("SELECT "+classNameField+" FROM "+getTableName(),null,null,null);
+      int i = 0;
+      while (i < set.getRowCount())
+      {
+        IResultRow row = set.getRow(i++);
+        String className = row.getValue(classNameField).toString();
+        // Call the deinstall method
+        TransformationConnectorFactory.deinstall(threadContext,className);
+      }
+      performDrop(invKeys);
+    }
+    catch (ManifoldCFException e)
+    {
+      signalRollback();
+      throw e;
+    }
+    catch (Error e)
+    {
+      signalRollback();
+      throw e;
+    }
+    finally
+    {
+      endTransaction();
+    }
+  }
+
+  /** Register a new connector.
+  * The connector's install method will also be called.
+  *@param description is the description to use in the UI.
+  *@param className is the class name.
+  */
+  public void registerConnector(String description, String className)
+    throws ManifoldCFException
+  {
+    StringSet invKeys = new StringSet(getCacheKey());
+    beginTransaction();
+    try
+    {
+      //performLock();
+      // See if already there.
+      ArrayList params = new ArrayList();
+      params.add(className);
+      IResultSet set = performQuery("SELECT * FROM "+getTableName()+" WHERE "+classNameField+"=? FOR UPDATE",params,null,null);
+      HashMap map = new HashMap();
+      map.put(descriptionField,description);
+      if (set.getRowCount() == 0)
+      {
+        // Insert it into table first.
+        map.put(classNameField,className);
+        performInsert(map,invKeys);
+      }
+      else
+      {
+        performUpdate(map,"WHERE "+classNameField+"=?",params,invKeys);
+      }
+
+      // Either way, we must do the install/upgrade itself.
+      TransformationConnectorFactory.install(threadContext,className);
+    }
+    catch (ManifoldCFException e)
+    {
+      signalRollback();
+      throw e;
+    }
+    catch (Error e)
+    {
+      signalRollback();
+      throw e;
+    }
+    finally
+    {
+      endTransaction();
+    }
+  }
+
+  /** Unregister a connector.
+  * The connector's deinstall method will also be called.
+  *@param className is the class name of the connector to unregister.
+  */
+  public void unregisterConnector(String className)
+    throws ManifoldCFException
+  {
+    StringSet invKeys = new StringSet(getCacheKey());
+    beginTransaction();
+    try
+    {
+      // Uninstall first
+      TransformationConnectorFactory.deinstall(threadContext,className);
+
+      removeConnector(className);
+    }
+    catch (ManifoldCFException e)
+    {
+      signalRollback();
+      throw e;
+    }
+    catch (Error e)
+    {
+      signalRollback();
+      throw e;
+    }
+    finally
+    {
+      endTransaction();
+    }
+  }
+
+  /** Remove a connector.
+  * Use this method when the connector doesn't seem to be in the
+  * classpath, so deregistration cannot occur.
+  *@param className is the connector class to remove.
+  */
+  public void removeConnector(String className)
+    throws ManifoldCFException
+  {
+    StringSet invKeys = new StringSet(getCacheKey());
+    ArrayList list = new ArrayList();
+    list.add(className);
+    performDelete("WHERE "+classNameField+"=?",list,invKeys);
+  }
+
+  /** Get ordered list of connectors.
+  *@return a resultset with the columns "description" and "classname".
+  * These will be ordered by description.
+  */
+  public IResultSet getConnectors()
+    throws ManifoldCFException
+  {
+    StringSet invKeys = new StringSet(getCacheKey());
+
+    return performQuery("SELECT "+descriptionField+" AS description,"+classNameField+" AS classname FROM "+
+      getTableName()+" ORDER BY "+descriptionField+" ASC",null,invKeys,null);
+  }
+
+  /** Get a description given a class name.
+  *@param className is the class name.
+  *@return the description, or null if the class is not registered.
+  */
+  public String getDescription(String className)
+    throws ManifoldCFException
+  {
+    StringSet invKeys = new StringSet(getCacheKey());
+
+    ArrayList list = new ArrayList();
+    list.add(className);
+    IResultSet set = performQuery("SELECT "+descriptionField+" FROM "+
+      getTableName()+" WHERE "+classNameField+"=?",list,invKeys,null);
+    if (set.getRowCount() == 0)
+      return null;
+    IResultRow row = set.getRow(0);
+    return row.getValue(descriptionField).toString();
+  }
+
+  /** Check if a particular connector is installed or not.
+  *@param className is the class name of the connector.
+  *@return true if installed, false otherwise.
+  */
+  public boolean isInstalled(String className)
+    throws ManifoldCFException
+  {
+    // Use the global table key; that's good enough because we don't expect stuff to change out from under very often.
+    StringSet invKeys = new StringSet(getCacheKey());
+
+    ArrayList list = new ArrayList();
+    list.add(className);
+    IResultSet set = performQuery("SELECT * FROM "+
+      getTableName()+" WHERE "+classNameField+"=?",list,invKeys,null);
+    return set.getRowCount() > 0;
+  }
+
+
+
+  // Protected methods
+
+  /** Get the cache key for the connector manager table.
+  *@return the cache key
+  */
+  protected String getCacheKey()
+  {
+    return CacheKeyFactory.makeTableKey(null,getTableName(),getDBInterface().getDatabaseName());
+  }
+
+}

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnmgr/TransformationConnectorManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: manifoldcf/branches/CONNECTORS-946/framework/agents/src/main/java/org/apache/manifoldcf/agents/transformationconnmgr/TransformationConnectorManager.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: manifoldcf/branches/CONNECTORS-946/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/CrawlerAgent.java
URL: http://svn.apache.org/viewvc/manifoldcf/branches/CONNECTORS-946/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/CrawlerAgent.java?rev=1598556&r1=1598555&r2=1598556&view=diff
==============================================================================
--- manifoldcf/branches/CONNECTORS-946/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/CrawlerAgent.java (original)
+++ manifoldcf/branches/CONNECTORS-946/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/CrawlerAgent.java Fri May 30 11:31:55 2014
@@ -282,6 +282,48 @@ public class CrawlerAgent implements IAg
     jobManager.noteOutputConnectionChange(connectionName);
   }
 
+  /** Request permission from agent to delete a transformation connection.
+  *@param connName is the name of the transformation connection.
+  *@return true if the connection is in use, false otherwise.
+  */
+  @Override
+  public boolean isTransformationConnectionInUse(IThreadContext threadContext, String connName)
+    throws ManifoldCFException
+  {
+    // MHL
+    return false;
+  }
+
+  /** Note the deregistration of a set of transformation connections.
+  *@param connectionNames are the names of the connections being deregistered.
+  */
+  @Override
+  public void noteTransformationConnectorDeregistration(IThreadContext threadContext, String[] connectionNames)
+    throws ManifoldCFException
+  {
+    // MHL
+  }
+
+  /** Note the registration of a set of transformation connections.
+  *@param connectionNames are the names of the connections being registered.
+  */
+  @Override
+  public void noteTransformationConnectorRegistration(IThreadContext threadContext, String[] connectionNames)
+    throws ManifoldCFException
+  {
+    // MHL
+  }
+
+  /** Note a change in configuration for a transformation connection.
+  *@param connectionName is the name of the connection being changed.
+  */
+  @Override
+  public void noteTransformationConnectionChange(IThreadContext threadContext, String connectionName)
+    throws ManifoldCFException
+  {
+    // MHL
+  }
+
   /** Start everything.
   */
   public void startSystem(IThreadContext threadContext)