Author: kwright
Date: Sat May 16 11:35:14 2015
New Revision: 1679731

URL: http://svn.apache.org/r1679731
Log:
Pull up fix for CONNECTORS-1199 from trunk.

Modified:
    manifoldcf/branches/dev_1x/   (props changed)
    manifoldcf/branches/dev_1x/CHANGES.txt
    
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxClient.java
    
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConfig.java
    
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConnector.java
    
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxDocument.java
    
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxException.java

Propchange: manifoldcf/branches/dev_1x/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat May 16 11:35:14 2015
@@ -123,4 +123,4 @@
 /manifoldcf/branches/CONNECTORS-981:1605049-1605773
 /manifoldcf/branches/CONNECTORS-989:1611600-1612101
 /manifoldcf/branches/CONNECTORS-990:1610284-1610707
-/manifoldcf/trunk:1620703,1620748,1620812,1620862,1621449,1621613,1621855,1622213,1622740,1622850,1622853-1622854,1623249,1623251,1623314,1623599,1623951,1623953-1623954,1623956,1623972,1624058,1624085,1624174,1624236,1624377,1624384,1624399,1624449,1624464,1624504,1624729-1624731,1624906,1624909-1624910,1624982,1625023,1625095,1625103,1625108,1625264,1625270,1625394,1625400,1625910,1626090,1626097,1626102,1626638-1626639,1626973,1627687,1627690,1627959,1628046,1628066,1628106,1628168,1628188,1628699,1628798,1628808,1628845,1628905,1629122,1629374-1629375,1629379,1629541,1629994,1630188,1630535,1630623,1630671,1630812,1630885,1631039,1631162,1631164,1631252,1631750,1631953,1632013,1632225,1632289,1632562,1632844,1632847,1632854,1633062-1633063,1633108,1633193,1633202,1633282,1633284,1633295,1633336,1633339,1633345,1633348,1633364,1633378,1633383,1633432,1633546,1633590,1633634,1633668,1633727,1633760,1633764,1633786,1633910,1633923,1634021,1634028,1634067,1634132,1634145,1634148,163
 
4155,1634188,1634202,1634264,1634373,1634530,1634688,1634850,1634857,1635103,1635116,1635421,1635438,1635478,1635481,1635484,1635490,1635809,1635939,1636146,1636167,1636180,1636207,1636215,1636232,1636334,1636519,1636570,1636684,1636940,1637011,1637310,1637350,1637364,1637373,1637378,1639259,1639593,1639600,1640018,1640101,1640199,1640204,1640208,1640314,1640319,1640749,1640772,1640805,1640888,1640925,1640941-1640942,1641222,1641328,1641557,1641559,1641629,1641633,1641724,1641754,1641911,1642163,1642255,1642318,1642531,1642650,1642658,1642673,1642716,1644197,1644399,1644538,1644920,1644931,1646317,1646397,1646403,1646408,1646640,1646947,1647574,1647585,1647608,1648686,1648976,1649201,1649203,1649529,1649605,1649628,1649794,1650351,1650722,1650741-1650742,1650745,1650747,1650911,1650954,1651332,1651539,1651907,1651921,1652071,1652974,1653175,1653899,1654651,1655205,1655261,1655264,1655377,1655411,1655618,1655914,1657346,1657443,1658004,1658036,1658121,1658155,1658188,1658463,1658476,
 
1660258,1660276,1661454,1665848,1666160,1666781,1666820,1668312,1669100,1669238,1669487,1669523,1669586,1669660,1670614,1670625,1670715,1671496,1672169,1672301,1672616,1672737,1673559,1673573,1673579,1673722,1675781,1675898,1676094,1676882,1676910,1678300,1678329,1678471,1678551
+/manifoldcf/trunk:1620703,1620748,1620812,1620862,1621449,1621613,1621855,1622213,1622740,1622850,1622853-1622854,1623249,1623251,1623314,1623599,1623951,1623953-1623954,1623956,1623972,1624058,1624085,1624174,1624236,1624377,1624384,1624399,1624449,1624464,1624504,1624729-1624731,1624906,1624909-1624910,1624982,1625023,1625095,1625103,1625108,1625264,1625270,1625394,1625400,1625910,1626090,1626097,1626102,1626638-1626639,1626973,1627687,1627690,1627959,1628046,1628066,1628106,1628168,1628188,1628699,1628798,1628808,1628845,1628905,1629122,1629374-1629375,1629379,1629541,1629994,1630188,1630535,1630623,1630671,1630812,1630885,1631039,1631162,1631164,1631252,1631750,1631953,1632013,1632225,1632289,1632562,1632844,1632847,1632854,1633062-1633063,1633108,1633193,1633202,1633282,1633284,1633295,1633336,1633339,1633345,1633348,1633364,1633378,1633383,1633432,1633546,1633590,1633634,1633668,1633727,1633760,1633764,1633786,1633910,1633923,1634021,1634028,1634067,1634132,1634145,1634148,163
 
4155,1634188,1634202,1634264,1634373,1634530,1634688,1634850,1634857,1635103,1635116,1635421,1635438,1635478,1635481,1635484,1635490,1635809,1635939,1636146,1636167,1636180,1636207,1636215,1636232,1636334,1636519,1636570,1636684,1636940,1637011,1637310,1637350,1637364,1637373,1637378,1639259,1639593,1639600,1640018,1640101,1640199,1640204,1640208,1640314,1640319,1640749,1640772,1640805,1640888,1640925,1640941-1640942,1641222,1641328,1641557,1641559,1641629,1641633,1641724,1641754,1641911,1642163,1642255,1642318,1642531,1642650,1642658,1642673,1642716,1644197,1644399,1644538,1644920,1644931,1646317,1646397,1646403,1646408,1646640,1646947,1647574,1647585,1647608,1648686,1648976,1649201,1649203,1649529,1649605,1649628,1649794,1650351,1650722,1650741-1650742,1650745,1650747,1650911,1650954,1651332,1651539,1651907,1651921,1652071,1652974,1653175,1653899,1654651,1655205,1655261,1655264,1655377,1655411,1655618,1655914,1657346,1657443,1658004,1658036,1658121,1658155,1658188,1658463,1658476,
 
1660258,1660276,1661454,1665848,1666160,1666781,1666820,1668312,1669100,1669238,1669487,1669523,1669586,1669660,1670614,1670625,1670715,1671496,1672169,1672301,1672616,1672737,1673559,1673573,1673579,1673722,1675781,1675898,1676094,1676882,1676910,1678300,1678329,1678471,1678551,1679730

Modified: manifoldcf/branches/dev_1x/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/dev_1x/CHANGES.txt?rev=1679731&r1=1679730&r2=1679731&view=diff
==============================================================================
--- manifoldcf/branches/dev_1x/CHANGES.txt (original)
+++ manifoldcf/branches/dev_1x/CHANGES.txt Sat May 16 11:35:14 2015
@@ -3,6 +3,9 @@ $Id$
 
 ======================= 1.10-dev =====================
 
+CONNECTORS-1199: SearchBlox connector formatting non-standard.
+(Karl Wright)
+
 CONNECTORS-1198: SearchBlox connector session management not
 working properly.
 (Timo Selvaraj, Rafa Haro, Karl Wright)

Modified: 
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxClient.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxClient.java?rev=1679731&r1=1679730&r2=1679731&view=diff
==============================================================================
--- 
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxClient.java
 (original)
+++ 
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxClient.java
 Sat May 16 11:35:14 2015
@@ -47,222 +47,215 @@ import org.xml.sax.SAXException;
  */
 public class SearchBloxClient {
 
-    // TODO All this might need to be included in a configuration file
-    public static final String DEFAULT_ENDPOINT = 
"http://localhost:8080/searchblox/rest/v1/api";;
+  // TODO All this might need to be included in a configuration file
+  public static final String DEFAULT_ENDPOINT = 
"http://localhost:8080/searchblox/rest/v1/api";;
 
-    private static final String ADD_PATH = "add";
+  private static final String ADD_PATH = "add";
 
-    private static final String DELETE_PATH = "delete";
+  private static final String DELETE_PATH = "delete";
 
-    private static final String STATUS_PATH = "status";
+  private static final String STATUS_PATH = "status";
 
-    private static final String CREATE_PATH = "coladd";
-
-    private static final String CLEAR_PATH = "clear";
-
-    private static final String STATUS_NODE = "statuscode";
-    
-    private static final Pattern status_pattern = Pattern.compile("^status 
code\\s?:\\s([0-9]+)$");
-
-    public static enum ResponseCode {
-        DOCUMENT_INDEXED(100),
-        DOCUMENT_REJECTED(101),
-        DOCUMENT_DELETED(200, 2001),
-        DOCUMENT_NOT_EXIST(201, 2002),
-        DOCUMENT_NOT_FOUND(301),
-        COLLECTION_CLEARED(400),
-        ERROR_CLEARING_COLLECTION(401),
-        COLLECTION_CREATED(900),
-        INVALID_COLLECTION_NAME(500, 501),
-        INVALID_REQUEST(501),
-        INVALID_DOCUMENT_LOCATION(502),
-        NOT_CUSTOM_COLLECTION(503),
-        LIMIT_EXCEEDED(504),
-        INVALID_LICENSE_ID(601),
-        SERVER_UNREACHABLE(700);
-
-        private int code;
-        private int jsonCode;
-        
-        ResponseCode(int code) {
-            this.code = code;
-        }
-        
-        ResponseCode(int code, int jsonCode) {
-            this.code = code;
-            this.jsonCode = jsonCode;
-        }
-        
-        static ResponseCode getCodeFromValue(int value){
-               for(ResponseCode e:ResponseCode.values())
-                       if(value == e.code)
-                               return e;
-               return null;
-        }
-        
-        static ResponseCode getCodeFromValue(int value, boolean json){
-               for(ResponseCode e:ResponseCode.values())
-                       if((json && value == e.jsonCode) || (value == e.code)) {
-                               return e;
-                       }
-               return null;
-        }
-        
-        int getCode(){
-               return code;
-        }
-        
-        int getJsonCode() {
-               return jsonCode;
-        }
+  private static final String CREATE_PATH = "coladd";
+
+  private static final String CLEAR_PATH = "clear";
+
+  private static final String STATUS_NODE = "statuscode";
+  
+  private static final Pattern status_pattern = Pattern.compile("^status 
code\\s?:\\s([0-9]+)$");
+
+  public static enum ResponseCode {
+    DOCUMENT_INDEXED(100),
+    DOCUMENT_REJECTED(101),
+    DOCUMENT_DELETED(200, 2001),
+    DOCUMENT_NOT_EXIST(201, 2002),
+    DOCUMENT_NOT_FOUND(301),
+    COLLECTION_CLEARED(400),
+    ERROR_CLEARING_COLLECTION(401),
+    COLLECTION_CREATED(900),
+    INVALID_COLLECTION_NAME(500, 501),
+    INVALID_REQUEST(501),
+    INVALID_DOCUMENT_LOCATION(502),
+    NOT_CUSTOM_COLLECTION(503),
+    LIMIT_EXCEEDED(504),
+    INVALID_LICENSE_ID(601),
+    SERVER_UNREACHABLE(700);
+
+    private int code;
+    private int jsonCode;
+    
+    ResponseCode(int code) {
+      this.code = code;
     }
     
-
-    private String apikey;
-    private Client client;
-    private UriBuilder uriBuilder;
-
-    public SearchBloxClient(String apikey, ClientBuilder builder, String 
endpoint) {
-        this.apikey = apikey;
-        builder.register(StringTextStar.class);
-        this.client = builder.build();
-        if (endpoint != null && !endpoint.isEmpty()) {
-            uriBuilder = UriBuilder.fromUri(endpoint);
-        } else {
-            uriBuilder = UriBuilder.fromUri(DEFAULT_ENDPOINT);
+    ResponseCode(int code, int jsonCode) {
+      this.code = code;
+      this.jsonCode = jsonCode;
+    }
+    
+    static ResponseCode getCodeFromValue(int value){
+        for(ResponseCode e:ResponseCode.values())
+            if(value == e.code)
+                return e;
+        return null;
+    }
+    
+    static ResponseCode getCodeFromValue(int value, boolean json){
+      for(ResponseCode e:ResponseCode.values())
+        if((json && value == e.jsonCode) || (value == e.code)) {
+          return e;
         }
+      return null;
+    }
+    
+    int getCode(){
+      return code;
+    }
+    
+    int getJsonCode() {
+      return jsonCode;
     }
+  }
+  
 
+  private String apikey;
+  private Client client;
+  private UriBuilder uriBuilder;
+
+  public SearchBloxClient(String apikey, ClientBuilder builder, String 
endpoint) {
+    this.apikey = apikey;
+    builder.register(StringTextStar.class);
+    this.client = builder.build();
+    if (endpoint != null && !endpoint.isEmpty()) {
+      uriBuilder = UriBuilder.fromUri(endpoint);
+    } else {
+      uriBuilder = UriBuilder.fromUri(DEFAULT_ENDPOINT);
+    }
+  }
+
+
+  public ResponseCode addUpdateDocument(SearchBloxDocument document, String 
format)
+      throws SearchBloxException {
+    return post(document, format, 
SearchBloxDocument.DocumentAction.ADD_UPDATE);
+  }
+
+  public ResponseCode deleteDocument(SearchBloxDocument document, String 
format)
+      throws SearchBloxException {
+    return post(document, format, SearchBloxDocument.DocumentAction.DELETE);
+  }
+
+  public ResponseCode createCollection(String colname, String format)
+      throws SearchBloxException {
+    SearchBloxDocument document = new SearchBloxDocument(apikey);
+    document.colName = colname;
+    return post(document, format, SearchBloxDocument.DocumentAction.CREATE);
+  }
+
+  public ResponseCode clearCollection(String colname, String format)
+      throws SearchBloxException {
+    SearchBloxDocument document = new SearchBloxDocument(apikey);
+    document.colName = colname;
+    return post(document, format, SearchBloxDocument.DocumentAction.CLEAR);
+  }
+
+  public boolean ping(String format)
+      throws SearchBloxException {
+    SearchBloxDocument document = new SearchBloxDocument(apikey);
+    document.colName = UUID.randomUUID().toString();
+    document.uid = UUID.randomUUID().toString();
+    ResponseCode result = post(document, format, 
SearchBloxDocument.DocumentAction.STATUS);
+    return result == ResponseCode.INVALID_COLLECTION_NAME;
+  }
 
-    public ResponseCode addUpdateDocument(SearchBloxDocument document, String 
format)
-            throws SearchBloxException {
-        return post(document, format, 
SearchBloxDocument.DocumentAction.ADD_UPDATE);
-    }
-
-    public ResponseCode deleteDocument(SearchBloxDocument document, String 
format)
-            throws SearchBloxException {
-        return post(document, format, 
SearchBloxDocument.DocumentAction.DELETE);
-    }
-
-    public ResponseCode createCollection(String colname, String format)
-            throws SearchBloxException {
-        SearchBloxDocument document = new SearchBloxDocument(apikey);
-        document.colName = colname;
-        return post(document, format, 
SearchBloxDocument.DocumentAction.CREATE);
-    }
-
-    public ResponseCode clearCollection(String colname, String format)
-            throws SearchBloxException {
-        SearchBloxDocument document = new SearchBloxDocument(apikey);
-        document.colName = colname;
-        return post(document, format, SearchBloxDocument.DocumentAction.CLEAR);
-    }
-
-    public boolean ping(String format)
-            throws SearchBloxException {
-        SearchBloxDocument document = new SearchBloxDocument(apikey);
-        document.colName = UUID.randomUUID().toString();
-        document.uid = UUID.randomUUID().toString();
-        ResponseCode result = post(document, format, 
SearchBloxDocument.DocumentAction.STATUS);
-        return result == ResponseCode.INVALID_COLLECTION_NAME;
-    }
-
-    private ResponseCode post(SearchBloxDocument document, String format, 
SearchBloxDocument.DocumentAction action)
-            throws SearchBloxException {
-        
-       SearchBloxDocument.IndexingFormat iFormat = 
SearchBloxDocument.IndexingFormat.valueOf(format.toUpperCase());
-       
-       if (iFormat == null) {
-            Logging.connectors.error("[Post request] Format not recognized " 
+format);
-            throw new SearchBloxException("Unknown Serialization Format " + 
format);
-        }
-       
-       boolean isJson = iFormat.equals(SearchBloxDocument.IndexingFormat.JSON);
-       
-        
-
-        UriBuilder uri = uriBuilder.clone();
-        if (action == SearchBloxDocument.DocumentAction.ADD_UPDATE) {
-            uri = uri.path(ADD_PATH);
-        } else if (action == SearchBloxDocument.DocumentAction.DELETE) {
-            uri = uri.path(DELETE_PATH);
-        } else if (action == SearchBloxDocument.DocumentAction.STATUS) {
-            uri = uri.path(STATUS_PATH);
-        } else if (action == SearchBloxDocument.DocumentAction.CREATE) {
-            uri = uri.path(CREATE_PATH);
-        } else if (action == SearchBloxDocument.DocumentAction.CLEAR) {
-            uri = uri.path(CLEAR_PATH);
-        }
+  private ResponseCode post(SearchBloxDocument document, String format, 
SearchBloxDocument.DocumentAction action)
+      throws SearchBloxException {
+    
+    SearchBloxDocument.IndexingFormat iFormat = 
SearchBloxDocument.IndexingFormat.valueOf(format.toUpperCase());
+      
+    if (iFormat == null) {
+      Logging.connectors.error("[Post request] Format not recognized " 
+format);
+      throw new SearchBloxException("Unknown Serialization Format " + format);
+    }
+      
+    boolean isJson = iFormat.equals(SearchBloxDocument.IndexingFormat.JSON);
+      
+    
 
-        WebTarget target = client.target(uri.build());
-        Builder httpRequest = target.request();
-        if (iFormat == SearchBloxDocument.IndexingFormat.JSON) {
-               httpRequest.accept(MediaType.APPLICATION_JSON_TYPE);
-        }else{
-               httpRequest.accept(MediaType.APPLICATION_XML_TYPE);
-        }
-        
+    UriBuilder uri = uriBuilder.clone();
+    if (action == SearchBloxDocument.DocumentAction.ADD_UPDATE) {
+      uri = uri.path(ADD_PATH);
+    } else if (action == SearchBloxDocument.DocumentAction.DELETE) {
+      uri = uri.path(DELETE_PATH);
+    } else if (action == SearchBloxDocument.DocumentAction.STATUS) {
+      uri = uri.path(STATUS_PATH);
+    } else if (action == SearchBloxDocument.DocumentAction.CREATE) {
+      uri = uri.path(CREATE_PATH);
+    } else if (action == SearchBloxDocument.DocumentAction.CLEAR) {
+      uri = uri.path(CLEAR_PATH);
+    }
+
+    WebTarget target = client.target(uri.build());
+    Builder httpRequest = target.request();
+    if (iFormat == SearchBloxDocument.IndexingFormat.JSON) {
+      httpRequest.accept(MediaType.APPLICATION_JSON_TYPE);
+    }else{
+      httpRequest.accept(MediaType.APPLICATION_XML_TYPE);
+    }
+    
 
-        document.apiKey = this.apikey;
-        
-        String body = document.toString(iFormat, action);
-        Logging.connectors.debug("Document for document: " + document.uid +":" 
+ body);
-        MediaType type = MediaType.TEXT_PLAIN_TYPE;
-        if (iFormat == SearchBloxDocument.IndexingFormat.JSON) {
-            type = MediaType.APPLICATION_JSON_TYPE;
-        }
+    document.apiKey = this.apikey;
+    
+    String body = document.toString(iFormat, action);
+    Logging.connectors.debug("Document for document: " + document.uid +":" + 
body);
+    MediaType type = MediaType.TEXT_PLAIN_TYPE;
+    if (iFormat == SearchBloxDocument.IndexingFormat.JSON) {
+      type = MediaType.APPLICATION_JSON_TYPE;
+    }
 
-        
-        Entity<String> entity = Entity.entity(body, type);
-        Response response = null;
-        try {
-               response = httpRequest.post(entity);
-        }
-        catch(Exception e) {
-        //     return e.getCause() instanceof ConnectException ? 
ResponseCode.SERVER_UNREACHABLE : ResponseCode.INVALID_COLLECTION_NAME;
-            Logging.connectors.error("[No Connection] Error trying to connect 
",e);
-            return ResponseCode.SERVER_UNREACHABLE;
-        }
-        
-        String rawResponse = response.readEntity(String.class);
-        if(iFormat == IndexingFormat.XML){
-               DOMParser parser = new DOMParser();
-               try {
-                       parser.parse(new InputSource(new 
StringReader(rawResponse)));
-               } catch (SAXException | IOException e) {
-                       Logging.connectors.error("[Response parsing] Dom 
parsing error", e);
-                       throw new SearchBloxException(e);
-               }
-               Document doc = parser.getDocument();
-               NodeList nodeList = doc.getElementsByTagName(STATUS_NODE);
-               if (nodeList == null || nodeList.getLength() == 0) {
-                       String message = "[Response Parsing] Status code not 
found";
-                       Logging.connectors.error(message);
-                       throw new SearchBloxException(message);
-               }
-               String codeStr = nodeList.item(0).getTextContent();
-               int statusCode = Integer.parseInt(codeStr);
-               return ResponseCode.getCodeFromValue(statusCode, isJson);
-        }else{
-//             try {
-//                             JSONObject json = new JSONObject(rawResponse);
-//                             String codeStr = json.getString(STATUS_NODE);
-                       Matcher matcher = status_pattern.matcher(rawResponse);
-                       String codeStr = null;
-                       if(matcher.find())
-                               codeStr = matcher.group(1);
-                       if(codeStr == null){
-                               String message = "[Response parsing] Response 
code parsing error";
-                               Logging.connectors.error(message);
-                       throw new SearchBloxException(message);
-                       }
-                               
-                               int statusCode = Integer.parseInt(codeStr);
-                       return ResponseCode.getCodeFromValue(statusCode, 
isJson);
-//                     } catch (JSONException e) {
-//                             Logging.connectors.error("[Response parsing] 
Response JSON parsing error", e);
-//                     throw new SearchBloxException(e);
-//                     }
-        }
+    
+    Entity<String> entity = Entity.entity(body, type);
+    Response response = null;
+    try {
+      response = httpRequest.post(entity);
+    }
+    catch(Exception e) {
+    //    return e.getCause() instanceof ConnectException ? 
ResponseCode.SERVER_UNREACHABLE : ResponseCode.INVALID_COLLECTION_NAME;
+      Logging.connectors.error("[No Connection] Error trying to connect ",e);
+      return ResponseCode.SERVER_UNREACHABLE;
+    }
+    
+    String rawResponse = response.readEntity(String.class);
+    if(iFormat == IndexingFormat.XML){
+      DOMParser parser = new DOMParser();
+      try {
+        parser.parse(new InputSource(new StringReader(rawResponse)));
+      } catch (SAXException | IOException e) {
+        Logging.connectors.error("[Response parsing] Dom parsing error", e);
+        throw new SearchBloxException(e);
+      }
+      Document doc = parser.getDocument();
+      NodeList nodeList = doc.getElementsByTagName(STATUS_NODE);
+      if (nodeList == null || nodeList.getLength() == 0) {
+        String message = "[Response Parsing] Status code not found";
+        Logging.connectors.error(message);
+        throw new SearchBloxException(message);
+      }
+      String codeStr = nodeList.item(0).getTextContent();
+      int statusCode = Integer.parseInt(codeStr);
+      return ResponseCode.getCodeFromValue(statusCode, isJson);
+    }else{
+      Matcher matcher = status_pattern.matcher(rawResponse);
+      String codeStr = null;
+      if(matcher.find())
+        codeStr = matcher.group(1);
+      if(codeStr == null){
+        String message = "[Response parsing] Response code parsing error";
+        Logging.connectors.error(message);
+        throw new SearchBloxException(message);
+      }
+                
+      int statusCode = Integer.parseInt(codeStr);
+      return ResponseCode.getCodeFromValue(statusCode, isJson);
     }
+  }
 }

Modified: 
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConfig.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConfig.java?rev=1679731&r1=1679730&r2=1679731&view=diff
==============================================================================
--- 
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConfig.java
 (original)
+++ 
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConfig.java
 Sat May 16 11:35:14 2015
@@ -7,12 +7,12 @@ package org.apache.manifoldcf.agents.out
  */
 class SearchBloxConfig {
 
-       static final String NODE_CONFIGURATION = "configuration";
-       static final String ATTRIBUTE_TITLEBOOST = "title_boost";
-       static final String ATTRIBUTE_CONTENTBOOST = "content_boost";
-       static final String ATTRIBUTE_KEYWORDSBOOST = "keywords_boost";
-       static final String ATTRIBUTE_DESCRIPTIONBOOST = "description_boost";
-       static final String ATTRIBUTE_INDEX_FORMAT = "indexformat";
-       static final String ATTRIBUTE_COLLECTION_NAME = "collection";
+  static final String NODE_CONFIGURATION = "configuration";
+  static final String ATTRIBUTE_TITLEBOOST = "title_boost";
+  static final String ATTRIBUTE_CONTENTBOOST = "content_boost";
+  static final String ATTRIBUTE_KEYWORDSBOOST = "keywords_boost";
+  static final String ATTRIBUTE_DESCRIPTIONBOOST = "description_boost";
+  static final String ATTRIBUTE_INDEX_FORMAT = "indexformat";
+  static final String ATTRIBUTE_COLLECTION_NAME = "collection";
 
 }

Modified: 
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConnector.java
URL: 
http://svn.apache.org/viewvc/manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConnector.java?rev=1679731&r1=1679730&r2=1679731&view=diff
==============================================================================
--- 
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConnector.java
 (original)
+++ 
manifoldcf/branches/dev_1x/connectors/searchblox/connector/src/main/java/org/apache/manifoldcf/agents/output/searchblox/SearchBloxConnector.java
 Sat May 16 11:35:14 2015
@@ -43,799 +43,799 @@ import java.util.concurrent.TimeUnit;
  */
 public class SearchBloxConnector extends BaseOutputConnector {
 
-       private final static String SEARCHBLOX_TAB_PARAMETERS = 
"SearchBloxConnector.Parameters";
+  private final static String SEARCHBLOX_TAB_PARAMETERS = 
"SearchBloxConnector.Parameters";
 
-       private static final String EDIT_SPECIFICATION_JS = 
"editSpecification.js";
-       private static final String EDIT_SPECIFICATION_CONFIGURATION_HTML = 
"editSpecification_Configuration.html";
-       private static final String VIEW_SPECIFICATION_HTML = 
"viewSpecification.html";
-
-       /** Forward to the javascript to check the configuration parameters */
-       private static final String EDIT_CONFIG_HEADER_FORWARD = 
"editConfiguration.js";
-
-       /** Forward to the HTML template to edit the configuration parameters */
-       private static final String EDIT_CONFIG_FORWARD_PARAMETERS = 
"editConfiguration_Parameters.html";
-
-       /** Forward to the HTML template to view the configuration parameters */
-       private static final String VIEW_CONFIG_FORWARD = 
"viewConfiguration.html";
-
-       /**
-        * Default collection name
-        */
-       private static final String DEFAULT_COLLECTION = "Custom";
-       
-       /**
-        * Default apiKey
-        */
-       private static final String DEFAULT_APIKEY = "apiKey";
-       
-       /**
-        * Ingestion activity
-        */
-       public final static String INGEST_ACTIVITY = "document ingest";
-
-       /**
-        * Document removal activity
-        */
-       public final static String REMOVE_ACTIVITY = "document deletion";
-
-       /**
-        * Collection Creation activity
-        */
-       public final static String CREATION_ACTIVITY = "collection created";
-
-       
-       private static final String SEARCHBLOX_ENDPOINT = "endpoint";
-       private static final String SEARCHBLOX_INDEXING_FORMAT = "indexformat";
-       private static final String SEARCHBLOX_SOCKET_TIMEOUT = "sockettimeout";
-       private static final String SEARCHBLOX_CONNECTION_TIMEOUT = 
"connectiontimeout";
-       
-       private static final String BUILDER_DEFAULT_SOCKET_TIMEOUT = "60";
-       private static final String BUILDER_DEFAULT_CONNECTION_TIMEOUT = "60";
-
-       private SearchBloxClient client = null;
-       private String apiKey = null;
-
-       public SearchBloxConnector() {
-
-       }
-
-       /** Connect.
-       */
-       @Override
-       public void connect(ConfigParams configParams) {
-               super.connect(configParams);
-       }
-       
-       /**
-        * This method is called to assess whether to count this connector 
instance
-        * should actually be counted as being connected.
-        *
-        * @return true if the connector instance is actually connected.
-        */
-       @Override
-       public boolean isConnected() {
-               return client != null;
-       }
-
-       /**
-        * Close the connection. Call this before discarding the connection.
-        */
-       @Override
-       public void disconnect() throws ManifoldCFException {
-               if (client != null) {
-                       apiKey = null;
-                       client = null;
-               }
-               super.disconnect();
-       }
-
-       /**
-        * Return the list of activities that this connector supports (i.e. 
writes
-        * into the log).
-        *
-        * @return the list.
-        */
-       @Override
-       public String[] getActivitiesList() {
-               return new String[] { INGEST_ACTIVITY, REMOVE_ACTIVITY,
-                               CREATION_ACTIVITY };
-       }
-
-       protected void getSession()
-               throws ManifoldCFException {
-               if (client == null) {
-                       String connectionTimeoutString = 
params.getParameter(SEARCHBLOX_CONNECTION_TIMEOUT);
-                       if (connectionTimeoutString == null)
-                               connectionTimeoutString = 
BUILDER_DEFAULT_CONNECTION_TIMEOUT;
-                       long connectionTimeout;
-                       try {
-                               connectionTimeout = 
Integer.parseInt(connectionTimeoutString);
-                       } catch (NumberFormatException e) {
-                               throw new ManifoldCFException("Bad connection 
timeout: "+e.getMessage(),e);
-                       }
-                       String socketTimeoutString = 
params.getParameter(SEARCHBLOX_SOCKET_TIMEOUT);
-                       if (socketTimeoutString == null)
-                               socketTimeoutString = 
BUILDER_DEFAULT_SOCKET_TIMEOUT;
-                       long socketTimeout;
-                       try {
-                               socketTimeout = 
Integer.parseInt(socketTimeoutString);
-                       } catch (NumberFormatException e) {
-                               throw new ManifoldCFException("Bad socket 
timeout: "+e.getMessage(),e);
-                       }
-                       final String endpoint = 
params.getParameter(SEARCHBLOX_ENDPOINT);
-                       this.apiKey = 
params.getParameter(SearchBloxDocument.API_KEY);
-                       ResteasyClientBuilder builder = new 
ResteasyClientBuilder();
-                       builder.connectionPoolSize(1);
-                       builder.establishConnectionTimeout(connectionTimeout, 
TimeUnit.SECONDS);
-                       builder.socketTimeout(socketTimeout, TimeUnit.SECONDS);
-                       client = new SearchBloxClient(apiKey, builder, 
endpoint);
-               }
-               
-       }
-
-       @Override
-       public String check() throws ManifoldCFException {
-               getSession();
-               try {
-                       String format = 
getConfiguration().getParameter(SEARCHBLOX_INDEXING_FORMAT);
-                       if (client.ping(format)) {
-                               return super.check();
-                       } else {
-                               return "Connection Not Working!. Check 
SearchBlox Server is up and the configuration is correct.";
-                       }
-               } catch (SearchBloxException e) {
-                       Logging.connectors.error("Connection Not Working", e);
-                       return "Connection Not Working!" + e.getMessage();
-               }
-       }
-
-       /**
-        * Get an output version string, given an output specification. The 
output
-        * version string is used to uniquely describe the pertinent details of 
the
-        * output specification and the configuration, to allow the Connector
-        * Framework to determine whether a document will need to be output 
again.
-        * Note that the contents of the document cannot be considered by this
-        * method, and that a different version string (defined in
-        * IRepositoryConnector) is used to describe the version of the actual
-        * document.
-        * <p/>
-        * This method presumes that the connector object has been configured, 
and
-        * it is thus able to communicate with the output data store should 
that be
-        * necessary.
-        *
-        * @param spec
-        *            is the current output specification for the job that is 
doing
-        *            the crawling.
-        * @return a string, of unlimited length, which uniquely describes 
output
-        *         configuration and specification in such a way that if two 
such
-        *         strings are equal, the document will not need to be sent 
again to
-        *         the output data store.
-        */
-       @Override
-       public VersionContext getPipelineDescription(Specification spec)
-                       throws ManifoldCFException, ServiceInterruption {
-               SpecPacker sp = new SpecPacker(spec);
-               return new VersionContext(sp.toPackedString(), params, spec);
-       }
-
-       /**
-        * Detect if a mime type is indexable or not. This method is used by
-        * participating repository connectors to pre-filter the number of 
unusable
-        * documents that will be passed to this output connector.
-        *
-        * @param outputDescription
-        *            is the document's output version.
-        * @param mimeType
-        *            is the mime type of the document.
-        * @return true if the mime type is indexable by this connector.
-        */
-       @Override
-       public boolean checkMimeTypeIndexable(VersionContext outputDescription,
-                       String mimeType, IOutputCheckActivity activities)
-                       throws ManifoldCFException, ServiceInterruption {
-               // We work against the API, so we need to suppose the content 
reached by
-               // the connector is a String convertible stream
-               return true;
-       }
-
-       /**
-        * Pre-determine whether a document's length is indexable by this 
connector.
-        * This method is used by participating repository connectors to help 
filter
-        * out documents that are too long to be indexable.
-        *
-        * @param outputDescription
-        *            is the document's output version.
-        * @param length
-        *            is the length of the document.
-        * @return true if the file is indexable.
-        */
-       @Override
-       public boolean checkLengthIndexable(VersionContext outputDescription,
-                       long length, IOutputCheckActivity activities)
-                       throws ManifoldCFException, ServiceInterruption {
-               // No Size Limit for SearchBlox
-               return true;
-       }
-
-       /**
-        * Add (or replace) a document in the output data store using the 
connector.
-        * This method presumes that the connector object has been configured, 
and
-        * it is thus able to communicate with the output data store should 
that be
-        * necessary.
-        *
-        * @param documentURI
-        *            is the URI of the document. The URI is presumed to be the
-        *            unique identifier which the output data store will use to
-        *            process and serve the document. This URI is constructed 
by the
-        *            repository connector which fetches the document, and is 
thus
-        *            universal across all output connectors.
-        * @param pipelineDescription
-        *            includes the description string that was constructed for 
this
-        *            document by the getOutputDescription() method.
-        * @param document
-        *            is the document data to be processed (handed to the output
-        *            data store).
-        * @param authorityNameString
-        *            is the name of the authority responsible for authorizing 
any
-        *            access tokens passed in with the repository document. May 
be
-        *            null.
-        * @param activities
-        *            is the handle to an object that the implementer of a 
pipeline
-        *            connector may use to perform operations, such as logging
-        *            processing activity, or sending a modified document to the
-        *            next stage in the pipeline.
-        * @return the document status (accepted or permanently rejected).
-        * @throws IOException
-        *             only if there's a stream error reading the document data.
-        */
-       @Override
-       public int addOrReplaceDocumentWithException(String documentURI,
-                       VersionContext pipelineDescription, RepositoryDocument 
document,
-                       String authorityNameString, IOutputAddActivity 
activities)
-                       throws ManifoldCFException, ServiceInterruption, 
IOException {
-
-               Logging.connectors.info("Indexing Document " + documentURI);
-               long indexingTime = System.currentTimeMillis();
-               SpecPacker sp = new 
SpecPacker(pipelineDescription.getSpecification());
-               Map<String, List<String>> args = sp.getArgs();
-               // Establish a session
-               getSession();
-
-               SearchBloxDocument sbDoc = new SearchBloxDocument(this.apiKey,
-                               documentURI, document, args);
-               String format = 
this.getConfiguration().getParameter(SEARCHBLOX_INDEXING_FORMAT);
-               long startTime = System.currentTimeMillis();
-               try {
-                       ResponseCode code = client.addUpdateDocument(sbDoc, 
format);
-                       if (code == ResponseCode.DOCUMENT_INDEXED) {
+  private static final String EDIT_SPECIFICATION_JS = "editSpecification.js";
+  private static final String EDIT_SPECIFICATION_CONFIGURATION_HTML = 
"editSpecification_Configuration.html";
+  private static final String VIEW_SPECIFICATION_HTML = 
"viewSpecification.html";
+
+  /** Forward to the javascript to check the configuration parameters */
+  private static final String EDIT_CONFIG_HEADER_FORWARD = 
"editConfiguration.js";
+
+  /** Forward to the HTML template to edit the configuration parameters */
+  private static final String EDIT_CONFIG_FORWARD_PARAMETERS = 
"editConfiguration_Parameters.html";
+
+  /** Forward to the HTML template to view the configuration parameters */
+  private static final String VIEW_CONFIG_FORWARD = "viewConfiguration.html";
+
+  /**
+   * Default collection name
+   */
+  private static final String DEFAULT_COLLECTION = "Custom";
+  
+  /**
+   * Default apiKey
+   */
+  private static final String DEFAULT_APIKEY = "apiKey";
+  
+  /**
+   * Ingestion activity
+   */
+  public final static String INGEST_ACTIVITY = "document ingest";
+
+  /**
+   * Document removal activity
+   */
+  public final static String REMOVE_ACTIVITY = "document deletion";
+
+  /**
+   * Collection Creation activity
+   */
+  public final static String CREATION_ACTIVITY = "collection created";
+
+  
+  private static final String SEARCHBLOX_ENDPOINT = "endpoint";
+  private static final String SEARCHBLOX_INDEXING_FORMAT = "indexformat";
+  private static final String SEARCHBLOX_SOCKET_TIMEOUT = "sockettimeout";
+  private static final String SEARCHBLOX_CONNECTION_TIMEOUT = 
"connectiontimeout";
+  
+  private static final String BUILDER_DEFAULT_SOCKET_TIMEOUT = "60";
+  private static final String BUILDER_DEFAULT_CONNECTION_TIMEOUT = "60";
+
+  private SearchBloxClient client = null;
+  private String apiKey = null;
+
+  public SearchBloxConnector() {
+
+  }
+
+  /** Connect.
+  */
+  @Override
+  public void connect(ConfigParams configParams) {
+    super.connect(configParams);
+  }
+  
+  /**
+   * This method is called to assess whether to count this connector instance
+   * should actually be counted as being connected.
+   *
+   * @return true if the connector instance is actually connected.
+   */
+  @Override
+  public boolean isConnected() {
+    return client != null;
+  }
+
+  /**
+   * Close the connection. Call this before discarding the connection.
+   */
+  @Override
+  public void disconnect() throws ManifoldCFException {
+    if (client != null) {
+      apiKey = null;
+      client = null;
+    }
+    super.disconnect();
+  }
+
+  /**
+   * Return the list of activities that this connector supports (i.e. writes
+   * into the log).
+   *
+   * @return the list.
+   */
+  @Override
+  public String[] getActivitiesList() {
+    return new String[] { INGEST_ACTIVITY, REMOVE_ACTIVITY,
+        CREATION_ACTIVITY };
+  }
+
+  protected void getSession()
+    throws ManifoldCFException {
+    if (client == null) {
+      String connectionTimeoutString = 
params.getParameter(SEARCHBLOX_CONNECTION_TIMEOUT);
+      if (connectionTimeoutString == null)
+        connectionTimeoutString = BUILDER_DEFAULT_CONNECTION_TIMEOUT;
+      long connectionTimeout;
+      try {
+        connectionTimeout = Integer.parseInt(connectionTimeoutString);
+      } catch (NumberFormatException e) {
+        throw new ManifoldCFException("Bad connection timeout: 
"+e.getMessage(),e);
+      }
+      String socketTimeoutString = 
params.getParameter(SEARCHBLOX_SOCKET_TIMEOUT);
+      if (socketTimeoutString == null)
+        socketTimeoutString = BUILDER_DEFAULT_SOCKET_TIMEOUT;
+      long socketTimeout;
+      try {
+        socketTimeout = Integer.parseInt(socketTimeoutString);
+      } catch (NumberFormatException e) {
+        throw new ManifoldCFException("Bad socket timeout: "+e.getMessage(),e);
+      }
+      final String endpoint = params.getParameter(SEARCHBLOX_ENDPOINT);
+      this.apiKey = params.getParameter(SearchBloxDocument.API_KEY);
+      ResteasyClientBuilder builder = new ResteasyClientBuilder();
+      builder.connectionPoolSize(1);
+      builder.establishConnectionTimeout(connectionTimeout, TimeUnit.SECONDS);
+      builder.socketTimeout(socketTimeout, TimeUnit.SECONDS);
+      client = new SearchBloxClient(apiKey, builder, endpoint);
+    }
+    
+  }
+
+  @Override
+  public String check() throws ManifoldCFException {
+    getSession();
+    try {
+      String format = 
getConfiguration().getParameter(SEARCHBLOX_INDEXING_FORMAT);
+      if (client.ping(format)) {
+        return super.check();
+      } else {
+        return "Connection Not Working!. Check SearchBlox Server is up and the 
configuration is correct.";
+      }
+    } catch (SearchBloxException e) {
+      Logging.connectors.error("Connection Not Working", e);
+      return "Connection Not Working!" + e.getMessage();
+    }
+  }
+
+  /**
+   * Get an output version string, given an output specification. The output
+   * version string is used to uniquely describe the pertinent details of the
+   * output specification and the configuration, to allow the Connector
+   * Framework to determine whether a document will need to be output again.
+   * Note that the contents of the document cannot be considered by this
+   * method, and that a different version string (defined in
+   * IRepositoryConnector) is used to describe the version of the actual
+   * document.
+   * <p/>
+   * This method presumes that the connector object has been configured, and
+   * it is thus able to communicate with the output data store should that be
+   * necessary.
+   *
+   * @param spec
+   *            is the current output specification for the job that is doing
+   *            the crawling.
+   * @return a string, of unlimited length, which uniquely describes output
+   *         configuration and specification in such a way that if two such
+   *         strings are equal, the document will not need to be sent again to
+   *         the output data store.
+   */
+  @Override
+  public VersionContext getPipelineDescription(Specification spec)
+      throws ManifoldCFException, ServiceInterruption {
+    SpecPacker sp = new SpecPacker(spec);
+    return new VersionContext(sp.toPackedString(), params, spec);
+  }
+
+  /**
+   * Detect if a mime type is indexable or not. This method is used by
+   * participating repository connectors to pre-filter the number of unusable
+   * documents that will be passed to this output connector.
+   *
+   * @param outputDescription
+   *            is the document's output version.
+   * @param mimeType
+   *            is the mime type of the document.
+   * @return true if the mime type is indexable by this connector.
+   */
+  @Override
+  public boolean checkMimeTypeIndexable(VersionContext outputDescription,
+      String mimeType, IOutputCheckActivity activities)
+      throws ManifoldCFException, ServiceInterruption {
+    // We work against the API, so we need to suppose the content reached by
+    // the connector is a String convertible stream
+    return true;
+  }
+
+  /**
+   * Pre-determine whether a document's length is indexable by this connector.
+   * This method is used by participating repository connectors to help filter
+   * out documents that are too long to be indexable.
+   *
+   * @param outputDescription
+   *            is the document's output version.
+   * @param length
+   *            is the length of the document.
+   * @return true if the file is indexable.
+   */
+  @Override
+  public boolean checkLengthIndexable(VersionContext outputDescription,
+      long length, IOutputCheckActivity activities)
+      throws ManifoldCFException, ServiceInterruption {
+    // No Size Limit for SearchBlox
+    return true;
+  }
+
+  /**
+   * Add (or replace) a document in the output data store using the connector.
+   * This method presumes that the connector object has been configured, and
+   * it is thus able to communicate with the output data store should that be
+   * necessary.
+   *
+   * @param documentURI
+   *            is the URI of the document. The URI is presumed to be the
+   *            unique identifier which the output data store will use to
+   *            process and serve the document. This URI is constructed by the
+   *            repository connector which fetches the document, and is thus
+   *            universal across all output connectors.
+   * @param pipelineDescription
+   *            includes the description string that was constructed for this
+   *            document by the getOutputDescription() method.
+   * @param document
+   *            is the document data to be processed (handed to the output
+   *            data store).
+   * @param authorityNameString
+   *            is the name of the authority responsible for authorizing any
+   *            access tokens passed in with the repository document. May be
+   *            null.
+   * @param activities
+   *            is the handle to an object that the implementer of a pipeline
+   *            connector may use to perform operations, such as logging
+   *            processing activity, or sending a modified document to the
+   *            next stage in the pipeline.
+   * @return the document status (accepted or permanently rejected).
+   * @throws IOException
+   *             only if there's a stream error reading the document data.
+   */
+  @Override
+  public int addOrReplaceDocumentWithException(String documentURI,
+      VersionContext pipelineDescription, RepositoryDocument document,
+      String authorityNameString, IOutputAddActivity activities)
+      throws ManifoldCFException, ServiceInterruption, IOException {
+
+    Logging.connectors.info("Indexing Document " + documentURI);
+    long indexingTime = System.currentTimeMillis();
+    SpecPacker sp = new SpecPacker(pipelineDescription.getSpecification());
+    Map<String, List<String>> args = sp.getArgs();
+    // Establish a session
+    getSession();
+
+    SearchBloxDocument sbDoc = new SearchBloxDocument(this.apiKey,
+        documentURI, document, args);
+    String format = 
this.getConfiguration().getParameter(SEARCHBLOX_INDEXING_FORMAT);
+    long startTime = System.currentTimeMillis();
+    try {
+      ResponseCode code = client.addUpdateDocument(sbDoc, format);
+      if (code == ResponseCode.DOCUMENT_INDEXED) {
                 Logging.connectors.info("Document Indexed" + documentURI);
-                               activities.recordActivity(startTime, 
INGEST_ACTIVITY, null,
-                                               documentURI, "OK", "Document 
Indexed");}
-                       else
-                               activities.recordActivity(startTime, 
INGEST_ACTIVITY, null,
-                                               documentURI, "" + 
code.getCode(), code.name());
-               } catch (SearchBloxException e) {
-                       Logging.connectors
-                                       .error("[Indexing - Add] Exception 
indexing document :"
-                                                       + document, e);
-                       String activityCode = e.getClass().getSimpleName()
-                                       .toUpperCase(Locale.ROOT);
-                       String activityDetails = e.getMessage()
-                                       + ((e.getCause() != null) ? ": "
-                                                       + 
e.getCause().getMessage() : "");
-                       activities.recordActivity(startTime, INGEST_ACTIVITY, 
null,
-                                       documentURI, activityCode, 
activityDetails);
-                       return DOCUMENTSTATUS_REJECTED;
-               }
-               indexingTime = System.currentTimeMillis() - indexingTime;
-               Logging.connectors.info("Indexing Time for document " + 
documentURI + ": " + indexingTime);
-               return DOCUMENTSTATUS_ACCEPTED;
-       }
-
-       /**
-        * Remove a document using the connector. Note that the last
-        * outputDescription is included, since it may be necessary for the
-        * connector to use such information to know how to properly remove the
-        * document.
-        *
-        * @param documentURI
-        *            is the URI of the document. The URI is presumed to be the
-        *            unique identifier which the output data store will use to
-        *            process and serve the document. This URI is constructed 
by the
-        *            repository connector which fetches the document, and is 
thus
-        *            universal across all output connectors.
-        * @param outputDescription
-        *            is the last description string that was constructed for 
this
-        *            document by the getOutputDescription() method above.
-        * @param activities
-        *            is the handle to an object that the implementer of an 
output
-        *            connector may use to perform operations, such as logging
-        *            processing activity.
-        */
-       @Override
-       public void removeDocument(String documentURI, String outputDescription,
-                       IOutputRemoveActivity activities) throws 
ManifoldCFException,
-                       ServiceInterruption {
-               Logging.ingest.debug("Deleting SearchBlox Document: '" + 
documentURI
-                               + "'");
-
-               SpecPacker packer = new SpecPacker(outputDescription);
-               Map<String, List<String>> args = packer.getArgs();
-               // Establish a session
-               getSession();
-               
-               SearchBloxDocument document = new 
SearchBloxDocument(this.apiKey);
-               document.uid = documentURI;
-               // document.apiKey = args.get(API_KEY).get(0);
-               document.colName = 
args.get(SearchBloxDocument.SEARCHBLOX_COLLECTION).get(0);
-               String format = args.get(SEARCHBLOX_INDEXING_FORMAT).get(0);
-               long startTime = System.currentTimeMillis();
-               try {
-                       ResponseCode code = client.deleteDocument(document, 
format);
-                       if (code == ResponseCode.DOCUMENT_DELETED)
-                               activities.recordActivity(startTime, 
REMOVE_ACTIVITY, null,
-                                               documentURI, "OK", "Document 
Deleted");
-                       else
-                               activities.recordActivity(startTime, 
REMOVE_ACTIVITY, null,
-                                               documentURI, "" + 
code.getCode(), code.name());
-               } catch (SearchBloxException e) {
-                       Logging.connectors.error(
-                                       "[Indexing - Remove] Exception indexing 
document :"
-                                                       + document, e);
-                       String activityCode = e.getClass().getSimpleName()
-                                       .toUpperCase(Locale.ROOT);
-                       String activityDetails = e.getMessage()
-                                       + ((e.getCause() != null) ? ": "
-                                                       + 
e.getCause().getMessage() : "");
-                       activities.recordActivity(startTime, REMOVE_ACTIVITY, 
null,
-                                       documentURI, activityCode, 
activityDetails);
-               }
-       }
-
-       /**
-        * Read the content of a resource, replace the variable ${PARAMNAME} 
with
-        * the value and copy it to the out.
-        * 
-        * @param resName
-        * @param out
-        * @throws ManifoldCFException
-        */
-       private static void outputResource(String resName, IHTTPOutput out,
-                       Locale locale, Map<String, String> params, String 
tabName,
-                       Integer sequenceNumber, Integer currentSequenceNumber)
-                       throws ManifoldCFException {
-               Map<String, String> paramMap = null;
-               if (params != null) {
-                       paramMap = params;
-                       if (tabName != null) {
-                               paramMap.put("TabName", tabName);
-                       }
-                       if (currentSequenceNumber != null)
-                               paramMap.put("SelectedNum", 
currentSequenceNumber.toString());
-               } else {
-                       paramMap = new HashMap<String, String>();
-               }
-               if (sequenceNumber != null)
-                       paramMap.put("SeqNum", sequenceNumber.toString());
-
-               Messages.outputResourceWithVelocity(out, locale, resName, 
paramMap,
-                               true);
-       }
-
-       @Override
-       public void outputConfigurationHeader(IThreadContext threadContext,
-                       IHTTPOutput out, Locale locale, ConfigParams parameters,
-                       List<String> tabsArray) throws ManifoldCFException, 
IOException {
-               super.outputConfigurationHeader(threadContext, out, locale, 
parameters,
-                               tabsArray);
-               tabsArray.add(Messages.getString(locale, 
SEARCHBLOX_TAB_PARAMETERS));
-               outputResource(EDIT_CONFIG_HEADER_FORWARD, out, locale, null, 
null,
-                               null, null);
-       }
-
-       @Override
-       public void outputConfigurationBody(IThreadContext threadContext,
-                       IHTTPOutput out, Locale locale, ConfigParams parameters,
-                       String tabName) throws ManifoldCFException, IOException 
{
-               super.outputConfigurationBody(threadContext, out, locale, 
parameters,
-                               tabName);
-               Map<String, String> config = getConfigParameters(parameters);
-               outputResource(EDIT_CONFIG_FORWARD_PARAMETERS, out, locale, 
config,
-                               tabName, null, null);
-       }
-
-       /**
-        * Build a Map of SearchBlox parameters. If configParams is null,
-        * getConfiguration() is used.
-        * 
-        * @param configParams
-        */
-       final private Map<String, String> getConfigParameters(
-                       ConfigParams configParams) {
-               Map<String, String> map = new HashMap<String, String>();
-
-               String apiKey = 
configParams.getParameter(SearchBloxDocument.API_KEY);
-               if(apiKey == null)
-                       apiKey = DEFAULT_APIKEY;
-               map.put(SearchBloxDocument.API_KEY, apiKey);
-               
-               String endpoint = 
configParams.getParameter(SEARCHBLOX_ENDPOINT);
-               if(endpoint == null) {
-                       endpoint = SearchBloxClient.DEFAULT_ENDPOINT;
-               }
-               map.put(SEARCHBLOX_ENDPOINT,
-                               endpoint);
-               
-               String indexFormat = 
configParams.getParameter(SEARCHBLOX_INDEXING_FORMAT);
-               if (indexFormat == null) {
-                       indexFormat = IndexingFormat.JSON.name();
-               }
-               map.put(SEARCHBLOX_INDEXING_FORMAT, indexFormat);
-               
-               String connectionTimeout = 
configParams.getParameter(SEARCHBLOX_CONNECTION_TIMEOUT);
-               if (connectionTimeout == null) {
-                       connectionTimeout = BUILDER_DEFAULT_CONNECTION_TIMEOUT;
-               }
-               map.put(SEARCHBLOX_CONNECTION_TIMEOUT, connectionTimeout);
-               
-               String socketTimeout = 
configParams.getParameter(SEARCHBLOX_SOCKET_TIMEOUT);
-               if (socketTimeout == null) {
-                       socketTimeout = BUILDER_DEFAULT_SOCKET_TIMEOUT;
-               }
-               map.put(SEARCHBLOX_SOCKET_TIMEOUT, socketTimeout);
-               
-               return map;
-       }
-
-       @Override
-       public void viewConfiguration(IThreadContext threadContext,
-                       IHTTPOutput out, Locale locale, ConfigParams parameters)
-                       throws ManifoldCFException, IOException {
-               outputResource(VIEW_CONFIG_FORWARD, out, locale,
-                               getConfigParameters(parameters), null, null, 
null);
-       }
-
-       /**
-        * Process a configuration post. This method is called at the start of 
the
-        * connector's configuration page, whenever there is a possibility that 
form
-        * data for a connection has been posted. Its purpose is to gather form
-        * information and modify the configuration parameters accordingly. The 
name
-        * of the posted form is "editconnection".
-        *
-        * @param threadContext
-        *            is the local thread context.
-        * @param variableContext
-        *            is the set of variables available from the post, including
-        *            binary file post information.
-        * @param parameters
-        *            are the configuration parameters, as they currently 
exist, for
-        *            this connection being configured.
-        * @return null if all is well, or a string error message if there is an
-        *         error that should prevent saving of the connection (and 
cause a
-        *         redirection to an error page).
-        */
-       @Override
-       public String processConfigurationPost(IThreadContext threadContext,
-                       IPostParameters variableContext, Locale locale,
-                       ConfigParams parameters) throws ManifoldCFException {
-               String apiKey = 
variableContext.getParameter(SearchBloxDocument.API_KEY);
-               if (apiKey != null)
-                       parameters.setParameter(SearchBloxDocument.API_KEY, 
apiKey);
-
-               String endpoint = 
variableContext.getParameter(SEARCHBLOX_ENDPOINT);
-               if (endpoint != null)
-                       parameters.setParameter(SEARCHBLOX_ENDPOINT, endpoint);
-               
-               String indexformat = 
variableContext.getParameter(SEARCHBLOX_INDEXING_FORMAT);
-               if (indexformat != null)
-                       parameters.setParameter(SEARCHBLOX_INDEXING_FORMAT, 
indexformat);
-
-               String connectionTimeout = 
variableContext.getParameter(SEARCHBLOX_CONNECTION_TIMEOUT);
-               if (connectionTimeout != null)
-                       parameters.setParameter(SEARCHBLOX_CONNECTION_TIMEOUT, 
connectionTimeout);
-               
-               String socketTimeout = 
variableContext.getParameter(SEARCHBLOX_SOCKET_TIMEOUT);
-               if (socketTimeout != null)
-                       parameters.setParameter(SEARCHBLOX_SOCKET_TIMEOUT, 
socketTimeout);
-               
-               return null;
-       }
-
-       /**
-        * Output the specification header section. This method is called in the
-        * head section of a job page which has selected a pipeline connection 
of
-        * the current type. Its purpose is to add the required tabs to the 
list,
-        * and to output any javascript methods that might be needed by the job
-        * editing HTML.
-        *
-        * @param out
-        *            is the output to which any HTML should be sent.
-        * @param locale
-        *            is the preferred local of the output.
-        * @param os
-        *            is the current pipeline specification for this connection.
-        * @param connectionSequenceNumber
-        *            is the unique number of this connection within the job.
-        * @param tabsArray
-        *            is an array of tab names. Add to this array any tab names 
that
-        *            are specific to the connector.
-        */
-       @Override
-       public void outputSpecificationHeader(IHTTPOutput out, Locale locale,
-                       Specification os, int connectionSequenceNumber,
-                       List<String> tabsArray) throws ManifoldCFException, 
IOException {
-               Map<String, Object> paramMap = new HashMap<String, Object>();
-               paramMap.put("SEQNUM", 
Integer.toString(connectionSequenceNumber));
-
-               tabsArray.add(Messages.getString(locale,
-                               "SearchBloxConnector.Configuration"));
-
-               // Fill in the specification header map, using data from all 
tabs.
-               fillInSpecificationMap(paramMap, os);
-
-               Messages.outputResourceWithVelocity(out, locale, 
EDIT_SPECIFICATION_JS,
-                               paramMap);
-       }
-
-       private void fillInSpecificationMap(
-                       Map<String, Object> paramMap, Specification os) {
-
-               for (int i = 0, len = os.getChildCount(); i < len; i++) {
-                       SpecificationNode sn = os.getChild(i);
-                       if 
(sn.getType().equals(SearchBloxConfig.NODE_CONFIGURATION)) {
-
-                               String titleBoost = sn
-                                               
.getAttributeValue(SearchBloxConfig.ATTRIBUTE_TITLEBOOST);
-                               if (titleBoost == null || titleBoost.isEmpty())
-                                       titleBoost = "0";
-                               String contentBoost = sn
-                                               
.getAttributeValue(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST);
-                               if (contentBoost == null || 
contentBoost.isEmpty())
-                                       contentBoost = "0";
-                               String keywordsBoost = sn
-                                               
.getAttributeValue(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST);
-                               if (keywordsBoost == null || 
keywordsBoost.isEmpty())
-                                       keywordsBoost = "0";
-                               String descriptionBoost = sn
-                                               
.getAttributeValue(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST);
-                               if (descriptionBoost == null || 
descriptionBoost.isEmpty())
-                                       descriptionBoost = "0";
-
-                               String collection = sn
-                                               
.getAttributeValue(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME);
-                               if (collection == null)
-                                       collection = DEFAULT_COLLECTION;
-                               
-                               
paramMap.put(SearchBloxConfig.ATTRIBUTE_TITLEBOOST.toUpperCase(),
-                                               titleBoost);
-                               
paramMap.put(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST.toUpperCase(),
-                                               contentBoost);
-                               
paramMap.put(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST.toUpperCase(),
-                                               keywordsBoost);
-                               
paramMap.put(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST.toUpperCase(),
-                                               descriptionBoost);
-                               
paramMap.put(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME
-                                               .toUpperCase(), collection);
-
-                               return;
-                       }
-
-               }
-
-               
paramMap.put(SearchBloxConfig.ATTRIBUTE_TITLEBOOST.toUpperCase(), 0);
-               
paramMap.put(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST.toUpperCase(), 0);
-               
paramMap.put(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST.toUpperCase(), 0);
-               
paramMap.put(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST.toUpperCase(), 0);
-               
paramMap.put(SearchBloxConfig.ATTRIBUTE_INDEX_FORMAT.toUpperCase(),
-                               IndexingFormat.XML.name());
-               
paramMap.put(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME.toUpperCase(),
-                               "");
-
-       }
-
-       /**
-        * View specification. This method is called in the body section of a 
job's
-        * view page. Its purpose is to present the pipeline specification
-        * information to the user. The coder can presume that the HTML that is
-        * output from this configuration will be within appropriate <html> and
-        * <body> tags.
-        *
-        * @param out
-        *            is the output to which any HTML should be sent.
-        * @param locale
-        *            is the preferred local of the output.
-        * @param connectionSequenceNumber
-        *            is the unique number of this connection within the job.
-        * @param os
-        *            is the current pipeline specification for this job.
-        */
-       @Override
-       public void viewSpecification(IHTTPOutput out, Locale locale,
-                       Specification os, int connectionSequenceNumber)
-                       throws ManifoldCFException, IOException {
-               Map<String, Object> paramMap = new HashMap<String, Object>();
-               paramMap.put("SEQNUM", 
Integer.toString(connectionSequenceNumber));
-
-               // Fill in the map with data from all tabs
-               fillInSpecificationMap(paramMap, os);
-
-               Messages.outputResourceWithVelocity(out, locale,
-                               VIEW_SPECIFICATION_HTML, paramMap);
-
-       }
-
-       /**
-        * Output the specification body section. This method is called in the 
body
-        * section of a job page which has selected a pipeline connection of the
-        * current type. Its purpose is to present the required form elements 
for
-        * editing. The coder can presume that the HTML that is output from this
-        * configuration will be within appropriate <html>, <body>, and <form> 
tags.
-        * The name of the form is "editjob".
-        *
-        * @param out
-        *            is the output to which any HTML should be sent.
-        * @param locale
-        *            is the preferred local of the output.
-        * @param os
-        *            is the current pipeline specification for this job.
-        * @param connectionSequenceNumber
-        *            is the unique number of this connection within the job.
-        * @param actualSequenceNumber
-        *            is the connection within the job that has currently been
-        *            selected.
-        * @param tabName
-        *            is the current tab name.
-        */
-       @Override
-       public void outputSpecificationBody(IHTTPOutput out, Locale locale,
-                       Specification os, int connectionSequenceNumber,
-                       int actualSequenceNumber, String tabName)
-                       throws ManifoldCFException, IOException {
-               Map<String, Object> paramMap = new HashMap<String, Object>();
-
-               // Set the tab name
-               paramMap.put("TABNAME", tabName);
-               paramMap.put("SEQNUM", 
Integer.toString(connectionSequenceNumber));
-               paramMap.put("SELECTEDNUM", 
Integer.toString(actualSequenceNumber));
-
-               // Fill in the field mapping tab data
-               fillInSpecificationMap(paramMap, os);
-
-               Messages.outputResourceWithVelocity(out, locale,
-                               EDIT_SPECIFICATION_CONFIGURATION_HTML, 
paramMap);
-
-       }
-
-       /**
-        * Process a specification post. This method is called at the start of 
job's
-        * edit or view page, whenever there is a possibility that form data 
for a
-        * connection has been posted. Its purpose is to gather form 
information and
-        * modify the transformation specification accordingly. The name of the
-        * posted form is "editjob".
-        *
-        * @param variableContext
-        *            contains the post data, including binary file-upload
-        *            information.
-        * @param locale
-        *            is the preferred local of the output.
-        * @param os
-        *            is the current pipeline specification for this job.
-        * @param connectionSequenceNumber
-        *            is the unique number of this connection within the job.
-        * @return null if all is well, or a string error message if there is an
-        *         error that should prevent saving of the job (and cause a
-        *         redirection to an error page).
-        */
-       @Override
-       public String processSpecificationPost(IPostParameters variableContext,
-                       Locale locale, Specification os, int 
connectionSequenceNumber)
-                       throws ManifoldCFException {
-               String seqPrefix = "s" + connectionSequenceNumber + "_";
-               String titleBoost = variableContext.getParameter(seqPrefix
-                               + SearchBloxConfig.ATTRIBUTE_TITLEBOOST);
-               String contentBoost = variableContext.getParameter(seqPrefix
-                               + SearchBloxConfig.ATTRIBUTE_CONTENTBOOST);
-               String keywordsBoost = variableContext.getParameter(seqPrefix
-                               + SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST);
-               String descriptionBoost = variableContext.getParameter(seqPrefix
-                               + SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST);
-               String collection = variableContext.getParameter(seqPrefix
-                               + SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME);
-               String indexFormat = variableContext.getParameter(seqPrefix
-                               + SearchBloxConfig.ATTRIBUTE_INDEX_FORMAT);
-
-               // About to gather the configuration values, so get rid of the 
old one.
-               int i = 0, len = os.getChildCount();
-               while (i < len) {
-                       SpecificationNode node = os.getChild(i);
-                       if 
(node.getType().equals(SearchBloxConfig.NODE_CONFIGURATION))
-                               os.removeChild(i);
-                       else
-                               i++;
-               }
-
-               SpecificationNode node = new SpecificationNode(
-                               SearchBloxConfig.NODE_CONFIGURATION);
-               node.setAttribute(SearchBloxConfig.ATTRIBUTE_TITLEBOOST, 
titleBoost);
-               node.setAttribute(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST, 
contentBoost);
-               node.setAttribute(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST, 
keywordsBoost);
-               node.setAttribute(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST, 
descriptionBoost);
-               node.setAttribute(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME,
-                               collection);
-               node.setAttribute(SearchBloxConfig.ATTRIBUTE_INDEX_FORMAT, 
indexFormat);
-               os.addChild(os.getChildCount(), node);
-
-               return null;
-
-       }
-       
-
-       protected static class SpecPacker {
-               /** Arguments, from configuration */
-           private final Multimap<String, String> args = HashMultimap.create();
-           
-           public SpecPacker(String outputDescription) {
-               String[] parts = outputDescription.split(",");
-               for(String part : parts) {
-                       String[] keyValue = part.split("=");
-                       if(keyValue.length != 2) {
-                               continue;
-                       }
-                       
-                       args.put(keyValue[0], keyValue[1]);
-               }
-           }
-           
-           public SpecPacker(Specification spec) {
-             // Process arguments
-             for (int i = 0; i < spec.getChildCount(); i++)
-             {
-              SpecificationNode node = spec.getChild(i);
-              if (node.getType().equals(SearchBloxConfig.NODE_CONFIGURATION))
-               {
-                 String titleBoost = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_TITLEBOOST);
-                 String contentBoost = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST);
-                 String keywordsBoost = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST);
-                 String descriptionBoost = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST);
-                 String collection = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME);
-                 args.put(SearchBloxConfig.ATTRIBUTE_TITLEBOOST, titleBoost);
-                 args.put(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST, 
contentBoost);
-                 args.put(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST, 
keywordsBoost);
-                 args.put(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST, 
descriptionBoost);
-                 args.put(SearchBloxDocument.SEARCHBLOX_COLLECTION, 
collection);
-                 
-               }
-             }
-           
-           }
-           
-           public String toPackedString() {
-               Map<String, List<String>> mapList = getArgs();
-               StringBuilder sb = new StringBuilder();
-               for(String s : mapList.keySet()) {
-                       sb.append(s).append("=").append(mapList.get(s).get(0));
-                       sb.append(",");
-               }
-               if(sb.toString().length()!=0)
-                   return sb.substring(0, sb.length()-1);
-            else
-                return "";
-               
-           }
-           
-           public Map<String,List<String>> getArgs() {
-               Map<String,List<String>> result = Maps.newHashMap();
-               for(String s : args.keySet()) {
-                       Collection<String> list = args.get(s);
-                       if(list instanceof List) {
-                               result.put(s,  (List<String>) list);
-                       }
-                       else {
-                               List<String> l = Lists.newArrayList(list);
-                               result.put(s,  l);
-                       }
-               }
-             return result;
-           }
-       }
+        activities.recordActivity(startTime, INGEST_ACTIVITY, null,
+            documentURI, "OK", "Document Indexed");}
+      else
+        activities.recordActivity(startTime, INGEST_ACTIVITY, null,
+            documentURI, "" + code.getCode(), code.name());
+    } catch (SearchBloxException e) {
+      Logging.connectors
+          .error("[Indexing - Add] Exception indexing document :"
+              + document, e);
+      String activityCode = e.getClass().getSimpleName()
+          .toUpperCase(Locale.ROOT);
+      String activityDetails = e.getMessage()
+          + ((e.getCause() != null) ? ": "
+              + e.getCause().getMessage() : "");
+      activities.recordActivity(startTime, INGEST_ACTIVITY, null,
+          documentURI, activityCode, activityDetails);
+      return DOCUMENTSTATUS_REJECTED;
+    }
+    indexingTime = System.currentTimeMillis() - indexingTime;
+    Logging.connectors.info("Indexing Time for document " + documentURI + ": " 
+ indexingTime);
+    return DOCUMENTSTATUS_ACCEPTED;
+  }
+
+  /**
+   * Remove a document using the connector. Note that the last
+   * outputDescription is included, since it may be necessary for the
+   * connector to use such information to know how to properly remove the
+   * document.
+   *
+   * @param documentURI
+   *            is the URI of the document. The URI is presumed to be the
+   *            unique identifier which the output data store will use to
+   *            process and serve the document. This URI is constructed by the
+   *            repository connector which fetches the document, and is thus
+   *            universal across all output connectors.
+   * @param outputDescription
+   *            is the last description string that was constructed for this
+   *            document by the getOutputDescription() method above.
+   * @param activities
+   *            is the handle to an object that the implementer of an output
+   *            connector may use to perform operations, such as logging
+   *            processing activity.
+   */
+  @Override
+  public void removeDocument(String documentURI, String outputDescription,
+      IOutputRemoveActivity activities) throws ManifoldCFException,
+      ServiceInterruption {
+    Logging.ingest.debug("Deleting SearchBlox Document: '" + documentURI
+        + "'");
+
+    SpecPacker packer = new SpecPacker(outputDescription);
+    Map<String, List<String>> args = packer.getArgs();
+    // Establish a session
+    getSession();
+    
+    SearchBloxDocument document = new SearchBloxDocument(this.apiKey);
+    document.uid = documentURI;
+    // document.apiKey = args.get(API_KEY).get(0);
+    document.colName = 
args.get(SearchBloxDocument.SEARCHBLOX_COLLECTION).get(0);
+    String format = args.get(SEARCHBLOX_INDEXING_FORMAT).get(0);
+    long startTime = System.currentTimeMillis();
+    try {
+      ResponseCode code = client.deleteDocument(document, format);
+      if (code == ResponseCode.DOCUMENT_DELETED)
+        activities.recordActivity(startTime, REMOVE_ACTIVITY, null,
+            documentURI, "OK", "Document Deleted");
+      else
+        activities.recordActivity(startTime, REMOVE_ACTIVITY, null,
+            documentURI, "" + code.getCode(), code.name());
+    } catch (SearchBloxException e) {
+      Logging.connectors.error(
+          "[Indexing - Remove] Exception indexing document :"
+              + document, e);
+      String activityCode = e.getClass().getSimpleName()
+          .toUpperCase(Locale.ROOT);
+      String activityDetails = e.getMessage()
+          + ((e.getCause() != null) ? ": "
+              + e.getCause().getMessage() : "");
+      activities.recordActivity(startTime, REMOVE_ACTIVITY, null,
+          documentURI, activityCode, activityDetails);
+    }
+  }
+
+  /**
+   * Read the content of a resource, replace the variable ${PARAMNAME} with
+   * the value and copy it to the out.
+   * 
+   * @param resName
+   * @param out
+   * @throws ManifoldCFException
+   */
+  private static void outputResource(String resName, IHTTPOutput out,
+      Locale locale, Map<String, String> params, String tabName,
+      Integer sequenceNumber, Integer currentSequenceNumber)
+      throws ManifoldCFException {
+    Map<String, String> paramMap = null;
+    if (params != null) {
+      paramMap = params;
+      if (tabName != null) {
+        paramMap.put("TabName", tabName);
+      }
+      if (currentSequenceNumber != null)
+        paramMap.put("SelectedNum", currentSequenceNumber.toString());
+    } else {
+      paramMap = new HashMap<String, String>();
+    }
+    if (sequenceNumber != null)
+      paramMap.put("SeqNum", sequenceNumber.toString());
+
+    Messages.outputResourceWithVelocity(out, locale, resName, paramMap,
+        true);
+  }
+
+  @Override
+  public void outputConfigurationHeader(IThreadContext threadContext,
+      IHTTPOutput out, Locale locale, ConfigParams parameters,
+      List<String> tabsArray) throws ManifoldCFException, IOException {
+    super.outputConfigurationHeader(threadContext, out, locale, parameters,
+        tabsArray);
+    tabsArray.add(Messages.getString(locale, SEARCHBLOX_TAB_PARAMETERS));
+    outputResource(EDIT_CONFIG_HEADER_FORWARD, out, locale, null, null,
+        null, null);
+  }
+
+  @Override
+  public void outputConfigurationBody(IThreadContext threadContext,
+      IHTTPOutput out, Locale locale, ConfigParams parameters,
+      String tabName) throws ManifoldCFException, IOException {
+    super.outputConfigurationBody(threadContext, out, locale, parameters,
+        tabName);
+    Map<String, String> config = getConfigParameters(parameters);
+    outputResource(EDIT_CONFIG_FORWARD_PARAMETERS, out, locale, config,
+        tabName, null, null);
+  }
+
+  /**
+   * Build a Map of SearchBlox parameters. If configParams is null,
+   * getConfiguration() is used.
+   * 
+   * @param configParams
+   */
+  final private Map<String, String> getConfigParameters(
+      ConfigParams configParams) {
+    Map<String, String> map = new HashMap<String, String>();
+
+    String apiKey = configParams.getParameter(SearchBloxDocument.API_KEY);
+    if(apiKey == null)
+      apiKey = DEFAULT_APIKEY;
+    map.put(SearchBloxDocument.API_KEY, apiKey);
+    
+    String endpoint = configParams.getParameter(SEARCHBLOX_ENDPOINT);
+    if(endpoint == null) {
+      endpoint = SearchBloxClient.DEFAULT_ENDPOINT;
+    }
+    map.put(SEARCHBLOX_ENDPOINT,
+        endpoint);
+    
+    String indexFormat = configParams.getParameter(SEARCHBLOX_INDEXING_FORMAT);
+    if (indexFormat == null) {
+      indexFormat = IndexingFormat.JSON.name();
+    }
+    map.put(SEARCHBLOX_INDEXING_FORMAT, indexFormat);
+    
+    String connectionTimeout = 
configParams.getParameter(SEARCHBLOX_CONNECTION_TIMEOUT);
+    if (connectionTimeout == null) {
+      connectionTimeout = BUILDER_DEFAULT_CONNECTION_TIMEOUT;
+    }
+    map.put(SEARCHBLOX_CONNECTION_TIMEOUT, connectionTimeout);
+    
+    String socketTimeout = 
configParams.getParameter(SEARCHBLOX_SOCKET_TIMEOUT);
+    if (socketTimeout == null) {
+      socketTimeout = BUILDER_DEFAULT_SOCKET_TIMEOUT;
+    }
+    map.put(SEARCHBLOX_SOCKET_TIMEOUT, socketTimeout);
+    
+    return map;
+  }
+
+  @Override
+  public void viewConfiguration(IThreadContext threadContext,
+      IHTTPOutput out, Locale locale, ConfigParams parameters)
+      throws ManifoldCFException, IOException {
+    outputResource(VIEW_CONFIG_FORWARD, out, locale,
+        getConfigParameters(parameters), null, null, null);
+  }
+
+  /**
+   * Process a configuration post. This method is called at the start of the
+   * connector's configuration page, whenever there is a possibility that form
+   * data for a connection has been posted. Its purpose is to gather form
+   * information and modify the configuration parameters accordingly. The name
+   * of the posted form is "editconnection".
+   *
+   * @param threadContext
+   *            is the local thread context.
+   * @param variableContext
+   *            is the set of variables available from the post, including
+   *            binary file post information.
+   * @param parameters
+   *            are the configuration parameters, as they currently exist, for
+   *            this connection being configured.
+   * @return null if all is well, or a string error message if there is an
+   *         error that should prevent saving of the connection (and cause a
+   *         redirection to an error page).
+   */
+  @Override
+  public String processConfigurationPost(IThreadContext threadContext,
+      IPostParameters variableContext, Locale locale,
+      ConfigParams parameters) throws ManifoldCFException {
+    String apiKey = variableContext.getParameter(SearchBloxDocument.API_KEY);
+    if (apiKey != null)
+      parameters.setParameter(SearchBloxDocument.API_KEY, apiKey);
+
+    String endpoint = variableContext.getParameter(SEARCHBLOX_ENDPOINT);
+    if (endpoint != null)
+      parameters.setParameter(SEARCHBLOX_ENDPOINT, endpoint);
+    
+    String indexformat = 
variableContext.getParameter(SEARCHBLOX_INDEXING_FORMAT);
+    if (indexformat != null)
+      parameters.setParameter(SEARCHBLOX_INDEXING_FORMAT, indexformat);
+
+    String connectionTimeout = 
variableContext.getParameter(SEARCHBLOX_CONNECTION_TIMEOUT);
+    if (connectionTimeout != null)
+      parameters.setParameter(SEARCHBLOX_CONNECTION_TIMEOUT, 
connectionTimeout);
+    
+    String socketTimeout = 
variableContext.getParameter(SEARCHBLOX_SOCKET_TIMEOUT);
+    if (socketTimeout != null)
+      parameters.setParameter(SEARCHBLOX_SOCKET_TIMEOUT, socketTimeout);
+    
+    return null;
+  }
+
+  /**
+   * Output the specification header section. This method is called in the
+   * head section of a job page which has selected a pipeline connection of
+   * the current type. Its purpose is to add the required tabs to the list,
+   * and to output any javascript methods that might be needed by the job
+   * editing HTML.
+   *
+   * @param out
+   *            is the output to which any HTML should be sent.
+   * @param locale
+   *            is the preferred local of the output.
+   * @param os
+   *            is the current pipeline specification for this connection.
+   * @param connectionSequenceNumber
+   *            is the unique number of this connection within the job.
+   * @param tabsArray
+   *            is an array of tab names. Add to this array any tab names that
+   *            are specific to the connector.
+   */
+  @Override
+  public void outputSpecificationHeader(IHTTPOutput out, Locale locale,
+      Specification os, int connectionSequenceNumber,
+      List<String> tabsArray) throws ManifoldCFException, IOException {
+    Map<String, Object> paramMap = new HashMap<String, Object>();
+    paramMap.put("SEQNUM", Integer.toString(connectionSequenceNumber));
+
+    tabsArray.add(Messages.getString(locale,
+        "SearchBloxConnector.Configuration"));
+
+    // Fill in the specification header map, using data from all tabs.
+    fillInSpecificationMap(paramMap, os);
+
+    Messages.outputResourceWithVelocity(out, locale, EDIT_SPECIFICATION_JS,
+        paramMap);
+  }
+
+  private void fillInSpecificationMap(
+      Map<String, Object> paramMap, Specification os) {
+
+    for (int i = 0, len = os.getChildCount(); i < len; i++) {
+      SpecificationNode sn = os.getChild(i);
+      if (sn.getType().equals(SearchBloxConfig.NODE_CONFIGURATION)) {
+
+        String titleBoost = sn
+            .getAttributeValue(SearchBloxConfig.ATTRIBUTE_TITLEBOOST);
+        if (titleBoost == null || titleBoost.isEmpty())
+          titleBoost = "0";
+        String contentBoost = sn
+            .getAttributeValue(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST);
+        if (contentBoost == null || contentBoost.isEmpty())
+          contentBoost = "0";
+        String keywordsBoost = sn
+            .getAttributeValue(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST);
+        if (keywordsBoost == null || keywordsBoost.isEmpty())
+          keywordsBoost = "0";
+        String descriptionBoost = sn
+            .getAttributeValue(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST);
+        if (descriptionBoost == null || descriptionBoost.isEmpty())
+          descriptionBoost = "0";
+
+        String collection = sn
+            .getAttributeValue(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME);
+        if (collection == null)
+          collection = DEFAULT_COLLECTION;
+        
+        paramMap.put(SearchBloxConfig.ATTRIBUTE_TITLEBOOST.toUpperCase(),
+            titleBoost);
+        paramMap.put(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST.toUpperCase(),
+            contentBoost);
+        paramMap.put(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST.toUpperCase(),
+            keywordsBoost);
+        paramMap.put(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST.toUpperCase(),
+            descriptionBoost);
+        paramMap.put(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME
+            .toUpperCase(), collection);
+
+        return;
+      }
+
+    }
+
+    paramMap.put(SearchBloxConfig.ATTRIBUTE_TITLEBOOST.toUpperCase(), 0);
+    paramMap.put(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST.toUpperCase(), 0);
+    paramMap.put(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST.toUpperCase(), 0);
+    paramMap.put(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST.toUpperCase(), 0);
+    paramMap.put(SearchBloxConfig.ATTRIBUTE_INDEX_FORMAT.toUpperCase(),
+        IndexingFormat.XML.name());
+    paramMap.put(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME.toUpperCase(),
+        "");
+
+  }
+
+  /**
+   * View specification. This method is called in the body section of a job's
+   * view page. Its purpose is to present the pipeline specification
+   * information to the user. The coder can presume that the HTML that is
+   * output from this configuration will be within appropriate <html> and
+   * <body> tags.
+   *
+   * @param out
+   *            is the output to which any HTML should be sent.
+   * @param locale
+   *            is the preferred local of the output.
+   * @param connectionSequenceNumber
+   *            is the unique number of this connection within the job.
+   * @param os
+   *            is the current pipeline specification for this job.
+   */
+  @Override
+  public void viewSpecification(IHTTPOutput out, Locale locale,
+      Specification os, int connectionSequenceNumber)
+      throws ManifoldCFException, IOException {
+    Map<String, Object> paramMap = new HashMap<String, Object>();
+    paramMap.put("SEQNUM", Integer.toString(connectionSequenceNumber));
+
+    // Fill in the map with data from all tabs
+    fillInSpecificationMap(paramMap, os);
+
+    Messages.outputResourceWithVelocity(out, locale,
+        VIEW_SPECIFICATION_HTML, paramMap);
+
+  }
+
+  /**
+   * Output the specification body section. This method is called in the body
+   * section of a job page which has selected a pipeline connection of the
+   * current type. Its purpose is to present the required form elements for
+   * editing. The coder can presume that the HTML that is output from this
+   * configuration will be within appropriate <html>, <body>, and <form> tags.
+   * The name of the form is "editjob".
+   *
+   * @param out
+   *            is the output to which any HTML should be sent.
+   * @param locale
+   *            is the preferred local of the output.
+   * @param os
+   *            is the current pipeline specification for this job.
+   * @param connectionSequenceNumber
+   *            is the unique number of this connection within the job.
+   * @param actualSequenceNumber
+   *            is the connection within the job that has currently been
+   *            selected.
+   * @param tabName
+   *            is the current tab name.
+   */
+  @Override
+  public void outputSpecificationBody(IHTTPOutput out, Locale locale,
+      Specification os, int connectionSequenceNumber,
+      int actualSequenceNumber, String tabName)
+      throws ManifoldCFException, IOException {
+    Map<String, Object> paramMap = new HashMap<String, Object>();
+
+    // Set the tab name
+    paramMap.put("TABNAME", tabName);
+    paramMap.put("SEQNUM", Integer.toString(connectionSequenceNumber));
+    paramMap.put("SELECTEDNUM", Integer.toString(actualSequenceNumber));
+
+    // Fill in the field mapping tab data
+    fillInSpecificationMap(paramMap, os);
+
+    Messages.outputResourceWithVelocity(out, locale,
+        EDIT_SPECIFICATION_CONFIGURATION_HTML, paramMap);
+
+  }
+
+  /**
+   * Process a specification post. This method is called at the start of job's
+   * edit or view page, whenever there is a possibility that form data for a
+   * connection has been posted. Its purpose is to gather form information and
+   * modify the transformation specification accordingly. The name of the
+   * posted form is "editjob".
+   *
+   * @param variableContext
+   *            contains the post data, including binary file-upload
+   *            information.
+   * @param locale
+   *            is the preferred local of the output.
+   * @param os
+   *            is the current pipeline specification for this job.
+   * @param connectionSequenceNumber
+   *            is the unique number of this connection within the job.
+   * @return null if all is well, or a string error message if there is an
+   *         error that should prevent saving of the job (and cause a
+   *         redirection to an error page).
+   */
+  @Override
+  public String processSpecificationPost(IPostParameters variableContext,
+      Locale locale, Specification os, int connectionSequenceNumber)
+      throws ManifoldCFException {
+    String seqPrefix = "s" + connectionSequenceNumber + "_";
+    String titleBoost = variableContext.getParameter(seqPrefix
+        + SearchBloxConfig.ATTRIBUTE_TITLEBOOST);
+    String contentBoost = variableContext.getParameter(seqPrefix
+        + SearchBloxConfig.ATTRIBUTE_CONTENTBOOST);
+    String keywordsBoost = variableContext.getParameter(seqPrefix
+        + SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST);
+    String descriptionBoost = variableContext.getParameter(seqPrefix
+        + SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST);
+    String collection = variableContext.getParameter(seqPrefix
+        + SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME);
+    String indexFormat = variableContext.getParameter(seqPrefix
+        + SearchBloxConfig.ATTRIBUTE_INDEX_FORMAT);
+
+    // About to gather the configuration values, so get rid of the old one.
+    int i = 0, len = os.getChildCount();
+    while (i < len) {
+      SpecificationNode node = os.getChild(i);
+      if (node.getType().equals(SearchBloxConfig.NODE_CONFIGURATION))
+        os.removeChild(i);
+      else
+        i++;
+    }
+
+    SpecificationNode node = new SpecificationNode(
+        SearchBloxConfig.NODE_CONFIGURATION);
+    node.setAttribute(SearchBloxConfig.ATTRIBUTE_TITLEBOOST, titleBoost);
+    node.setAttribute(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST, contentBoost);
+    node.setAttribute(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST, keywordsBoost);
+    node.setAttribute(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST, 
descriptionBoost);
+    node.setAttribute(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME,
+        collection);
+    node.setAttribute(SearchBloxConfig.ATTRIBUTE_INDEX_FORMAT, indexFormat);
+    os.addChild(os.getChildCount(), node);
+
+    return null;
+
+  }
+  
+
+  protected static class SpecPacker {
+    /** Arguments, from configuration */
+    private final Multimap<String, String> args = HashMultimap.create();
+      
+    public SpecPacker(String outputDescription) {
+      String[] parts = outputDescription.split(",");
+      for(String part : parts) {
+        String[] keyValue = part.split("=");
+        if(keyValue.length != 2) {
+          continue;
+        }
+          
+        args.put(keyValue[0], keyValue[1]);
+      }
+    }
+      
+    public SpecPacker(Specification spec) {
+      // Process arguments
+      for (int i = 0; i < spec.getChildCount(); i++)
+      {
+        SpecificationNode node = spec.getChild(i);
+        if (node.getType().equals(SearchBloxConfig.NODE_CONFIGURATION))
+        {
+          String titleBoost = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_TITLEBOOST);
+          String contentBoost = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST);
+          String keywordsBoost = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST);
+          String descriptionBoost = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST);
+          String collection = 
node.getAttributeValue(SearchBloxConfig.ATTRIBUTE_COLLECTION_NAME);
+          args.put(SearchBloxConfig.ATTRIBUTE_TITLEBOOST, titleBoost);
+          args.put(SearchBloxConfig.ATTRIBUTE_CONTENTBOOST, contentBoost);
+          args.put(SearchBloxConfig.ATTRIBUTE_KEYWORDSBOOST, keywordsBoost);
+          args.put(SearchBloxConfig.ATTRIBUTE_DESCRIPTIONBOOST, 
descriptionBoost);
+          args.put(SearchBloxDocument.SEARCHBLOX_COLLECTION, collection);
+            
+        }
+      }
+      
+    }
+      
+    public String toPackedString() {
+      Map<String, List<String>> mapList = getArgs();
+      StringBuilder sb = new StringBuilder();
+      for(String s : mapList.keySet()) {
+        sb.append(s).append("=").append(mapList.get(s).get(0));
+        sb.append(",");
+      }
+      if(sb.toString().length()!=0)
+        return sb.substring(0, sb.length()-1);
+      else
+        return "";
+        
+    }
+      
+    public Map<String,List<String>> getArgs() {
+      Map<String,List<String>> result = Maps.newHashMap();
+      for(String s : args.keySet()) {
+        Collection<String> list = args.get(s);
+        if(list instanceof List) {
+          result.put(s,  (List<String>) list);
+        }
+        else {
+          List<String> l = Lists.newArrayList(list);
+          result.put(s,  l);
+        }
+      }
+      return result;
+    }
+  }
 }


Reply via email to