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 2016/05/10 11:39:48 UTC

svn commit: r1743159 - in /manifoldcf/trunk: ./ connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/jdbc/ connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/jdbc/ connectors/jdbc/connector/src/main/native2ascii/o...

Author: kwright
Date: Tue May 10 11:39:48 2016
New Revision: 1743159

URL: http://svn.apache.org/viewvc?rev=1743159&view=rev
Log:
Fix for CONNECTORS-1313.

Removed:
    manifoldcf/trunk/connectors/jdbc/connector/src/main/resource/
Modified:
    manifoldcf/trunk/   (props changed)
    manifoldcf/trunk/CHANGES.txt
    manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/jdbc/JDBCConnector.java
    manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/jdbc/JDBCConstants.java
    manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/authorities/jdbc/common_es_ES.properties
    manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_en_US.properties
    manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_es_ES.properties
    manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_ja_JP.properties
    manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_zh_CN.properties
    manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/end-user-documentation.xml

Propchange: manifoldcf/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue May 10 11:39:48 2016
@@ -65,6 +65,7 @@
 /manifoldcf/branches/CONNECTORS-1270:1726811-1727380
 /manifoldcf/branches/CONNECTORS-13:1525862-1527182,1539324-1541634
 /manifoldcf/branches/CONNECTORS-1308:1741766-1741789
+/manifoldcf/branches/CONNECTORS-1313:1742768-1743158
 /manifoldcf/branches/CONNECTORS-470:1349741-1360750,1360808
 /manifoldcf/branches/CONNECTORS-474:1349741-1353803
 /manifoldcf/branches/CONNECTORS-488:1363249-1364203

Modified: manifoldcf/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/CHANGES.txt?rev=1743159&r1=1743158&r2=1743159&view=diff
==============================================================================
--- manifoldcf/trunk/CHANGES.txt (original)
+++ manifoldcf/trunk/CHANGES.txt Tue May 10 11:39:48 2016
@@ -3,6 +3,9 @@ $Id$
 
 ======================= 2.5-dev =====================
 
+CONNECTORS-1313: Add multivalued data support to JDBC connector.
+(Luca Alciata, Karl Wright)
+
 CONNECTORS-1312: Treat "connection reset by peer" same way as "busy"
 in JCIFS connector.
 (Konstantin Avdeev, Karl Wright)

Modified: manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/jdbc/JDBCConnector.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/jdbc/JDBCConnector.java?rev=1743159&r1=1743158&r2=1743159&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/jdbc/JDBCConnector.java (original)
+++ manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/crawler/connectors/jdbc/JDBCConnector.java Tue May 10 11:39:48 2016
@@ -535,6 +535,98 @@ public class JDBCConnector extends org.a
       }
     }
     
+    // We have a primary query and a number of attribute queries to execute.
+    // We execute the attribute queries first because those do not include binary data.
+    final Map<String, Map<String, Set<String>>> attributeValues = new HashMap<String, Map<String, Set<String>>>();
+    int index = 0;
+    while (index < spec.getChildCount())
+    {
+      SpecificationNode sn = spec.getChild(index++);
+      if (sn.getType().equals(JDBCConstants.attributeQueryNode))
+      {
+        final String attributeName = sn.getAttributeValue(JDBCConstants.attributeName);
+        final String attributeQuery = sn.getValue();
+        // Fire off attribute query
+        VariableMap attrVm = new VariableMap();
+        addConstant(attrVm,JDBCConstants.idReturnVariable,JDBCConstants.idReturnColumnName);
+        addConstant(attrVm,JDBCConstants.dataReturnVariable,JDBCConstants.dataReturnColumnName);
+        if (!addIDList(attrVm,JDBCConstants.idListVariable,documentIdentifiers,map.keySet()))
+          continue;
+        
+        // Do the substitution
+        ArrayList paramList = new ArrayList();
+        StringBuilder sb = new StringBuilder();
+        substituteQuery(attributeQuery,attrVm,sb,paramList);
+
+        // Fire off the query!
+        getSession();
+        IDynamicResultSet result;
+        String queryText = sb.toString();
+        long startTime = System.currentTimeMillis();
+        // Get a dynamic resultset.  Contract for dynamic resultset is that if
+        // one is returned, it MUST be closed, or a connection will leak.
+        try
+        {
+          result = connection.executeUncachedQuery(queryText,paramList,-1);
+        }
+        catch (ManifoldCFException e)
+        {
+          // If failure, record the failure.
+          if (e.getErrorCode() != ManifoldCFException.INTERRUPTED)
+            activities.recordActivity(new Long(startTime), ACTIVITY_EXTERNAL_QUERY, null,
+              createQueryString(queryText,paramList), "ERROR", e.getMessage(), null);
+          throw e;
+        }
+        try
+        {
+          // If success, record that too.
+          activities.recordActivity(new Long(startTime), ACTIVITY_EXTERNAL_QUERY, null,
+            createQueryString(queryText,paramList), "OK", null, null);
+          // Now, go through resultset
+          while (true)
+          {
+            IDynamicResultRow row = result.getNextRow();
+            if (row == null)
+              break;
+            try
+            {
+              Object o = row.getValue(JDBCConstants.idReturnColumnName);
+              if (o == null)
+                throw new ManifoldCFException("Bad attribute query; doesn't return $(IDCOLUMN) column.  Try using quotes around $(IDCOLUMN) variable, e.g. \"$(IDCOLUMN)\", or, for MySQL, select \"by label\" in your repository connection.");
+              String idValue = JDBCConnection.readAsString(o);
+              o = row.getValue(JDBCConstants.dataReturnColumnName);
+              String dataValue;
+              if (o == null)
+                dataValue = "";
+              else
+                dataValue = JDBCConnection.readAsString(o);
+              Map<String, Set<String>> avs = attributeValues.get(idValue);
+              if (avs == null)
+              {
+                avs = new HashMap<String, Set<String>>();
+                attributeValues.put(idValue,avs);
+              }
+              Set<String> dataValues = avs.get(attributeName);
+              if (dataValues == null)
+              {
+                dataValues = new HashSet<String>();
+                avs.put(attributeName, dataValues);
+              }
+              dataValues.add(dataValue);
+            }
+            finally
+            {
+              row.close();
+            }
+          }
+        }
+        finally
+        {
+          result.close();
+        }
+      }
+    }
+    
     // For all the documents not marked "scan only", form a query and pick up the contents.
     // If the contents is not found, then explicitly call the delete action method.
     VariableMap vm = new VariableMap();
@@ -684,7 +776,8 @@ public class JDBCConnector extends org.a
             // An ingestion will take place for this document.
             RepositoryDocument rd = new RepositoryDocument();
             rd.setMimeType(contentType);
-                        
+
+            applyMultiAttributeValues(rd,attributeValues.get(id));
             applyAccessTokens(rd,documentAcls.get(id));
             applyMetadata(rd,row);
 
@@ -1171,6 +1264,46 @@ public class JDBCConnector extends org.a
 "  postFormSetAnchor(anchorvalue);\n"+
 "}\n"+
 "\n"+
+"function "+seqPrefix+"DeleteAttr(index)\n"+
+"{\n"+
+"  "+seqPrefix+"SpecOp(\""+seqPrefix+"attr_\"+index+\"_op\", \"Delete\", \""+seqPrefix+"attr_\" + index);\n"+
+"}\n"+
+"\n"+
+"function "+seqPrefix+"AddAttr(index)\n"+
+"{\n"+
+"  if (editjob."+seqPrefix+"attr_name.value == \"\")\n"+
+"  {\n"+
+"    alert(\"" + Messages.getBodyJavascriptString(locale,"JDBCConnector.TypeInAnAttributeName") + "\");\n"+
+"    editjob."+seqPrefix+"attr_name.focus();\n"+
+"    return;\n"+
+"  }\n"+
+"  if (editjob."+seqPrefix+"attr_query.value == \"\")\n"+
+"  {\n"+
+"    alert(\"" + Messages.getBodyJavascriptString(locale,"JDBCConnector.AttributeQueryCannotBeNull") + "\");\n"+
+"    editjob."+seqPrefix+"attr_query.focus();\n"+
+"    return;\n"+
+"  }\n"+
+"  if (editjob."+seqPrefix+"attr_query.value.indexOf(\"$(IDCOLUMN)\") == -1)\n"+
+"  {\n"+
+"    alert(\"" + Messages.getBodyJavascriptString(locale,"JDBCConnector.MustReturnIDCOLUMNInTheResult") + "\");\n"+
+"    editjob."+seqPrefix+"attr_query.focus();\n"+
+"    return;\n"+
+"  }\n"+
+"  if (editjob."+seqPrefix+"attr_query.value.indexOf(\"$(DATACOLUMN)\") == -1)\n"+
+"  {\n"+
+"    alert(\"" + Messages.getBodyJavascriptString(locale,"JDBCConnector.MustReturnDATACOLUMNInTheResult") + "\");\n"+
+"    editjob."+seqPrefix+"attr_query.focus();\n"+
+"    return;\n"+
+"  }\n"+
+"  if (editjob."+seqPrefix+"attr_query.value.indexOf(\"$(IDLIST)\") == -1)\n"+
+"  {\n"+
+"    alert(\"" + Messages.getBodyJavascriptString(locale,"JDBCConnector.MustUseIDLISTInWHEREClause") + "\");\n"+
+"    editjob."+seqPrefix+"attr_query.focus();\n"+
+"    return;\n"+
+"  }\n"+
+"  "+seqPrefix+"SpecOp(\""+seqPrefix+"attr_op\", \"Add\", \""+seqPrefix+"attr_\"+(index+1));\n"+
+"}\n"+
+"\n"+
 "function "+seqPrefix+"SpecAddToken(anchorvalue)\n"+
 "{\n"+
 "  if (editjob."+seqPrefix+"spectoken.value == \"\")\n"+
@@ -1303,6 +1436,7 @@ public class JDBCConnector extends org.a
     String dataQuery = "SELECT idfield AS $(IDCOLUMN), urlfield AS $(URLCOLUMN), datafield AS $(DATACOLUMN) FROM documenttable WHERE idfield IN $(IDLIST)";
     String aclQuery = "SELECT docidfield AS $(IDCOLUMN), aclfield AS $(TOKENCOLUMN) FROM acltable WHERE docidfield IN $(IDLIST)";
     
+    final Map<String, String> attributeQueryMap = new HashMap<String, String>();
     int i = 0;
     while (i < ds.getChildCount())
     {
@@ -1331,8 +1465,18 @@ public class JDBCConnector extends org.a
         if (aclQuery == null)
           aclQuery = "";
       }
+      else if (sn.getType().equals(JDBCConstants.attributeQueryNode))
+      {
+        String attributeName = sn.getAttributeValue(JDBCConstants.attributeName);
+        String attributeQuery = sn.getValue();
+        attributeQueryMap.put(attributeName, attributeQuery);
+      }
     }
 
+    // Sort the attribute query list
+    final String[] attributeNames = attributeQueryMap.keySet().toArray(new String[0]);
+    java.util.Arrays.sort(attributeNames);
+    
     // The Queries tab
 
     if (tabName.equals(Messages.getString(locale,"JDBCConnector.Queries")) && connectionSequenceNumber == actualSequenceNumber)
@@ -1355,6 +1499,91 @@ public class JDBCConnector extends org.a
 "  <tr>\n"+
 "    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"JDBCConnector.DataQuery") + "</nobr><br/><nobr>" + Messages.getBodyString(locale,"JDBCConnector.returnIdsUrlsAndDataForASetOfDocuments") + "</nobr></td>\n"+
 "    <td class=\"value\"><textarea name=\""+seqPrefix+"dataquery\" cols=\"64\" rows=\"6\">"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(dataQuery)+"</textarea></td>\n"+
+"  </tr>\n");
+      out.print(
+"  <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+
+"  <tr>"+
+"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"JDBCConnector.AttributeQueries") + "</nobr></td>\n"+
+"    <td class=\"boxcell\">\n"+
+"      <table class=\"formtable\">\n"+
+"        <tr class=\"formheaderrow\">\n"+
+"          <td class=\"formcolumnheader\"></td>\n"+
+"          <td class=\"formcolumnheader\"><nobr>" + Messages.getBodyString(locale,"JDBCConnector.AttributeName") + "</nobr></td>\n"+
+"          <td class=\"formcolumnheader\"><nobr>" + Messages.getBodyString(locale,"JDBCConnector.AttributeQuery") + "</nobr></td>\n"+
+"        </tr>\n"
+      );
+      int attributeIndex = 0;
+      for (final String attributeName : attributeNames) {
+        final String attributeQuery = attributeQueryMap.get(attributeName);
+        if (attributeIndex % 2 == 0)
+        {
+          out.print(
+"        <tr class=\"evenformrow\">\n"
+          );
+        }
+        else 
+        {
+          out.print(
+"        <tr class=\"oddformrow\">\n"
+          );
+        }
+        // Delete button
+        out.print(
+"          <td class=\"formcolumncell\">\n"+
+"            <a name=\""+seqPrefix+"attr_"+attributeIndex+"\">\n"+
+"              <nobr>\n"+
+"                <input type=\"button\" value=\""+Messages.getAttributeString(locale,"JDBCConnector.Delete")+"\"\n"+
+"                alt=\""+Messages.getAttributeString(locale,"JDBCConnector.DeleteAttributeQueryNumber")+attributeIndex+"\" onclick=\"javascript:"+seqPrefix+"DeleteAttr("+attributeIndex+");\"/>\n"+
+"              </nobr>\n"+
+"            </a>\n"+
+"            <input type=\"hidden\" name=\""+seqPrefix+"attr_"+attributeIndex+"_op"+"\" value=\"Continue\"/>\n"+
+"            <input type=\"hidden\" name=\""+seqPrefix+"attr_"+attributeIndex+"_name\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(attributeName)+"\"/>\n"+
+"          </td>\n"
+        );
+        // Attribute name
+        out.print(
+"          <td class=\"formcolumncell\">\n"+
+"            "+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(attributeName)+"\n"+
+"          </td>\n"
+        );
+        // Query
+        out.print(
+"          <td class=\"formcolumncell\">\n"+
+"            <textarea name=\""+seqPrefix+"attr_"+attributeIndex+"_query\" cols=\"64\" rows=\"6\">"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(attributeQuery)+"</textarea>\n"+
+"          </td>\n"
+        );
+        out.print(
+"        </tr>\n"
+        );
+        attributeIndex++;
+      }
+      if (attributeIndex == 0)
+      {
+        out.print(
+"        <tr><td class=\"formmessage\" colspan=\"3\">"+Messages.getBodyString(locale,"JDBCConnector.NoAttributeQueries")+"</td></tr>\n"
+        );
+      }
+      // Add button
+      out.print(
+"        <tr><td class=\"formseparator\" colspan=\"3\"><hr/></td></tr>\n"+
+"        <tr class=\"formrow\">\n"+
+"          <td class=\"formcolumncell\">\n"+
+"            <a name=\""+seqPrefix+"attr_"+attributeIndex+"\">\n"+
+"              <input type=\"button\" value=\""+Messages.getAttributeString(locale,"JDBCConnector.Add")+"\"\n"+
+"              alt=\""+Messages.getAttributeString(locale,"JDBCConnector.AddAttribute")+"\" onclick=\"javascript:"+seqPrefix+"AddAttr("+attributeIndex+");\"/>\n"+
+"            </a>\n"+
+"            <input type=\"hidden\" name=\""+seqPrefix+"attr_count\" value=\""+attributeIndex+"\"/>\n"+
+"            <input type=\"hidden\" name=\""+seqPrefix+"attr_op\" value=\"Continue\"/>\n"+
+"          </td>\n"+
+"          <td class=\"formcolumncell\"><nobr><input name=\""+seqPrefix+"attr_name\" type=\"text\" size=\"16\" value=\"\"/></nobr></td>\n"+
+"          <td class=\"formcolumncell\">\n"+
+"            <textarea name=\""+seqPrefix+"attr_query\" cols=\"64\" rows=\"6\">SELECT idfield AS $(IDCOLUMN), datafield AS $(DATACOLUMN) FROM attributetable WHERE idfield IN $(IDLIST)</textarea>\n"+
+"          </td>\n"+
+"        </tr>\n"
+      );
+      out.print(
+"      </table>\n"+
+"    </td>\n"+
 "  </tr>\n"+
 "</table>\n"
       );
@@ -1367,6 +1596,18 @@ public class JDBCConnector extends org.a
 "<input type=\"hidden\" name=\""+seqPrefix+"aclquery\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(aclQuery)+"\"/>\n"+
 "<input type=\"hidden\" name=\""+seqPrefix+"dataquery\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(dataQuery)+"\"/>\n"
       );
+      int attributeIndex = 0;
+      for (final String attributeName : attributeNames) {
+        final String attributeQuery = attributeQueryMap.get(attributeName);
+        out.print(
+"<input type=\"hidden\" name=\""+seqPrefix+"attr_"+attributeIndex+"_name\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(attributeName)+"\"/>\n"+
+"<input type=\"hidden\" name=\""+seqPrefix+"attr_"+attributeIndex+"_query\" value=\""+org.apache.manifoldcf.ui.util.Encoder.attributeEscape(attributeQuery)+"\"/>\n"
+        );
+        attributeIndex++;
+      }
+      out.print(
+"<input type=\"hidden\" name=\""+seqPrefix+"attr_count\" value=\""+attributeIndex+"\"/>\n"
+      );
     }
 	
     // Security tab
@@ -1562,7 +1803,60 @@ public class JDBCConnector extends org.a
       ds.addChild(ds.getChildCount(),sn);
     }
 
-    String xc = variableContext.getParameter(seqPrefix+"specsecurity");
+    String xc;
+    xc = variableContext.getParameter(seqPrefix+"attr_count");
+    if (xc != null)
+    {
+      // Delete all attribute queries first
+      int i = 0;
+      while (i < ds.getChildCount())
+      {
+        sn = ds.getChild(i);
+        if (sn.getType().equals(JDBCConstants.attributeQueryNode))
+          ds.removeChild(i);
+        else
+          i++;
+      }
+
+      // Now, maybe do add
+      final String newAttributeName;
+      final String newAttributeOp = variableContext.getParameter(seqPrefix+"attr_op");
+      if (newAttributeOp != null && newAttributeOp.equals("Add"))
+      {
+        final String attributeName = variableContext.getParameter(seqPrefix+"attr_name");
+        final String attributeQuery = variableContext.getParameter(seqPrefix+"attr_query");
+        SpecificationNode node = new SpecificationNode(JDBCConstants.attributeQueryNode);
+        node.setAttribute(JDBCConstants.attributeName, attributeName);
+        newAttributeName = attributeName;
+        node.setValue(attributeQuery);
+        ds.addChild(ds.getChildCount(),node);
+      }
+      else
+      {
+        newAttributeName = null;
+      }
+
+      int attributeCount = Integer.parseInt(xc);
+      for (int attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++)
+      {
+        final String attributeOp = variableContext.getParameter(seqPrefix+"attr_"+attributeIndex+"_op");
+        if (!(attributeOp != null && attributeOp.equals("Delete")))
+        {
+          // Include this!!
+          final String attributeName = variableContext.getParameter(seqPrefix+"attr_"+attributeIndex+"_name");
+          if (newAttributeName == null || !attributeName.equals(newAttributeName)) {
+            final String attributeQuery = variableContext.getParameter(seqPrefix+"attr_"+attributeIndex+"_query");
+            SpecificationNode node = new SpecificationNode(JDBCConstants.attributeQueryNode);
+            node.setAttribute(JDBCConstants.attributeName, attributeName);
+            node.setValue(attributeQuery);
+            ds.addChild(ds.getChildCount(),node);
+          }
+        }
+      }
+      
+    }
+    
+    xc = variableContext.getParameter(seqPrefix+"specsecurity");
     if (xc != null)
     {
       // Delete all security entries first
@@ -1649,6 +1943,8 @@ public class JDBCConnector extends org.a
     String dataQuery = "";
     String aclQuery = "";
     
+    final Map<String, String> attributeQueryMap = new HashMap<String, String>();
+    
     int i = 0;
     while (i < ds.getChildCount())
     {
@@ -1677,8 +1973,18 @@ public class JDBCConnector extends org.a
         if (aclQuery == null)
           aclQuery = "";
       }
+      else if (sn.getType().equals(JDBCConstants.attributeQueryNode))
+      {
+        String attributeName = sn.getAttributeValue(JDBCConstants.attributeName);
+        String attributeQuery = sn.getValue();
+        attributeQueryMap.put(attributeName, attributeQuery);
+      }
     }
 
+    // Sort the attribute query list
+    final String[] attributeNames = attributeQueryMap.keySet().toArray(new String[0]);
+    java.util.Arrays.sort(attributeNames);
+
     out.print(
 "<table class=\"displaytable\">\n"+
 "  <tr>\n"+
@@ -1698,6 +2004,57 @@ public class JDBCConnector extends org.a
 "    <td class=\"value\">"+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(dataQuery)+"</td>\n"+
 "  </tr>\n"+
 "\n"+
+"  <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"+
+"  <tr>"+
+"    <td class=\"description\"><nobr>" + Messages.getBodyString(locale,"JDBCConnector.AttributeQueries") + "</nobr></td>\n"+
+"    <td class=\"boxcell\">\n"+
+"      <table class=\"formtable\">\n"+
+"        <tr class=\"formheaderrow\">\n"+
+"          <td class=\"formcolumnheader\"><nobr>" + Messages.getBodyString(locale,"JDBCConnector.AttributeName") + "</nobr></td>\n"+
+"          <td class=\"formcolumnheader\"><nobr>" + Messages.getBodyString(locale,"JDBCConnector.AttributeQuery") + "</nobr></td>\n"+
+"        </tr>\n"
+    );
+    int attributeIndex = 0;
+    for (final String attributeName : attributeNames) {
+      final String attributeQuery = attributeQueryMap.get(attributeName);
+      if (attributeIndex % 2 == 0)
+      {
+        out.print(
+"        <tr class=\"evenformrow\">\n"
+        );
+      }
+      else 
+      {
+        out.print(
+"        <tr class=\"oddformrow\">\n"
+        );
+      }
+      // Attribute name
+      out.print(
+"          <td class=\"formcolumncell\">\n"+
+"            "+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(attributeName)+"\n"+
+"          </td>\n"
+      );
+      // Query
+      out.print(
+"          <td class=\"formcolumncell\">\n"+
+"            "+org.apache.manifoldcf.ui.util.Encoder.bodyEscape(attributeQuery)+"\n"+
+"          </td>\n"
+      );
+      out.print(
+"        </tr>\n"
+      );
+      attributeIndex++;
+    }
+    if (attributeIndex == 0)
+    {
+      out.print(
+"        <tr><td class=\"formmessage\" colspan=\"2\">"+Messages.getBodyString(locale,"JDBCConnector.NoAttributeQueries")+"</td></tr>\n"
+      );
+    }
+    out.print(
+"      </table>\n"+
+"    </td>\n"+
 "  <tr><td class=\"separator\" colspan=\"2\"><hr/></td></tr>\n"
     );
     // Find whether security is on or off
@@ -1798,6 +2155,29 @@ public class JDBCConnector extends org.a
       }
     }
   }
+
+  /** Apply multi-valued attribute values to a repository document.
+  */
+  protected void applyMultiAttributeValues(final RepositoryDocument rd, final Map<String, Set<String>> values)
+    throws ManifoldCFException
+  {
+    if (values == null)
+    {
+      return;
+    }
+    
+    for (final String attributeName : values.keySet())
+    {
+      final Set<String> attributes = values.get(attributeName);
+      final String[] attributeValues = new String[values.size()];
+      int i = 0;
+      for (final String attributeValue : attributes)
+      {
+        attributeValues[i++] = attributeValue;
+      }
+      rd.addField(attributeName, attributeValues);
+    }
+  }
   
   /** Apply access tokens to a repository document.
   *@param rd is the repository document to apply the access tokens to.

Modified: manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/jdbc/JDBCConstants.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/jdbc/JDBCConstants.java?rev=1743159&r1=1743158&r2=1743159&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/jdbc/JDBCConstants.java (original)
+++ manifoldcf/trunk/connectors/jdbc/connector/src/main/java/org/apache/manifoldcf/jdbc/JDBCConstants.java Tue May 10 11:39:48 2016
@@ -47,6 +47,10 @@ public class JDBCConstants
   public static String dataQueryNode = "dataquery";
   /** The node containing the acl query */
   public static String aclQueryNode = "aclquery";
+  /** The node containing an attribute query */
+  public static String attributeQueryNode = "attrquery";
+  /** The attribute name for an attribute query */
+  public static String attributeName = "attributename";
 
   /** The name of the id return column */
   public static String idReturnColumnName = "lcf__id";

Modified: manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/authorities/jdbc/common_es_ES.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/authorities/jdbc/common_es_ES.properties?rev=1743159&r1=1743158&r2=1743159&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/authorities/jdbc/common_es_ES.properties (original)
+++ manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/authorities/authorities/jdbc/common_es_ES.properties Tue May 10 11:39:48 2016
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 JDBCAuthority.DatabaseType=Tipo de base de datos
-JDBCAuthority.AccessMethod=M�todo de acceso
+JDBCAuthority.AccessMethod=Método de acceso
 JDBCAuthority.ByName=por nombre
 JDBCAuthority.ByLabel=por etiqueta
 JDBCAuthority.Server=Server
@@ -22,17 +22,17 @@ JDBCAuthority.Credentials=Credenciales
 JDBCAuthority.DatabaseType2=tipo de base de datos
 JDBCAuthority.DatabaseHostAndPort=Base de datos de host y el puerto
 JDBCAuthority.DatabaseServiceNameOrInstanceDatabase=Base de datos el nombre del servicio o instancia base de datos
-JDBCAuthority.RawDatabaseConnectString=Base de datos RAW cadena de conexi�n:
+JDBCAuthority.RawDatabaseConnectString=Base de datos RAW cadena de conexión:
 JDBCAuthority.UserName=Nombre de usuario:
 JDBCAuthority.Password=Password:
-JDBCAuthority.Parameters=Par�metros:
+JDBCAuthority.Parameters=Parámetros:
 JDBCAuthority.Queries=consultas
 JDBCAuthority.UserIdQuery=Usuario consulta ID:
-JDBCAuthority.TokenQuery=Autorizaci�n fichas de consulta:
-JDBCAuthority.returnUserIdOrEmptyResultset=(volver Identificaci�n del usuario si existe usuario o conjunto de resultados vac�o)
-JDBCAuthority.returnTokensForUser=(autorizaci�n de devoluci�n fichas de usuario)
+JDBCAuthority.TokenQuery=Autorización fichas de consulta:
+JDBCAuthority.returnUserIdOrEmptyResultset=(volver Identificación del usuario si existe usuario o conjunto de resultados vacío)
+JDBCAuthority.returnTokensForUser=(autorización de devolución fichas de usuario)
 JDBCAuthority.NoAccessTokensPresent=No hay tokens de acceso actuales
 JDBCAuthority.NoAccessTokensSpecified=No hay tokens de acceso especificados
 JDBCAuthority.PleaseFillInADatabaseServerName=Por favor, rellene un nombre de servidor de base de datos
 JDBCAuthority.PleaseFillInTheNameOfTheDatabase=Por favor escriba el nombre de la base de datos
-JDBCAuthority.PleaseSupplyTheDatabaseUsernameForThisConnection=Por favor, facilite el nombre de usuario de base de datos para esta conexi�n
\ No newline at end of file
+JDBCAuthority.PleaseSupplyTheDatabaseUsernameForThisConnection=Por favor, facilite el nombre de usuario de base de datos para esta conexión
\ No newline at end of file

Modified: manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_en_US.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_en_US.properties?rev=1743159&r1=1743158&r2=1743159&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_en_US.properties (original)
+++ manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_en_US.properties Tue May 10 11:39:48 2016
@@ -42,14 +42,14 @@ JDBCConnector.PleaseFillInADatabaseServe
 JDBCConnector.PleaseFillInTheNameOfTheDatabase=Please fill in the name of the database
 JDBCConnector.PleaseSupplyTheDatabaseUsernameForThisConnection=Please supply the database username for this connection
 JDBCConnector.EnterASeedingQuery=Enter a seeding query
-JDBCConnector.MustReturnIDCOLUMNInTheResult=Must return $(IDCOLUMN) in the result.\\nExample: SELECT idfield AS $(IDCOLUMN) FROM ...
-JDBCConnector.MustReturnVERSIONCOLUMNInTheResult=Must return $(VERSIONCOLUMN) in the result, containing the document version.\\nExample: SELECT versionfield AS $(VERSIONCOLUMN), ...
-JDBCConnector.MustUseIDLISTInWHEREClause=Must use $(IDLIST) in WHERE clause.\\nExample: SELECT ... WHERE idfield IN $(IDLIST) ...
+JDBCConnector.MustReturnIDCOLUMNInTheResult=Must return $(IDCOLUMN) in the result.  Example: SELECT idfield AS $(IDCOLUMN) FROM ...
+JDBCConnector.MustReturnVERSIONCOLUMNInTheResult=Must return $(VERSIONCOLUMN) in the result, containing the document version.  Example: SELECT versionfield AS $(VERSIONCOLUMN), ...
+JDBCConnector.MustUseIDLISTInWHEREClause=Must use $(IDLIST) in WHERE clause.  Example: SELECT ... WHERE idfield IN $(IDLIST) ...
 JDBCConnector.EnterADataQuery=Enter a data query
-JDBCConnector.MustReturnIDCOLUMNInTheResult2=Must return $(IDCOLUMN) in the result.\\nExample: SELECT idfield AS $(IDCOLUMN), ...
-JDBCConnector.MustReturnURLCOLUMNInTheResult=Must return $(URLCOLUMN) in the result, containing the url to use to reach the document.\\nExample: SELECT urlfield AS $(URLCOLUMN), ...
-JDBCConnector.MustReturnDATACOLUMNInTheResult=Must return $(DATACOLUMN) in the result, containing the document data.\\nExample: SELECT datafield AS $(DATACOLUMN), ...
-JDBCConnector.MustReturnTOKENCOLUMNInTheResult=Must return $(TOKENCOLUMN) in the result, containing the access token.\\nExample: SELECT actoken AS $(TOKENCOLUMN), ...
+JDBCConnector.MustReturnIDCOLUMNInTheResult2=Must return $(IDCOLUMN) in the result.  Example: SELECT idfield AS $(IDCOLUMN), ...
+JDBCConnector.MustReturnURLCOLUMNInTheResult=Must return $(URLCOLUMN) in the result, containing the url to use to reach the document.  Example: SELECT urlfield AS $(URLCOLUMN), ...
+JDBCConnector.MustReturnDATACOLUMNInTheResult=Must return $(DATACOLUMN) in the result, containing the document data.  Example: SELECT datafield AS $(DATACOLUMN), ...
+JDBCConnector.MustReturnTOKENCOLUMNInTheResult=Must return $(TOKENCOLUMN) in the result, containing the access token.  Example: SELECT actoken AS $(TOKENCOLUMN), ...
 JDBCConnector.DeleteToken=Delete token #
 JDBCConnector.AddAccessToken=Add access token
 JDBCConnector.SeedingQuery=Seeding query:
@@ -62,3 +62,14 @@ JDBCConnector.leaveBlankIfNoSecurityCapa
 JDBCConnector.SecurityColon=Security:
 JDBCConnector.Enabled=Enabled
 JDBCConnector.Disabled=Disabled
+
+JDBCConnector.AttributeQueries=Attribute queries:
+JDBCConnector.AttributeName=Attribute name
+JDBCConnector.AttributeQuery=Attribute query
+JDBCConnector.Delete=Delete
+JDBCConnector.DeleteAttributeQueryNumber=Delete attribute query #
+JDBCConnector.NoAttributeQueries=No attribute queries
+JDBCConnector.Add=Add
+JDBCConnector.AddAttribute=Add attribute
+JDBCConnector.TypeInAnAttributeName=Type in an attribute name
+JDBCConnector.AttributeQueryCannotBeNull=Attribute query must not be null

Modified: manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_es_ES.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_es_ES.properties?rev=1743159&r1=1743158&r2=1743159&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_es_ES.properties (original)
+++ manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_es_ES.properties Tue May 10 11:39:48 2016
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 JDBCConnector.DatabaseType=Tipo de base de datos
-JDBCConnector.AccessMethod=M�todo de acceso
+JDBCConnector.AccessMethod=Método de acceso
 JDBCConnector.ByName=por nombre
 JDBCConnector.ByLabel=por etiqueta
 JDBCConnector.Server=Servidor
@@ -22,15 +22,15 @@ JDBCConnector.Credentials=Credenciales
 JDBCConnector.DatabaseType2=Tipo de base de datos:
 JDBCConnector.DatabaseHostAndPort=Base de datos de host y el puerto:
 JDBCConnector.DatabaseServiceNameOrInstanceDatabase=Base de datos el nombre del servicio o instancia / base de datos:
-JDBCConnector.RawDatabaseConnectString=Base de datos RAW cadena de conexi�n:
+JDBCConnector.RawDatabaseConnectString=Base de datos RAW cadena de conexión:
 JDBCConnector.UserName=nombre de usuario:
-JDBCConnector.Password=Contrase�a:
-JDBCConnector.Parameters=Par�metros:
+JDBCConnector.Password=Contraseña:
+JDBCConnector.Parameters=Paràmetros:
 JDBCConnector.TypeInAnAccessToken=Escriba un token de acceso
 JDBCConnector.Queries=consultas
 JDBCConnector.Security=Seguridad
 JDBCConnector.SeedingQuery=consulta Siembra:
-JDBCConnector.VersionCheckQuery=Pregunta de comprobaci�n de versi�n:
+JDBCConnector.VersionCheckQuery=Pregunta de comprobación de versión:
 JDBCConnector.returnIdsAndVersionsForASetOfDocuments=(devolver los identificadores y las versiones para un conjunto de documentos;
 JDBCConnector.leaveBlankIfNoVersioningCapability=salir si hay capacidad de versiones en blanco)
 JDBCConnector.DataQuery=consulta de datos:
@@ -40,20 +40,20 @@ JDBCConnector.NoAccessTokensPresent=No h
 JDBCConnector.NoAccessTokensSpecified=No hay tokens de acceso especificados
 JDBCConnector.PleaseFillInADatabaseServerName=Por favor, rellene un nombre de servidor de base de datos
 JDBCConnector.PleaseFillInTheNameOfTheDatabase=Por favor escriba el nombre de la base de datos
-JDBCConnector.PleaseSupplyTheDatabaseUsernameForThisConnection=Por favor, facilite el nombre de usuario de base de datos para esta conexi�n
+JDBCConnector.PleaseSupplyTheDatabaseUsernameForThisConnection=Por favor, facilite el nombre de usuario de base de datos para esta conexión
 JDBCConnector.EnterASeedingQuery=Escriba una consulta de siembra
-JDBCConnector.MustReturnIDCOLUMNInTheResult=Debe volver $(ID COLUMNA) en el resultado.\\nEjemplo: SELECCIONAR campo ID AS $(ID DE COLUMNA) DE ...
-JDBCConnector.MustReturnVERSIONCOLUMNInTheResult=Debe volver $(COLUMNA DE VERSI�N) en el resultado, que contiene la versi�n del documento.\\nEjemplo: SELECCIONAR campo de versi�n AS $(COLUMNA DE VERSI�N), ...
-JDBCConnector.MustUseIDLISTInWHEREClause=Debe usar $(LISTA ID) en DONDE cl�usula.\\nEjemplo: SELECCIONAR ... D�NDE campo id IN $(LISTA ID) ...
+JDBCConnector.MustReturnIDCOLUMNInTheResult=Debe volver $(ID COLUMNA) en el resultado.  Ejemplo: SELECCIONAR campo ID AS $(ID DE COLUMNA) DE ...
+JDBCConnector.MustReturnVERSIONCOLUMNInTheResult=Debe volver $(COLUMNA DE VERSIÓN) en el resultado, que contiene la versión del documento.  Ejemplo: SELECCIONAR campo de versión AS $(COLUMNA DE VERSIÓN), ...
+JDBCConnector.MustUseIDLISTInWHEREClause=Debe usar $(LISTA ID) en DONDE cláusula.  Ejemplo: SELECCIONAR ... DÓNDE campo id IN $(LISTA ID) ...
 JDBCConnector.EnterADataQuery=Escriba una consulta de datos
-JDBCConnector.MustReturnIDCOLUMNInTheResult2=Debe volver $(ID COLUMNA) en el resultado.\\nEjemplo: SELECCIONAR campo id AS $(ID DE COLUMNA), ...
-JDBCConnector.MustReturnURLCOLUMNInTheResult=Debe volver $(URL COLUMNA) en el resultado, que contiene la URL a utilizar para alcanzar el documento.\\nEjemplo: SELECCIONAR campo url AS $(URL COLUMNA), ...
-JDBCConnector.MustReturnDATACOLUMNInTheResult=Debe volver $(DATA COLUMNA) en el resultado, que contiene los datos del documento.\\nEjemplo: SELECCIONAR campo de datos AS $(DATOS DE COLUMNA), ...
-JDBCConnector.MustReturnTOKENCOLUMNInTheResult=Debe volver $(TOKEN COLUMNA) en el resultado, que contiene el token de acceso.\\nEjemplo: SELECCIONAR ac token AS $(TOKEN COLUMNA), ...
+JDBCConnector.MustReturnIDCOLUMNInTheResult2=Debe volver $(ID COLUMNA) en el resultado.  Ejemplo: SELECCIONAR campo id AS $(ID DE COLUMNA), ...
+JDBCConnector.MustReturnURLCOLUMNInTheResult=Debe volver $(URL COLUMNA) en el resultado, que contiene la URL a utilizar para alcanzar el documento.  Ejemplo: SELECCIONAR campo url AS $(URL COLUMNA), ...
+JDBCConnector.MustReturnDATACOLUMNInTheResult=Debe volver $(DATA COLUMNA) en el resultado, que contiene los datos del documento.  Ejemplo: SELECCIONAR campo de datos AS $(DATOS DE COLUMNA), ...
+JDBCConnector.MustReturnTOKENCOLUMNInTheResult=Debe volver $(TOKEN COLUMNA) en el resultado, que contiene el token de acceso.  Ejemplo: SELECCIONAR ac token AS $(TOKEN COLUMNA), ...
 JDBCConnector.DeleteToken=eliminar token #
-JDBCConnector.AddAccessToken=A�adir token de acceso
+JDBCConnector.AddAccessToken=Añadir token de acceso
 JDBCConnector.SeedingQuery=consulta Siembra:
-JDBCConnector.VersionCheckQuery=Verificaci�n de la versi�n:
+JDBCConnector.VersionCheckQuery=Verificaciòn de la versiòn:
 JDBCConnector.DataQuery=consulta de datos:
 JDBCConnector.AccessTokens=Tokens de acceso:
 JDBCConnector.AccessTokenQuery=Acceso consulta token:
@@ -62,3 +62,14 @@ JDBCConnector.leaveBlankIfNoSecurityCapa
 JDBCConnector.SecurityColon=Seguridad:
 JDBCConnector.Enabled=Activado
 JDBCConnector.Disabled=Imposibilitado
+
+JDBCConnector.AttributeQueries=Attribute queries:
+JDBCConnector.AttributeName=Attribute name
+JDBCConnector.AttributeQuery=Attribute query
+JDBCConnector.Delete=Delete
+JDBCConnector.DeleteAttributeQueryNumber=Delete attribute query #
+JDBCConnector.NoAttributeQueries=No attribute queries
+JDBCConnector.Add=Add
+JDBCConnector.AddAttribute=Add attribute
+JDBCConnector.TypeInAnAttributeName=Type in an attribute name
+JDBCConnector.AttributeQueryCannotBeNull=Attribute query must not be null

Modified: manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_ja_JP.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_ja_JP.properties?rev=1743159&r1=1743158&r2=1743159&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_ja_JP.properties (original)
+++ manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_ja_JP.properties Tue May 10 11:39:48 2016
@@ -42,14 +42,14 @@ JDBCConnector.PleaseFillInADatabaseServe
 JDBCConnector.PleaseFillInTheNameOfTheDatabase=データベース名を入力しうてください
 JDBCConnector.PleaseSupplyTheDatabaseUsernameForThisConnection=コネクション用のデータベースユーザ名を入力してください
 JDBCConnector.EnterASeedingQuery=シードクエリーを入力してください
-JDBCConnector.MustReturnIDCOLUMNInTheResult=結果に$(IDCOLUMN)を返す必要があります。\\n例:SELECT idfield AS $(IDCOLUMN) FROM ...
-JDBCConnector.MustReturnVERSIONCOLUMNInTheResult=結果にコンテンツのバージョン情報を含む$(VERSIONCOLUMN)を返す必要があります。\\n例:SELECT versionfield AS $(VERSIONCOLUMN), ...
-JDBCConnector.MustUseIDLISTInWHEREClause=WHERE句に$(IDLIST)を使ってください。\\n例:SELECT ... WHERE idfield IN $(IDLIST) ...
+JDBCConnector.MustReturnIDCOLUMNInTheResult=結果に$(IDCOLUMN)を返す必要があります。 例:SELECT idfield AS $(IDCOLUMN) FROM ...
+JDBCConnector.MustReturnVERSIONCOLUMNInTheResult=結果にコンテンツのバージョン情報を含む$(VERSIONCOLUMN)を返す必要があります。 例:SELECT versionfield AS $(VERSIONCOLUMN), ...
+JDBCConnector.MustUseIDLISTInWHEREClause=WHERE句に$(IDLIST)を使ってください。 例:SELECT ... WHERE idfield IN $(IDLIST) ...
 JDBCConnector.EnterADataQuery=データクエリーを入力してください
-JDBCConnector.MustReturnIDCOLUMNInTheResult2=結果に$(IDCOLUMN)を返す必要があります。\\n例:SELECT idfield AS $(IDCOLUMN), ...
-JDBCConnector.MustReturnURLCOLUMNInTheResult=結果にコンテンツを取得するURIを含む$(URLCOLUMN)を返す必要があります。\\n例:SELECT urlfield AS $(URLCOLUMN), ...
-JDBCConnector.MustReturnDATACOLUMNInTheResult=結果にコンテンツ内容を含む$(DATACOLUMN)を返す必要があります。\\n例:SELECT datafield AS $(DATACOLUMN), ...
-JDBCConnector.MustReturnTOKENCOLUMNInTheResult=Must return $(TOKENCOLUMN) in the result, containing the access token.\\nExample: SELECT actoken AS $(TOKENCOLUMN), ...
+JDBCConnector.MustReturnIDCOLUMNInTheResult2=結果に$(IDCOLUMN)を返す必要があります。 例:SELECT idfield AS $(IDCOLUMN), ...
+JDBCConnector.MustReturnURLCOLUMNInTheResult=結果にコンテンツを取得するURIを含む$(URLCOLUMN)を返す必要があります。 例:SELECT urlfield AS $(URLCOLUMN), ...
+JDBCConnector.MustReturnDATACOLUMNInTheResult=結果にコンテンツ内容を含む$(DATACOLUMN)を返す必要があります。 例:SELECT datafield AS $(DATACOLUMN), ...
+JDBCConnector.MustReturnTOKENCOLUMNInTheResult=Must return $(TOKENCOLUMN) in the result, containing the access token.  Example: SELECT actoken AS $(TOKENCOLUMN), ...
 JDBCConnector.DeleteToken=トークンを削除: #
 JDBCConnector.AddAccessToken=アクセストークンを追加
 JDBCConnector.SeedingQuery=シードクエリー:
@@ -62,3 +62,14 @@ JDBCConnector.leaveBlankIfNoSecurityCapa
 JDBCConnector.SecurityColon=Security:
 JDBCConnector.Enabled=Enabled
 JDBCConnector.Disabled=Disabled
+
+JDBCConnector.AttributeQueries=Attribute queries:
+JDBCConnector.AttributeName=Attribute name
+JDBCConnector.AttributeQuery=Attribute query
+JDBCConnector.Delete=Delete
+JDBCConnector.DeleteAttributeQueryNumber=Delete attribute query #
+JDBCConnector.NoAttributeQueries=No attribute queries
+JDBCConnector.Add=Add
+JDBCConnector.AddAttribute=Add attribute
+JDBCConnector.TypeInAnAttributeName=Type in an attribute name
+JDBCConnector.AttributeQueryCannotBeNull=Attribute query must not be null

Modified: manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_zh_CN.properties
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_zh_CN.properties?rev=1743159&r1=1743158&r2=1743159&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_zh_CN.properties (original)
+++ manifoldcf/trunk/connectors/jdbc/connector/src/main/native2ascii/org/apache/manifoldcf/crawler/connectors/jdbc/common_zh_CN.properties Tue May 10 11:39:48 2016
@@ -42,14 +42,14 @@ JDBCConnector.PleaseFillInADatabaseServe
 JDBCConnector.PleaseFillInTheNameOfTheDatabase=请输入数据库名
 JDBCConnector.PleaseSupplyTheDatabaseUsernameForThisConnection=请输入此连接的数据库用户名
 JDBCConnector.EnterASeedingQuery=请输入播种查询
-JDBCConnector.MustReturnIDCOLUMNInTheResult=结果需要返回$(IDCOLUMN)。\\n例: SELECT idfield AS $(IDCOLUMN) FROM ...
-JDBCConnector.MustReturnVERSIONCOLUMNInTheResult=返回结果必须包含文档版本信息$(VERSIONCOLUMN)\\n例: SELECT versionfield AS $(VERSIONCOLUMN), ...
-JDBCConnector.MustUseIDLISTInWHEREClause=WHERE语句务必使用$(IDLIST)。\\n例: SELECT ... WHERE idfield IN $(IDLIST) ...
+JDBCConnector.MustReturnIDCOLUMNInTheResult=结果需要返回$(IDCOLUMN)。 例: SELECT idfield AS $(IDCOLUMN) FROM ...
+JDBCConnector.MustReturnVERSIONCOLUMNInTheResult=返回结果必须包含文档版本信息$(VERSIONCOLUMN)。 例: SELECT versionfield AS $(VERSIONCOLUMN), ...
+JDBCConnector.MustUseIDLISTInWHEREClause=WHERE语句务必使用$(IDLIST)。 例: SELECT ... WHERE idfield IN $(IDLIST) ...
 JDBCConnector.EnterADataQuery=请输入数据查询
-JDBCConnector.MustReturnIDCOLUMNInTheResult2=结果需要返回$(IDCOLUMN)。\\n例: SELECT idfield AS $(IDCOLUMN), ...
-JDBCConnector.MustReturnURLCOLUMNInTheResult=返回结果必须包含取得文档用URI$(URLCOLUMN)。\\n例: SELECT urlfield AS $(URLCOLUMN), ...
-JDBCConnector.MustReturnDATACOLUMNInTheResult=返回结果必须包含文档内容$(DATACOLUMN)。\\n例: SELECT datafield AS $(DATACOLUMN), ...
-JDBCConnector.MustReturnTOKENCOLUMNInTheResult=Must return $(TOKENCOLUMN) in the result, containing the access token.\\nExample: SELECT actoken AS $(TOKENCOLUMN), ...
+JDBCConnector.MustReturnIDCOLUMNInTheResult2=结果需要返回$(IDCOLUMN)。 例: SELECT idfield AS $(IDCOLUMN), ...
+JDBCConnector.MustReturnURLCOLUMNInTheResult=返回结果必须包含取得文档用URI$(URLCOLUMN)。 例: SELECT urlfield AS $(URLCOLUMN), ...
+JDBCConnector.MustReturnDATACOLUMNInTheResult=返回结果必须包含文档内容$(DATACOLUMN)。 例: SELECT datafield AS $(DATACOLUMN), ...
+JDBCConnector.MustReturnTOKENCOLUMNInTheResult=Must return $(TOKENCOLUMN) in the result, containing the access token.  Example: SELECT actoken AS $(TOKENCOLUMN), ...
 JDBCConnector.DeleteToken=删除令牌:  #
 JDBCConnector.AddAccessToken=添加访问令牌
 JDBCConnector.SeedingQuery=播种查询: 
@@ -62,3 +62,14 @@ JDBCConnector.leaveBlankIfNoSecurityCapa
 JDBCConnector.SecurityColon=Security:
 JDBCConnector.Enabled=Enabled
 JDBCConnector.Disabled=Disabled
+
+JDBCConnector.AttributeQueries=Attribute queries:
+JDBCConnector.AttributeName=Attribute name
+JDBCConnector.AttributeQuery=Attribute query
+JDBCConnector.Delete=Delete
+JDBCConnector.DeleteAttributeQueryNumber=Delete attribute query #
+JDBCConnector.NoAttributeQueries=No attribute queries
+JDBCConnector.Add=Add
+JDBCConnector.AddAttribute=Add attribute
+JDBCConnector.TypeInAnAttributeName=Type in an attribute name
+JDBCConnector.AttributeQueryCannotBeNull=Attribute query must not be null

Modified: manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/end-user-documentation.xml
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/end-user-documentation.xml?rev=1743159&r1=1743158&r2=1743159&view=diff
==============================================================================
--- manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/end-user-documentation.xml (original)
+++ manifoldcf/trunk/site/src/documentation/content/xdocs/en_US/end-user-documentation.xml Tue May 10 11:39:48 2016
@@ -1999,15 +1999,16 @@ curl -XGET http://localhost:9200/index/_
                 <br/><br/>
                 <figure src="images/en_US/jdbc-job-queries.PNG" alt="Generic Database Job, Queries tab" width="80%"/>
                 <br/><br/>
-                <p>You must supply at least two queries.  (A third and fourth queries are optional.)  The purpose of these queries is to obtain the data needed for the database to be properly crawled.
+                <p>You must supply at least two queries.  (All other queries are optional.)  The purpose of these queries is to obtain the data needed for the database to be properly crawled.
                        But in order for you to write these queries, you must make some decisions first.  Basically, you need to figure out how best to map the constructs within your database
-                       to the requirements of the Framework.</p>
+                       to the requirements of the Framework.  The following are the sorts of queries you can provide:</p>
                 <br/>
                 <ul>
                     <li>Obtain a list of document identifiers corresponding to changes and additions that occurred within a specified time window (see below)</li>
                     <li>Given a set of document identifiers, find the corresponding version strings (see below)</li>
                     <li>Given a set of document identifiers, find the corresponding list of access tokens for each document identifier (see below)</li>
-                    <li>Given a set of document identifiers and version strings, find information about the document, consisting of the document's data, access URL, and metadata</li>
+                    <li>Given a set of document identifiers, find information about the document, consisting of the document's data, access URL, and metadata</li>
+                    <li>Given a set of document identifiers, find multivalued metadata from the document (multiple such queries)</li>
                 </ul>
                 <br/>
                 <p>The Framework uses a unique document identifier to describe every document within the confines of a defined repository connection.  This document identifier is used
@@ -2089,7 +2090,6 @@ curl -XGET http://localhost:9200/index/_
                 <p><code>SELECT id AS $(IDCOLUMN), characterdata AS $(DATACOLUMN), 'http://mydynamicserver.com?id=' || id AS $(URLCOLUMN), 
                   publisher AS metadata_a, distributor AS metadata_b FROM mytable WHERE id IN $(IDLIST)</code></p>
                 <br/>
-                <p>There is currently no support in the JDBC connection type for natively handling multi-valued metadata.</p>
                 <p>The "Security" tab simply allows you to add specific access tokens to all documents indexed with a general database job.  In order for you to know what tokens
                        to add, you must decide with what authority connection these documents will be secured, and understand the form of the access tokens used by that authority connection
                        type.  This is what the "Security" tab looks like:</p>