Package com.ikanow.infinit.e.data_model.driver

Source Code of com.ikanow.infinit.e.data_model.driver.InfiniteDriver

/*******************************************************************************
* Copyright 2012 The Infinit.e Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.ikanow.infinit.e.data_model.driver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.bson.types.ObjectId;

import com.google.common.collect.HashMultimap;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.ikanow.infinit.e.data_model.InfiniteEnums.HarvestEnum;
import com.ikanow.infinit.e.data_model.api.ApiManager;
import com.ikanow.infinit.e.data_model.api.ResponsePojo;
import com.ikanow.infinit.e.data_model.api.ResponsePojo.ResponseObject;
import com.ikanow.infinit.e.data_model.api.authentication.WordPressAuthPojo;
import com.ikanow.infinit.e.data_model.api.authentication.WordPressSetupPojo;
import com.ikanow.infinit.e.data_model.api.authentication.WordPressUserPojo;
import com.ikanow.infinit.e.data_model.api.config.SourcePojoApiMap;
import com.ikanow.infinit.e.data_model.api.custom.mapreduce.CustomMapReduceResultPojo;
import com.ikanow.infinit.e.data_model.api.custom.mapreduce.CustomMapReduceResultPojoApiMap;
import com.ikanow.infinit.e.data_model.api.knowledge.AdvancedQueryPojo;
import com.ikanow.infinit.e.data_model.api.knowledge.DimensionListPojo;
import com.ikanow.infinit.e.data_model.api.knowledge.DocumentPojoApiMap;
import com.ikanow.infinit.e.data_model.api.knowledge.SearchSuggestPojo;
import com.ikanow.infinit.e.data_model.api.social.community.CommunityPojoApiMap;
import com.ikanow.infinit.e.data_model.api.social.person.PersonPojoApiMap;
import com.ikanow.infinit.e.data_model.api.social.sharing.SharePojoApiMap;
import com.ikanow.infinit.e.data_model.store.config.source.SourcePojo;
import com.ikanow.infinit.e.data_model.store.custom.mapreduce.CustomMapReduceJobPojo;
import com.ikanow.infinit.e.data_model.store.document.DocumentPojo;
import com.ikanow.infinit.e.data_model.store.feature.entity.EntityFeaturePojo;
import com.ikanow.infinit.e.data_model.store.social.community.CommunityPojo;
import com.ikanow.infinit.e.data_model.store.social.person.PersonPojo;
import com.ikanow.infinit.e.data_model.store.social.sharing.SharePojo;
import com.ikanow.infinit.e.data_model.store.social.sharing.SharePojo.ShareCommunityPojo;
import com.ikanow.infinit.e.data_model.utils.TrustManagerManipulator;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;

public class InfiniteDriver
{
  private static String DEFAULT_API_ROOT = null;
  private static String DEFAULT_USER = null;
  private static String DEFAULT_PASSWORD = null;
 
  private String apiRoot;
  private String user;
  private String password;
  private String apiKey = null;
 
  private String cookie = null;
 
  public InfiniteDriver()
  {
    apiRoot = DEFAULT_API_ROOT;
    user = DEFAULT_USER;
    password = DEFAULT_PASSWORD;
  }
 
  public InfiniteDriver(String apiRootUrl)
  {
    if (apiRootUrl == null)
      apiRoot = DEFAULT_API_ROOT;
    else
      apiRoot = apiRootUrl;
   
    user = DEFAULT_USER;
    password = DEFAULT_PASSWORD;
  }
 
  public InfiniteDriver(String apiRootUrl, String apiKey)
  {
    if (apiRootUrl == null)
      apiRoot = DEFAULT_API_ROOT;
    else
      apiRoot = apiRootUrl;
   
    this.apiKey = "infinitecookie=api:" + apiKey + ";"; // (use it like a cookie to avoid localhost dev issues)
   
    // (unused)
    user = DEFAULT_USER;
    password = DEFAULT_PASSWORD;
  }
 
  public InfiniteDriver(String apiRootUrl, String username, String unencryptedPassword)
  {
    if (apiRootUrl == null)
      apiRoot = DEFAULT_API_ROOT;
    else
      apiRoot = apiRootUrl;
   
    if (username == null || unencryptedPassword == null)
    {
      user = DEFAULT_USER;
      password = DEFAULT_PASSWORD;
    }
    else
    {
      user = username;
      password = unencryptedPassword;
    }
  }
 
  static public void setDefaultUser(String username)
  {
    DEFAULT_USER = username; 
  }
 
  static public void setDefaultPassword(String unencryptedPassword)
  {
    DEFAULT_PASSWORD = unencryptedPassword;
  }
 
  static public void setDefaultApiRoot(String rootUrl)
  {
    DEFAULT_API_ROOT = rootUrl;
  }
 
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // AUTHENTICATION
 
  // If you already have a valid cookie, then use that:
 
  public void useExistingCookie(String existingCookie) {
    cookie = "infinitecookie=" + existingCookie + "; Path=/; HttpOnly";
  }
 
  /**
   * Returns the currently set cookie, can be used to
   * get the cookie after you login.
   *
   * @return
   */
  public String getCookie()
  {
    return cookie;
  }
 
  /**
   * Logs the user in specified by setUser() using the password
   * specified by setPassword().
   * @return true if the user was logged in successfully.
   */
  public Boolean login()
  {
    return login(new ResponseObject());
  }
 
  public Boolean adminLogin()
  {
    return adminLogin(new ResponseObject());
  }

  /**
   * Logs the user in specified by setUser() using the password
   * specified by setPassword().
   * @param responseObject this object will be said from the response of the API call
   * @return true if the user was logged in successfully.
   */
  public Boolean login(ResponseObject responseObject)
  {
    return login (user, password, responseObject);
  }
 
  public Boolean adminLogin(ResponseObject responseObject)
  {
    return adminLogin (user, password, responseObject);
  }

  /**
   * Logs the user in with the specified username and password.
   * This overrides the setUser and setPassword commands
   * @param username The username to log in
   * @param password the unencrypted password for the username
   * @param responseObject this object will be said from the response of the API call
   * @return true if the user was logged in successfully.
   */
  public Boolean login(String username, String password, ResponseObject responseObject)
  {
    try
    {
      return doLogin(username, encryptWithoutEncode(password), responseObject);
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
    return null;
  }
 
  public Boolean login_encrypted(String username, String encrypted_password, ResponseObject responseObject)
  {
    return doLogin(username, encrypted_password, responseObject);
  }
 
  private Boolean doLogin(String username, String password, ResponseObject responseObject)
  {
    if (null != apiKey) { // Have an API key, don't need to login....
      return true;
    }   
    cookie = null;
    try
    {
      String address = apiRoot + "auth/login/" + username + "/" + URLEncoder.encode(password, "UTF-8");
      String loginResult;
      loginResult = sendRequest(address, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(loginResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
      return responseObject.isSuccess();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }
 
  public Boolean adminLogin(String username, String password, ResponseObject responseObject)
  {
    // Allow this even if have an API key because it's currently the only way of knowing if you're an admin
   
    cookie = null;
    try {
      String address = apiRoot + "auth/login/admin/" + username + "/" + encryptEncodePassword(password);
      String loginResult;
      loginResult = sendRequest(address, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(loginResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
      return responseObject.isSuccess();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }

  /**
   * Logs the current logged in user out.
   * @return true if logout was successful.
   */
  public Boolean logout()
  {
    if (null == cookie) { // not logged in, eg have an API key
      return true;
    }
    try {
      String address = apiRoot + "auth/logout/";
      String logoutResult;
      logoutResult = sendRequest(address, null);
      ResponsePojo response = ResponsePojo.fromApi(logoutResult, ResponsePojo.class);

      //cookie set to null so that new cookie will be grabbed on next login
      cookie = null;

      return response.getResponse().isSuccess();
    }
    catch (Exception e)
    {
      cookie = null;
      return false;
    }
  }

  /**
   * Sends a keepalive message
   * @return true if user is currently logged in
   */
  public Boolean sendKeepalive() {
    return sendKeepalive(false);
  }
  public Boolean sendKeepalive(boolean bAdminOnly) {
   
    try {     
      String address = apiRoot + "auth/keepalive";
      if (bAdminOnly) {
        address += "/admin";
      }
      String logoutResult;
      logoutResult = sendRequest(address, null);
      ResponsePojo response = ResponsePojo.fromApi(logoutResult, ResponsePojo.class);
      return response.getResponse().isSuccess();
    }
    catch (Exception e)
    {
      return false;
    }
  }
 
  public Boolean deactivateUser(String username)
  {
    try
    {
      String deactivateAddress = apiRoot + "auth/deactivate?username=" + URLEncoder.encode(username,"UTF-8");
     
      String deactivateResult = sendRequest(deactivateAddress, null);

      ResponsePojo response = ResponsePojo.fromApi(deactivateResult, ResponsePojo.class);
      return response.getResponse().isSuccess();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return false;
  }
 
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // SOCIAL - COMMUNITIES
 
  /**
   * createCommunity
   * @param communityName
   * @param communityDesc
   * @param communityTag
   * @param responsePojo
   * @return CommunityPojo
   */
  public CommunityPojo createCommunity(String communityName, String communityDesc, String communityTags,String parentid, ResponseObject responseObject )
  {
    try{
      String createCommunityAddress = apiRoot + "social/community/add/" + URLEncoder.encode(communityName,"UTF-8") + "/" +
          URLEncoder.encode(communityDesc,"UTF-8") + "/" + URLEncoder.encode(communityTags,"UTF-8");
      if (null != parentid)
        createCommunityAddress += "/" + URLEncoder.encode(parentid,"UTF-8");
     
      String communityresult = sendRequest(createCommunityAddress, null);

      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(communityresult, ResponsePojo.class, CommunityPojo.class, new CommunityPojoApiMap());
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
     
      return (CommunityPojo)internal_responsePojo.getData();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }

  public String addToCommunity(String communityId, String personId, ResponseObject responseObject )
  {
    try
    {
      String addToCommunityAddress = apiRoot + "social/community/member/invite/" + URLEncoder.encode(communityId,"UTF-8") + "/" +
          URLEncoder.encode(personId,"UTF-8") + "/";
      String inviteresult = sendRequest(addToCommunityAddress, null);

      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(inviteresult, ResponsePojo.class, CommunityPojo.class, new CommunityPojoApiMap());
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.getMessage();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }
 
  public String joinCommunity(String communityId, ResponseObject responseObject )
  {
    try
    {
      String addToCommunityAddress = apiRoot + "social/community/member/join/" + URLEncoder.encode(communityId,"UTF-8");
      String inviteresult = sendRequest(addToCommunityAddress, null);

      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(inviteresult, ResponsePojo.class, CommunityPojo.class, new CommunityPojoApiMap());
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.getMessage();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }
 
  public String forcefullyAddToCommunity(String communityId, String personId, ResponseObject responseObject )
  {
    try
    {
      String addToCommunityAddress = apiRoot + "social/community/member/invite/" + URLEncoder.encode(communityId,"UTF-8") + "/" +
          URLEncoder.encode(personId,"UTF-8") + "/?skipinvitation=true";
      String inviteresult = sendRequest(addToCommunityAddress, null);

      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(inviteresult, ResponsePojo.class, CommunityPojo.class, new CommunityPojoApiMap());
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.getMessage();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }
 
  public CommunityPojo getCommunity(String communityIdentifier, ResponseObject responseObject )
  {
    try
    {
      String getCommunityAddress = apiRoot + "social/community/get/" + URLEncoder.encode(communityIdentifier,"UTF-8") + "";
      String getResult = sendRequest(getCommunityAddress, null);

      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(getResult, ResponsePojo.class, CommunityPojo.class, new CommunityPojoApiMap());
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return (CommunityPojo)internal_responsePojo.getData();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }
 
  public List<CommunityPojo> getPublicCommunities(ResponseObject responseObject)
  {
    try
    {
      String getCommunityAddress = apiRoot + "social/community/getpublic";
      String getResult = sendRequest(getCommunityAddress, null);
     
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(getResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
     
      List<CommunityPojo> communities = null;
     
      communities = ApiManager.mapListFromApi((JsonElement)internal_responsePojo.getData(),
                              CommunityPojo.listType(), null);     
     
      return communities;
    }
    catch (Exception e)
    {
      responseObject.setSuccess(false);
      responseObject.setMessage(e.getMessage());
    }   
    return null;
  }
 
  public List<CommunityPojo> getAllCommunity(ResponseObject responseObject)
  {
    try
    {
      String getCommunityAddress = apiRoot + "social/community/getall";
      String getResult = sendRequest(getCommunityAddress, null);
     
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(getResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
     
      List<CommunityPojo> communities = null;
     
      communities = ApiManager.mapListFromApi((JsonElement)internal_responsePojo.getData(),
                              CommunityPojo.listType(), null);     
     
      return communities;
    }
    catch (Exception e)
    {
      responseObject.setSuccess(false);
      responseObject.setMessage(e.getMessage());
    }   
    return null;
  }

  public Boolean deleteCommunity(String communityId, ResponseObject responseObject)
  {
    try
    {
      String addToCommunityAddress = apiRoot + "social/community/remove/" + URLEncoder.encode(communityId,"UTF-8");
      String inviteresult = sendRequest(addToCommunityAddress, null);

      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(inviteresult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.isSuccess();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }

  public Boolean updateCommunity(String communityId, CommunityPojo communityPojo, ResponseObject responseObject)
  {
    try{
      String addToCommunityAddress = apiRoot + "social/community/update/" + URLEncoder.encode(communityId,"UTF-8");
      String updateResult = sendRequest(addToCommunityAddress, new Gson().toJson(communityPojo));
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(updateResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.isSuccess();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return false;
  }
 
  public Boolean updateCommunityMemberType(String communityId, String personId, String userType, ResponseObject responseObject)
  {
    try
    {
      String updateCommunityMemberUrl = apiRoot + "social/community/member/update/type/" + URLEncoder.encode(communityId,"UTF-8") +
      "/" + URLEncoder.encode(personId,"UTF-8") + "/" + URLEncoder.encode(userType,"UTF-8");
      String updateResult = sendRequest(updateCommunityMemberUrl, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(updateResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.isSuccess();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return false;
  }
 
  public Boolean updateCommunityMemberStatus(String communityId, String personId, String userStatus, ResponseObject responseObject)
  {
    try
    {
      String updateCommunityMemberUrl = apiRoot + "social/community/member/update/status/" + URLEncoder.encode(communityId,"UTF-8") +
      "/" + URLEncoder.encode(personId,"UTF-8") + "/" + URLEncoder.encode(userStatus,"UTF-8");
      String updateResult = sendRequest(updateCommunityMemberUrl, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(updateResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.isSuccess();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return false;
  }
 
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // SOCIAL - SHARES
 
  public List<SharePojo> searchShares(String searchCriteria, String searchString, String typeFilter, ResponseObject responseObject)
  {
    return searchShares(searchCriteria,searchString,typeFilter,false,responseObject);
  }
  //TESTED
 
  public List<SharePojo> searchShares(String searchCriteria, String searchString, String typeFilter, Boolean searchParent, ResponseObject responseObject)
  {
    try {
      StringBuffer url = new StringBuffer(apiRoot).append("social/share/search/");
      if (null != searchCriteria) {
        url.append("?searchby=").append(searchCriteria).append("&id=").append(URLEncoder.encode(searchString, "UTF-8"));
      }
      if (null != typeFilter) {
        if (null != searchCriteria) {
          url.append("&");
        }
        else {
          url.append("?");       
        }
        url.append("type=").append(typeFilter);
      }
      if ( searchParent )
      {
        if ( null != searchCriteria && null != typeFilter)
          url.append("&");
        else
          url.append("?");
        url.append("searchParent=true");
      }
      String deleteResult = sendRequest(url.toString(), null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(deleteResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
     
      List<SharePojo> shares = null;
     
      shares = ApiManager.mapListFromApi((JsonElement)internal_responsePojo.getData(),
                              SharePojo.listType(), null);     
     
      return shares;
    }
    catch (Exception e) {
      responseObject.setSuccess(false);
      responseObject.setMessage(e.getMessage());
    }
    return null;
  }
 
  public SharePojo getShare(String shareId, ResponseObject responseObject)
  {
    try{
      String getShareAddress = apiRoot + "social/share/get/" + URLEncoder.encode(shareId,"UTF-8");
      String getResult = sendRequest(getShareAddress, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(getResult, ResponsePojo.class, SharePojo.class, new SharePojoApiMap(null));
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return (SharePojo)internal_responsePojo.getData();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }
 
 
  public SharePojo addShareJSON(String title, String description, String type, String jsonString , ResponseObject responseObject)
  {
    try
    {
      String addShareAddress = apiRoot + "social/share/add/json/" + URLEncoder.encode(type, "UTF-8") + "/" + URLEncoder.encode(title,"UTF-8") + "/" + URLEncoder.encode(description,"UTF-8");
      String addResult = sendRequest(addShareAddress, jsonString);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(addResult, ResponsePojo.class, SharePojo.class, new SharePojoApiMap(null));
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return (SharePojo)internal_responsePojo.getData();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }
 
  public Boolean updateShareJSON(String shareId, String title, String description, String type, String jsonString , ResponseObject responseObject)
  {
    try{
      String updateShareAddress = apiRoot + "social/share/update/json/" + shareId + "/" + URLEncoder.encode(type,"UTF-8") + "/" + URLEncoder.encode(title,"UTF-8") + "/" + URLEncoder.encode(description,"UTF-8");
      String updateResult = sendRequest(updateShareAddress, jsonString);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(updateResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.isSuccess();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return false;
  }
 
  public Boolean removeShare(String shareId, ResponseObject responseObject)
  {
    try{
      String removeShareAddress = apiRoot + "social/share/remove/" + URLEncoder.encode(shareId,"UTF-8");
      String updateResult = sendRequest(removeShareAddress, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(updateResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.isSuccess();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return false;
  }
 
  public Boolean addShareToCommunity(String shareId, String comment, String communityId, ResponseObject responseObject)
  {
    try
    {
      String addCommunityAddress = apiRoot + "social/share/add/community/" + shareId + "/" + URLEncoder.encode(comment,"UTF-8") + "/" + URLEncoder.encode(communityId,"UTF-8");
      String updateResult = sendRequest(addCommunityAddress, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(updateResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.isSuccess();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return false;
  }
 
  public Boolean removeShareFromCommunity(String shareId, String communityId, ResponseObject responseObject)
  {
    try{
      String addCommunityAddress = apiRoot + "social/share/remove/community/" + shareId + "/" + URLEncoder.encode(communityId,"UTF-8");
      String updateResult = sendRequest(addCommunityAddress, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(updateResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);

      return responseObject.isSuccess();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return false;
  }
 

  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // SOCIAL - PEOPLE
 
  public String deletePerson(String personId, ResponseObject responseObject)
  {
    try
    {
      String deletePersonAddress = apiRoot + "social/person/delete/" + URLEncoder.encode(personId,"UTF-8");
      String deleteResult = sendRequest(deletePersonAddress, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(deleteResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
     
      return responseObject.getMessage();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }

  /**
   * getPerson
   * @param personId  Can be the person id, email address, or Null. If Null, it will return information about current user.
   * @param responsePojo
   * @return PersonPojo
   */
  public PersonPojo getPerson(String personId, ResponseObject responseObject)
  {
    try
    {
      String getPersonAddress = apiRoot + "social/person/get";

      if (personId != null)
        getPersonAddress +=  "/" + URLEncoder.encode(personId,"UTF-8");

      String getResult = sendRequest(getPersonAddress, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(getResult, ResponsePojo.class, PersonPojo.class, new PersonPojoApiMap())
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
      return (PersonPojo)internal_responsePojo.getData();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }

  /**
   * listPerson
   *
   * @param responseObject
   * @return
   */
  public List<PersonPojo> listPerson(ResponseObject responseObject)
  {
    try
    {
      String listPersonAddress = apiRoot + "social/person/list";     
      String getResult = sendRequest(listPersonAddress, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(getResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();     
      responseObject = shallowCopy(responseObject, internal_ro);
      List<PersonPojo> people = null;
      people = ApiManager.mapListFromApi((JsonElement)internal_responsePojo.getData(), PersonPojo.listType(), new PersonPojoApiMap());
     
      return people;                 
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }

  public String registerPerson(String first_name, String last_name, String phone, String email, String password, String accountType, ResponseObject responseObject)
  {
    try {
      Date date = new Date();
      SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy kk:mm:ss aa");
      String today = formatter.format(date);
      String encrypted_password;

      encrypted_password = encryptWithoutEncode(password);

      WordPressUserPojo wpuser = new WordPressUserPojo();
      WordPressAuthPojo wpauth = new WordPressAuthPojo();

      wpuser.setCreated(today);
      wpuser.setModified(today);
      wpuser.setFirstname(first_name);
      wpuser.setLastname(last_name);
      wpuser.setPhone(phone);

      ArrayList<String> emailArray = new ArrayList<String>();
      emailArray.add(email);
      wpuser.setEmail(emailArray);

      //wpauth.setWPUserID(email);
      wpauth.setPassword(encrypted_password);
      wpauth.setAccountType(accountType);
      wpauth.setCreated(today);
      wpauth.setModified(today);
     
      WordPressSetupPojo wpSetup = new WordPressSetupPojo();
      wpSetup.setAuth(wpauth);
      wpSetup.setUser(wpuser);

      return registerPerson(wpSetup, responseObject);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }

    return null;
  }
 
  public String registerPerson(WordPressSetupPojo wpSetup, ResponseObject responseObject)
  {

    String theUrl = apiRoot + "social/person/register";
    String data =  new Gson().toJson(wpSetup);
    String registerResult = sendRequest(theUrl, data);
    ResponsePojo internal_responsePojo = ResponsePojo.fromApi(registerResult, ResponsePojo.class);
    ResponseObject internal_ro = internal_responsePojo.getResponse();
    responseObject = shallowCopy(responseObject, internal_ro);
   
    return responseObject.getMessage();
  }
 
  public String updatePerson(String first_name, String last_name, String phone, String email, String password, String accountType, ResponseObject responseObject)
  {
    try
    {
      Date date = new Date();
      SimpleDateFormat formatter = new SimpleDateFormat("MMM dd, yyyy kk:mm:ss aa");
      String today = formatter.format(date);
      String encrypted_password = null;
     
      if ( password != null )
        encrypted_password = encryptWithoutEncode(password);


      WordPressUserPojo wpuser = new WordPressUserPojo();
      WordPressAuthPojo wpauth = new WordPressAuthPojo();
     
      wpuser.setModified(today);
      wpuser.setFirstname(first_name);
      wpuser.setLastname(last_name);
      wpuser.setPhone(phone);
      ArrayList<String> emailArray = new ArrayList<String>();
      emailArray.add(email);     
      wpuser.setEmail(emailArray);
      wpauth.setWPUserID(email);
      wpauth.setPassword(encrypted_password);
      wpauth.setAccountType(accountType);
      wpauth.setModified(today);

      return updatePerson(wpuser, wpauth, responseObject);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }

    return null;
  }
 
  public String updatePerson(WordPressUserPojo wpuser, WordPressAuthPojo wpauth, ResponseObject responseObject)
  {

    String theUrl = apiRoot + "social/person/update";
    String data = "{ \"user\":" + new Gson().toJson(wpuser) + ", \"auth\":" + new Gson().toJson(wpauth) + "}";
    String updateResult = sendRequest(theUrl, data);
    ResponsePojo internal_responsePojo = ResponsePojo.fromApi(updateResult, ResponsePojo.class);
    ResponseObject internal_ro = internal_responsePojo.getResponse();
    responseObject = shallowCopy(responseObject, internal_ro);
   
    return responseObject.getMessage();
  }
 
  public String updatePersonPassword(String id, String newPassword, ResponseObject responseObject)
  {
    try
    {
      String updatePasswordAddress = apiRoot + "social/person/update/password/" + URLEncoder.encode(id,"UTF-8") + "/" + URLEncoder.encode(newPassword,"UTF-8");
      String updateResult = sendRequest(updatePasswordAddress, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(updateResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
   
      return responseObject.getMessage();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
    return "";
  }
 
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // CONFIG - SOURCE
 
  public SourcePojo getSource(String sourceId, ResponseObject responseObject)
  {
    try{
      String getSourceAddress = apiRoot + "config/source/get/" + URLEncoder.encode(sourceId,"UTF-8");

      String getResult = sendRequest(getSourceAddress, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(getResult, ResponsePojo.class, SourcePojo.class, new SourcePojoApiMap(null))
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
      return (SourcePojo)internal_responsePojo.getData();

    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }
 
  public SourcePojo saveSource(SourcePojo source, String communityId, ResponseObject responseObject)
  {
    try {
      String address = apiRoot + "config/source/save/" + communityId + "/";
      String saveResult;
      saveResult = sendRequest(address, new Gson().toJson(source));
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(saveResult, ResponsePojo.class, SourcePojo.class, new SourcePojoApiMap(null));
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
      return (SourcePojo)internal_responsePojo.getData();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }
 
  public String deleteSource(String sourceId, String communityId, ResponseObject responseObject)
  {
    try {
      String address = apiRoot + "config/source/delete/" + sourceId + "/" + communityId;
      String deleteResult = sendRequest(address, null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(deleteResult, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
     
      return responseObject.getMessage();
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return null;
  }

  public List<DocumentPojo> testSource(SourcePojo testSrc, ResponseObject response, int nToReturn, boolean bReturnFullText) {
   
    StringBuffer theUrl = new StringBuffer(apiRoot).append("config/source/test");
    if (nToReturn > 0) {
      theUrl.append("?numReturn=").append(nToReturn);
    }
    if (bReturnFullText) {
      if (nToReturn > 0) {
        theUrl.append('&');
      }
      else {
        theUrl.append('?');
      }
      theUrl.append("returnFullText=true");
    }
    String map = ApiManager.mapToApi(testSrc, null);   
    String testResult = sendRequest(theUrl.toString(), map);
   
    ResponsePojo internal_response = ResponsePojo.fromApi(testResult, ResponsePojo.class);
    shallowCopy(response, internal_response.getResponse());
    List<DocumentPojo> docs = null;
    if (response.isSuccess()) {
      docs = ApiManager.mapListFromApi((JsonElement)internal_response.getData(),
                                  DocumentPojo.listType(), new DocumentPojoApiMap());
    }
   
    return docs;
  }
 
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // KNOWLEDGE - QUERY
 
  // Queries are slightly different - the entire ResponsePojo is used.
 
  public ResponsePojo sendQuery(AdvancedQueryPojo query, ObjectId communityId, ResponseObject response) {
    ArrayList<ObjectId> community = new ArrayList<ObjectId>(1);
    community.add(communityId);
    return sendQuery(query, community, response);
  }
  public ResponsePojo sendQuery(AdvancedQueryPojo query, Collection<ObjectId> communities, ResponseObject response) {
   
    StringBuffer theUrl = new StringBuffer(apiRoot).append("knowledge/document/query/");
    boolean bFirstComm = true;
    for (ObjectId commId: communities) {
      if (!bFirstComm)
        theUrl.append(',');
      theUrl.append(commId.toString());
      bFirstComm = false;
    }
    String testResult = sendRequest(theUrl.toString(), query.toApi());
   
    ResponsePojo internal_response = ResponsePojo.fromApi(testResult, ResponsePojo.class);
    shallowCopy(response, internal_response.getResponse());
   
    return internal_response;
  }
 
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // KNOWLEDGE - DOCUMENT - GET
  public DocumentPojo getDocument(String docid, ResponseObject responseObject)
  {
    return getDocument(docid,false,false,responseObject);
 
  public DocumentPojo getDocument(String docid, boolean returnFullText, boolean returnRawData, ResponseObject responseObject)
  {
    try
    {
      StringBuffer theUrl = new StringBuffer(apiRoot).append("knowledge/document/get/");
      theUrl.append(docid);
      theUrl.append("?returnFullText=").append(returnFullText);
      theUrl.append("?returnRawData=").append(returnRawData);
     
      String getResult = sendRequest(theUrl.toString(), null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(getResult, ResponsePojo.class, DocumentPojo.class, new DocumentPojoApiMap())
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
      return (DocumentPojo)internal_responsePojo.getData();
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
    return null;
  }
 
  public DocumentPojo getDocument(String sourceKey, String url, ResponseObject responseObject)
  {
    return getDocument(sourceKey, url, false, false, responseObject);
  }
  public DocumentPojo getDocument(String sourceKey, String url, boolean returnFullText, boolean returnRawData, ResponseObject responseObject)
  {
    try
    {
      StringBuffer theUrl = new StringBuffer(apiRoot).append("knowledge/document/get/");
      theUrl.append(sourceKey).append("/").append(url);
      theUrl.append("?returnFullText=").append(returnFullText);
      theUrl.append("?returnRawData=").append(returnRawData);
     
      String getResult = sendRequest(theUrl.toString(), null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(getResult, ResponsePojo.class, DocumentPojo.class, new DocumentPojoApiMap())
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      responseObject = shallowCopy(responseObject, internal_ro);
      return (DocumentPojo)internal_responsePojo.getData();
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
    return null;
  }
 
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // CUSTOM - CREATE PLUGIN TASK
 
  // The following fields of taskConfig are filled in (string unless otherwise specified):
  // - jobtitle, jobdesc
  // - jarURL: the name of the JAR in the share
  // - inputCollection
  // - firstSchedule (Date) ... when it will be run
  // - scheduleFreq (SCHEDULE_FREQUENCY)
  // - mapper, combiner, reducer
  // - outputKey, outputValue
  // - appendResult, ageOutInDays
  // - jobDependencies ... though using the input param that allows them to be specified as jobtitles is recommended
 
  public ObjectId createCustomPluginTask(CustomMapReduceJobPojo taskConfig, Collection<String> dependencies, ObjectId communityId, ResponseObject response) {
    ArrayList<ObjectId> community = new ArrayList<ObjectId>(1);
    community.add(communityId);
    return createCustomPluginTask(taskConfig, dependencies, community, response);
  }
  public ObjectId createCustomPluginTask(CustomMapReduceJobPojo taskConfig, Collection<String> dependencies, Collection<ObjectId> communities, ResponseObject response) {
    return createCustomPluginTask(taskConfig, dependencies, communities, response, false);
  }
 
  private ObjectId createCustomPluginTask(CustomMapReduceJobPojo taskConfig, Collection<String> dependencies, Collection<ObjectId> communities, ResponseObject response, boolean bUpdate) {
    ObjectId retVal = null;
    try {
      StringBuffer url = new StringBuffer(apiRoot).append("custom/mapreduce/");
      if (bUpdate) {
        if (taskConfig._id != null) {
          url.append("updatejob/").append(taskConfig._id.toString()).append("/");       
        }
        else {
          url.append("updatejob/").append(taskConfig.jobtitle).append("/");
          taskConfig.jobtitle = null;
        }//TESTED
      }
      else {
        url.append("schedulejob/");       
      }     
      if (null != communities) {
        for (ObjectId communityId: communities) {
          url.append(communityId.toString()).append(',');
        }
        url.setLength(url.length() - 1);
      }
      else {
        url.append("null");
      }
      url.append('/');
     
      if ((null != taskConfig.jobDependencies) && !taskConfig.jobDependencies.isEmpty()) {
        for (ObjectId jobId: taskConfig.jobDependencies) {
          url.append(jobId.toString()).append(',');
        }
        url.setLength(url.length() - 1);       
      }
      else if ((null != dependencies) && !dependencies.isEmpty()) {
        for (String jobTitle: dependencies) {
          url.append(jobTitle).append(',');
        }
        url.setLength(url.length() - 1);               
      }
      else {
        url.append("null");       
      }
      url.append("/");

      // "nextRunTime"==first Schedule (date)
      if (null != taskConfig.firstSchedule) {
        taskConfig.nextRunTime = taskConfig.firstSchedule.getTime();
      }
     
      String json = sendRequest(url.toString(), ApiManager.mapToApi(taskConfig, null));
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(json, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      response = shallowCopy(response, internal_ro);
     
      if (response.isSuccess()) {
        JsonPrimitive retValObj = (JsonPrimitive)internal_responsePojo.getData();
        retVal = new ObjectId(retValObj.getAsString());
      }     
    }
    catch (Exception e) {
      response.setSuccess(false);
      response.setMessage(e.getMessage());
    }
    return retVal;
  }
  //TESTED (one minor clause to test, will leave for now)
 
  ///////////////////////////////////////////////////////////////////
 
  // Updates ... as above but jobtitle or _id must be specified
 
  public ObjectId updateCustomPluginTask(CustomMapReduceJobPojo taskConfig, Collection<String> dependencies, ObjectId communityId, ResponseObject response) {
    ArrayList<ObjectId> community = new ArrayList<ObjectId>(1);
    community.add(communityId);
    return updateCustomPluginTask(taskConfig, dependencies, community, response);
  }
 
  public ObjectId updateCustomPluginTask(CustomMapReduceJobPojo taskConfig, Collection<String> dependencies, Collection<ObjectId> communities, ResponseObject response) {
    return createCustomPluginTask(taskConfig, dependencies, communities, response, true);
  }
  //TESTED
   
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // CUSTOM - CREATE PLUGIN TASK
 
  // The following fields of taskConfig are filled in (string unless otherwise specified):
  // - jobtitle, jobdesc
  // - firstSchedule (Date) ... when it will be run
  // - scheduleFreq (SCHEDULE_FREQUENCY)
  // - appendResult, ageOutInDays
 
  public ObjectId createCustomSavedQueryTask(CustomMapReduceJobPojo taskConfig, AdvancedQueryPojo query, ObjectId communityId, ResponseObject response) {
    ArrayList<ObjectId> community = new ArrayList<ObjectId>(1);
    community.add(communityId);
    return createCustomSavedQueryTask(taskConfig, query, community, response);
  }
  public ObjectId createCustomSavedQueryTask(CustomMapReduceJobPojo taskConfig, ObjectId communityId, ResponseObject response) {
    ArrayList<ObjectId> community = new ArrayList<ObjectId>(1);
    community.add(communityId);
    return createCustomSavedQueryTask(taskConfig, null, community, response);
  }
  public ObjectId createCustomSavedQueryTask(CustomMapReduceJobPojo taskConfig, AdvancedQueryPojo query, Collection<ObjectId> communities, ResponseObject response) {
    if (null != query) {
      taskConfig.query = query.toApi();
    }
    return createCustomPluginTask(taskConfig, null, communities, response);
  }
  //TESTED
 
  ///////////////////////////////////////////////////////////////////
 
  // Updates ... as above but jobtitle or _id must be specified
 
  public ObjectId updateCustomSavedQueryTask(CustomMapReduceJobPojo taskConfig, AdvancedQueryPojo query, ObjectId communityId, ResponseObject response) {
    ArrayList<ObjectId> community = new ArrayList<ObjectId>(1);
    community.add(communityId);
    return updateCustomSavedQueryTask(taskConfig, query, community, response);
  }
  public ObjectId updateCustomSavedQueryTask(CustomMapReduceJobPojo taskConfig, ObjectId communityId, ResponseObject response) {
    ArrayList<ObjectId> community = new ArrayList<ObjectId>(1);
    community.add(communityId);
    return updateCustomPluginTask(taskConfig, null, community, response);
  }
  public ObjectId updateCustomSavedQueryTask(CustomMapReduceJobPojo taskConfig, AdvancedQueryPojo query, Collection<ObjectId> communities, ResponseObject response) {
    if (null != query) {
      taskConfig.query = query.toApi();
    }
    return updateCustomPluginTask(taskConfig, null, communities, response);   
  }
  //TESTED
 
  public CustomMapReduceResultPojo getCustomTaskOrQueryResults(String jobtitle, ResponseObject response)
  {
    CustomMapReduceResultPojo retVal = null;
    try
    {
      StringBuilder url = new StringBuilder(apiRoot).append("custom/mapreduce/getresults/");
      if ( null != jobtitle)
      {
        url.append(jobtitle);
      }
       
      String json = sendRequest(url.toString(), null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(json, ResponsePojo.class, CustomMapReduceResultPojo.class, new CustomMapReduceResultPojoApiMap());
     
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      response = shallowCopy(response, internal_ro);
     
      if (response.isSuccess())
      {
        //JsonElement js = (JsonElement)internal_responsePojo.getData();
        //retVal = ApiManager.mapFromApi(js, CustomMapReduceResultPojo.class, null);
        retVal = (CustomMapReduceResultPojo)internal_responsePojo.getData();
       
      }
    }
    catch (Exception e)
    {
      response.setSuccess(false);
      response.setMessage(e.getMessage());
    }
    return retVal;
  }
 
  //////////////////////////////////////////////////////////////////////////////////////////////

  public List<CustomMapReduceJobPojo> getCustomTaskOrQuery(String jobtitle, ResponseObject response) {
    List<CustomMapReduceJobPojo> retVal = null;
    try {
      StringBuilder url = new StringBuilder(apiRoot).append("custom/mapreduce/getjobs/");
      if (null != jobtitle) {
        url.append(jobtitle);
      }
      // (else get all)
     
      String json = sendRequest(url.toString(), null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(json, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      response = shallowCopy(response, internal_ro);
     
      if (response.isSuccess()) {
        retVal = ApiManager.mapListFromApi((JsonElement)internal_responsePojo.getData(),
                          CustomMapReduceJobPojo.listType(), null);
      }
    }
    catch (Exception e) {
      response.setSuccess(false);
      response.setMessage(e.getMessage());     
    }
    return retVal;
  }
 
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // And deletes, apply to either: 
 
  public boolean deleteCustomTaskOrQuery(String jobtitle, ResponseObject response) {
    try {
      StringBuilder url = new StringBuilder(apiRoot).append("custom/mapreduce/removejob/");
      url.append(jobtitle);
     
      String json = sendRequest(url.toString(), null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(json, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      response = shallowCopy(response, internal_ro);
    }
    catch (Exception e) {
      response.setSuccess(false);
      response.setMessage(e.getMessage());
    }
    return response.isSuccess();
  }
  public boolean deleteCustomTaskOrQuery(ObjectId taskId, ResponseObject response) {
    return deleteCustomTaskOrQuery(taskId.toString(), response);
 
  //TESTED
 
  //////////////////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // ALIASES
 
  // UPDATE, REMOVE, AND GET
 
  // This is not super-efficient code
 
  public Set<String> updateAliases(Collection<EntityFeaturePojo> aliasesToUpdate, String communityIdStr, boolean bUpsert, ResponseObject response) {
    return updateAliases(aliasesToUpdate, communityIdStr, bUpsert, null, response);
   
  }
  public Set<String> removeAliases(Collection<String> aliasesToRemove, String communityIdStr, ResponseObject response) {
    return removeAliases(aliasesToRemove, communityIdStr, null, response);
   
  }
  // (Only use this version if immediately called after getAliases since none of this is in any way atomic)
  public Set<String> updateAliases(Collection<EntityFeaturePojo> aliasesToUpdate, String communityIdStr, boolean bUpsert, Map<String, List<SharePojo>> aliasMapping, ResponseObject response) {
    if (null == aliasMapping) {
      aliasMapping = new HashMap<String, List<SharePojo>>();
      this.getAliases(communityIdStr, aliasMapping, response);
      if (!response.isSuccess()) {
        return null;
      }
    }//TESTED
    Map<ObjectId, BasicDBObject> shareContentCache = new HashMap<ObjectId, BasicDBObject>();
    List<SharePojo> sharesToUpdate = new LinkedList<SharePojo>();
    // Step through the aliases, update the content
    // Loop 1 update
    SharePojo shareForNewAliases = null;
    Set<String> erroredAliases = new HashSet<String>();
    HashMultimap<ObjectId, String> shareToAliasMapping = HashMultimap.create();
    for (EntityFeaturePojo alias: aliasesToUpdate) {
      List<SharePojo> sharesForThisAlias = aliasMapping.get(alias.getIndex());
      if ((null == sharesForThisAlias) && bUpsert) { // This is a new alias and not ignoring upserts
        if (null == shareForNewAliases) { // Haven't yet assigned such a share
          shareForNewAliases = this.upsertSharePrep(communityIdStr, shareContentCache, aliasMapping);
          if (null == shareForNewAliases) {
            erroredAliases.add(alias.getIndex());
            continue;
          }
          sharesToUpdate.add(shareForNewAliases);
        }
        BasicDBObject shareContent =  shareContentCache.get(shareForNewAliases.get_id()); // (exists by construction)
        shareContent.put(alias.getIndex(), alias.toDb());
        shareToAliasMapping.put(shareForNewAliases.get_id(), alias.getIndex());
      }//TESTED
      else if (null != sharesForThisAlias) {
        for (SharePojo share: sharesForThisAlias) {
          BasicDBObject shareContent =  shareContentCache.get(share.get_id());
          if (null == shareContent) {
            try {
              String json = share.getShare();
              shareContent = (BasicDBObject) JSON.parse(json);
              shareContentCache.put(share.get_id(), shareContent);
              sharesToUpdate.add(share);
            }
            catch (Exception e) {
              erroredAliases.add(alias.getIndex());             
            }
          }//TESTED
          shareContent.put(alias.getIndex(), alias.toDb());
          shareToAliasMapping.put(share.get_id(), alias.getIndex());
        }//TESTED
      }
      else {
        erroredAliases.add(alias.getIndex())
      }
      // end loop over updating shares
    }//end loop over aliases

    // Loop 2 now update all the shares
    boolean bSucceededUpdatingSomething = false;
    for (SharePojo share: sharesToUpdate) {
      BasicDBObject shareContent =  shareContentCache.get(share.get_id()); // (exists by construction)
      String shareIdStr = share.get_id().toString();
      this.updateShareJSON(shareIdStr, share.getTitle(), share.getDescription(), "infinite-entity-alias", shareContent.toString(), response);
      bSucceededUpdatingSomething |= response.isSuccess();
      if (!response.isSuccess()) {
        Set<String> failedAliases = shareToAliasMapping.get(share.get_id());
        if (null != failedAliases) {
          erroredAliases.addAll(failedAliases);
        }
      }
    }//TESTED   
   
    response.setSuccess(bSucceededUpdatingSomething);
    return erroredAliases;
  }
 
  // (Only use this version if immediately called after getAliases since none of this is in any way atomic)
  public Set<String> removeAliases(Collection<String> aliasesToRemove, String communityIdStr, Map<String, List<SharePojo>> aliasMapping, ResponseObject response) {
    if (null == aliasMapping) {
      aliasMapping = new HashMap<String, List<SharePojo>>();
      this.getAliases(communityIdStr, aliasMapping, response);
      if (!response.isSuccess()) {
        return null;
      }
    }//TESTED
    Map<ObjectId, BasicDBObject> shareContentCache = new HashMap<ObjectId, BasicDBObject>();
    List<SharePojo> sharesToUpdate = new LinkedList<SharePojo>();
    // Step through the aliases, update the content
    // Loop 1 update
    Set<String> erroredAliases = new HashSet<String>();
    HashMultimap<ObjectId, String> shareToAliasMapping = HashMultimap.create();
    for (String alias: aliasesToRemove) {
      List<SharePojo> sharesForThisAlias = aliasMapping.get(alias);
      if (null != sharesForThisAlias) {
        for (SharePojo share: sharesForThisAlias) {
          BasicDBObject shareContent =  shareContentCache.get(share.get_id());
          if (null == shareContent) {
            try {
              String json = share.getShare();
              shareContent = (BasicDBObject) JSON.parse(json);
              shareContentCache.put(share.get_id(), shareContent);
              sharesToUpdate.add(share);
            }
            catch (Exception e) {
              erroredAliases.add(alias);             
            }
          }//TESTED
          shareContent.remove(alias);
          shareToAliasMapping.put(share.get_id(), alias);
        }//TESTED
      }
      // end loop over updating shares
    }//end loop over aliases

    // Loop 2 now update all the shares
    boolean bSucceededUpdatingSomething = false;
    for (SharePojo share: sharesToUpdate) {
      BasicDBObject shareContent =  shareContentCache.get(share.get_id()); // (exists by construction)
      String shareIdStr = share.get_id().toString();
      if (shareContent.isEmpty()) { // Remove the share
        this.removeShare(shareIdStr, response);
        if (!response.isSuccess()) {
          Set<String> failedAliases = shareToAliasMapping.get(share.get_id());
          if (null != failedAliases) {
            erroredAliases.addAll(failedAliases);
          }
        }
      }//TESTED
      else {
        this.updateShareJSON(shareIdStr, share.getTitle(), share.getDescription(), "infinite-entity-alias", shareContent.toString(), response);
        bSucceededUpdatingSomething |= response.isSuccess();
        if (!response.isSuccess()) {
          Set<String> failedAliases = shareToAliasMapping.get(share.get_id());
          if (null != failedAliases) {
            erroredAliases.addAll(failedAliases);
          }
        }
      }//TESTED
    }//TESTED   
   
    response.setSuccess(bSucceededUpdatingSomething);
    return erroredAliases;
  }
  // THIS IS BOTH PUBLIC AND A UTILITY FOR THE OTHER CALLS
 
  public Map<String, EntityFeaturePojo> getAliases(String communityIdStr, ResponseObject response) {
    return getAliases(communityIdStr, null, response);
  }
 
  public Map<String, EntityFeaturePojo> getAliases(String communityIdStr, Map<String, List<SharePojo>> aliasMapping, ResponseObject response) {
   
    // Get the shares with the right type and community
    List<SharePojo> shareList = this.searchShares("community", communityIdStr, "infinite-entity-alias", response);
    if (!response.isSuccess()) {
      return null;
    }
    // Generate a list
    HashMap<String, EntityFeaturePojo> masterAliases = new HashMap<String, EntityFeaturePojo>();
   
    if (null != shareList) {
      for (SharePojo share: shareList) {
        populateAliasTableFromShare(share, masterAliases, aliasMapping);
      }
    }
    response.setSuccess(true);
    return masterAliases;
  }//TESTED
 
  // ALIAS UTILITIES:
 
  private SharePojo upsertSharePrep(String communityIdStr, Map<ObjectId, BasicDBObject> shareContentCache, Map<String, List<SharePojo>> aliasMapping) {
    SharePojo shareForNewAliases = null;
    BasicDBObject contentForNewAliases = null;
    for (List<SharePojo> shares: aliasMapping.values()) {
      if (!shares.isEmpty()) {
        shareForNewAliases = shares.iterator().next();
        try {
          String json = shareForNewAliases.getShare();
          contentForNewAliases = (BasicDBObject) JSON.parse(json);
          shareContentCache.put(shareForNewAliases.get_id(), contentForNewAliases);
          break;
        }
        catch (Exception e) {} // Try a different share
      }
    }//TESTED
    if (null == shareForNewAliases) { // Didn't find one, so going to have to create something
      EntityFeaturePojo discard = new EntityFeaturePojo();
      discard.setDisambiguatedName("DISCARD");
      discard.setType("SPECIAL");
      discard.setIndex("DISCARD");
      EntityFeaturePojo docDiscard = new EntityFeaturePojo();
      docDiscard.setDisambiguatedName("DOCUMENT_DISCARD");
      docDiscard.setType("SPECIAL");
      docDiscard.setIndex("DOCUMENT_DISCARD");
      contentForNewAliases = new BasicDBObject("DISCARD", discard.toDb());
      contentForNewAliases.put("DOCUMENT_DISCARD", docDiscard);
      ResponseObject response = new ResponseObject();
      shareForNewAliases = this.addShareJSON("Alias Share: " + communityIdStr, "An alias share for a specific community", "infinite-entity-alias", "{}", response);
      if ((null == shareForNewAliases) || !response.isSuccess()) {
        return null;
      }//TESTED
     
      // Remove share from personal community
      try {
        ShareCommunityPojo currCommunity =  shareForNewAliases.getCommunities().iterator().next();
        String removeCommunityIdStr = currCommunity.get_id().toString();
        if (!communityIdStr.equals(removeCommunityIdStr)) { // (obv not if this is my community somehow, don't think that's possible)
          this.removeShareFromCommunity(shareForNewAliases.get_id().toString(), removeCommunityIdStr, response);
          if (!response.isSuccess()) {
            return null;       
          }
        }
      }
      catch (Exception e) {} // do nothing I guess, not in any communities?
     
      this.addShareToCommunity(shareForNewAliases.get_id().toString(), "aliasComm", communityIdStr, response);
      if (!response.isSuccess()) {
        return null;       
      }
    }//TESTED
    shareContentCache.put(shareForNewAliases.get_id(), contentForNewAliases);
    return shareForNewAliases;
  }//TESTED
 
  // THIS IS A SUBSET OF com.ikanow.infinit.e.api.knowledge.aliases.AliasLookupTable
  private void populateAliasTableFromShare(SharePojo share, HashMap<String, EntityFeaturePojo> masterAliases,  Map<String, List<SharePojo>> aliasMapping) {
    String json = share.getShare();
    if (null != json) {
      try {
        DBObject dbo = (DBObject) JSON.parse(json);
        if (null != dbo) {
          for (Object entryObj: dbo.toMap().entrySet()) {
            @SuppressWarnings("unchecked")
            Map.Entry<String, Object> entry = (Map.Entry<String, Object>)entryObj;
           
            String masterAlias = entry.getKey();
           
            BasicDBObject entityFeatureObj = (BasicDBObject) entry.getValue();
            EntityFeaturePojo aliasInfo = null;
            try {
              aliasInfo = EntityFeaturePojo.fromDb(entityFeatureObj, EntityFeaturePojo.class);
            }
            catch (Exception e) {
              continue;
            }
            if (null == aliasInfo.getIndex()) {
              aliasInfo.setIndex(masterAlias);
            }

            if (null != aliasInfo) { // (allow getAlias to be null/empty)
              //(overwrite duplicates)
              masterAliases.put(aliasInfo.getIndex(), aliasInfo);
              if (null != aliasMapping) {
                List<SharePojo> shareList = aliasMapping.get(aliasInfo.getIndex());
                if (null == shareList) {
                  shareList = new LinkedList<SharePojo>();
                  aliasMapping.put(aliasInfo.getIndex(), shareList);
                }
                shareList.add(share);
              }
            }
          }
        }
      }
      catch (Exception e) {
       
      } // not Json, just carry on...
    }   
  }//TESTED
 
  public DimensionListPojo getEntitySuggest(String searchterm, String communityIdStr, boolean includeGeo, boolean includeLinkData, ResponseObject response)
  {   
    try
    {
      StringBuilder url = new StringBuilder(apiRoot).append("knowledge/feature/entitySuggest/");     
      url.append(URLEncoder.encode(searchterm,"UTF-8"));
      url.append("/");     
      url.append(URLEncoder.encode(communityIdStr,"UTF-8"));
     
      String json = sendRequest(url.toString(), null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(json, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      response = shallowCopy(response, internal_ro);
     
      return new Gson().fromJson((JsonElement)internal_responsePojo.getData(), DimensionListPojo.class);   
    }
    catch (Exception e)
    {
      response.setSuccess(false);
      response.setMessage(e.getMessage());
    }
    return null;
  }
 
  public List<SearchSuggestPojo> getGeoSuggest(Double latitude, Double longitude, String communityIdStr, ResponseObject response)
  {
    List<SearchSuggestPojo> locations = null;
    try
    {
      String searchterm = latitude + "," + longitude;
      StringBuilder url = new StringBuilder(apiRoot).append("knowledge/feature/geoSuggest/");     
      url.append(URLEncoder.encode(searchterm,"UTF-8"));
      url.append("/");     
      url.append(URLEncoder.encode(communityIdStr,"UTF-8"));
     
      String json = sendRequest(url.toString(), null);
      ResponsePojo internal_responsePojo = ResponsePojo.fromApi(json, ResponsePojo.class);
      ResponseObject internal_ro = internal_responsePojo.getResponse();
      response = shallowCopy(response, internal_ro);
     
      locations = ApiManager.mapListFromApi((JsonElement)internal_responsePojo.getData(), SearchSuggestPojo.listType(), null);     
    }
    catch (Exception e)
    {
      response.setSuccess(false);
      response.setMessage(e.getMessage());
    }
    return locations;
  }
 
 
  //////////////////////////////////////////////////////////////////////////////////////////////
 
  // UTILITY 
 
  public boolean hasSourceHarvested(String sourceId)
  {
    ResponseObject ro = new ResponseObject();
    return hasSourceHarvested(getSource(sourceId, ro));
  }
 
  public boolean hasSourceHarvested(SourcePojo source)
  {
    if ( source != null )
    {
      if ( source.getHarvestStatus() != null && source.getHarvestStatus().getHarvested() != null )
      {
        if ( source.getHarvestStatus().getHarvest_status() == HarvestEnum.in_progress && source.getHarvestStatus().getDoccount() != null && source.getHarvestStatus().getDoccount() > 0)
        {
          //if the source is in progress but has a doc count, it has already completed once
          return true;
        }
        else if ( source.getHarvestStatus().getHarvested() != null )
        {
          //if the source is not in progress but has a harvested date, it has completed atleast once
          return true;
        }
      }
    }
    return false;
  }
   
  public boolean isAdmin()
  {
    return this.sendKeepalive(true);
  }
 
  ///////// Request Calls 
 
  public String sendRequest(String urlAddress, String postData)
  {
    try {
      if (postData == null)
        return sendGetRequest(urlAddress);
      else
        return sendPostRequest(urlAddress, postData);
    } catch (Exception e) {
      e.printStackTrace();
      return "";
    }
  }

  private String sendPostRequest(String urlAddress, String data) throws MalformedURLException, IOException
  {
    return sendPostRequest(urlAddress, data, 0);
  }

  private String sendPostRequest(String urlAddress, String data, int redirects) throws MalformedURLException, IOException
 
    String result = "";

    if (urlAddress.startsWith("https:")) {
      TrustManagerManipulator.allowAllSSL();
    }
    URLConnection urlConnection = new URL(urlAddress).openConnection();

    if ( cookie != null )
      urlConnection.setRequestProperty("Cookie", cookie);
    if ( apiKey != null )
      urlConnection.setRequestProperty("Cookie", apiKey);

    urlConnection.setDoOutput(true);
    urlConnection.setRequestProperty("Accept-Charset", "UTF-8");
    ((HttpURLConnection)urlConnection).setRequestMethod("POST");

    // Post JSON string to URL

    OutputStream os = urlConnection.getOutputStream();

    byte[] b = data.getBytes("UTF-8");

    os.write(b);

    int status = ((HttpURLConnection)urlConnection).getResponseCode();
    // normally, 3xx is redirect
    if (status != HttpURLConnection.HTTP_OK)
    {
      if (status == HttpURLConnection.HTTP_MOVED_TEMP
        || status == HttpURLConnection.HTTP_MOVED_PERM
          || status == HttpURLConnection.HTTP_SEE_OTHER)
      {
        if (redirects <= 5) {
          String newUrlAddress = ((HttpURLConnection)urlConnection).getHeaderField("Location");
          if (null != newUrlAddress) {
            return sendPostRequest(newUrlAddress, data, redirects + 1);
          }
        }
        //(else carry on, will exception out or something below)
      }
    }//TESTED
   
    // Receive results back from API

    InputStream inStream = urlConnection.getInputStream();

    result = IOUtils.toString(inStream, "UTF-8");

    inStream.close();

    //save cookie if cookie is null
    if ( cookie == null )
    {
      String headername;
      for ( int i = 1; (headername = urlConnection.getHeaderFieldKey(i)) != null; i++ )
      {
        if ( headername.equals("Set-Cookie") )
        {
          cookie = urlConnection.getHeaderField(i);
          break;
        }
      }
    }    


    return result;
  }
 
 
  public String sendGetRequest(String urlAddress) throws Exception
  {
    return sendGetRequest(urlAddress, 0);
  }

  public String sendGetRequest(String urlAddress, int redirects) throws Exception
  {
    if (urlAddress.startsWith("https:")) {
      TrustManagerManipulator.allowAllSSL();
    }
   
    URL url = new URL(urlAddress);
    URLConnection urlConnection = url.openConnection();
    if ( cookie != null )
      urlConnection.setRequestProperty("Cookie", cookie);
    if ( apiKey != null )
      urlConnection.setRequestProperty("Cookie", apiKey);
     
    ((HttpURLConnection)urlConnection).setRequestMethod("GET");

    int status = ((HttpURLConnection)urlConnection).getResponseCode();
    // normally, 3xx is redirect
    if (status != HttpURLConnection.HTTP_OK)
    {
      if (status == HttpURLConnection.HTTP_MOVED_TEMP
        || status == HttpURLConnection.HTTP_MOVED_PERM
          || status == HttpURLConnection.HTTP_SEE_OTHER)
      {
        if (redirects <= 5) {
          String newUrlAddress = ((HttpURLConnection)urlConnection).getHeaderField("Location");
          if (null != newUrlAddress) {
            return sendGetRequest(newUrlAddress, redirects + 1);
          }
        }
        //(else carry on, will exception out or something below)
      }
    }//TESTED
   
    //read back result
    BufferedReader inStream = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
    StringBuilder strBuilder = new StringBuilder();
    String buffer;          
    while ( (buffer = inStream.readLine()) != null )
    {
      strBuilder.append(buffer);
    }      
    inStream.close();

    //save cookie if cookie is null
    if ( cookie == null )
    {
      String headername;
      for ( int i = 1; (headername = urlConnection.getHeaderFieldKey(i)) != null; i++ )
      {
        if ( headername.equals("Set-Cookie") )
        {
          cookie = urlConnection.getHeaderField(i);
          break;
        }
      }
    }      
    return strBuilder.toString();
 
 
 
  ///////////Password Encryption

  public String encryptEncodePassword(String pword) throws UnsupportedEncodingException, NoSuchAlgorithmException
  {
    return URLEncoder.encode(encryptWithoutEncode(pword), "UTF-8");
  }

  public static String encryptWithoutEncode(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException
 
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(password.getBytes("UTF-8"));

    return new String(Base64.encodeBase64(md.digest()));
  }
 
 
 
  //////////Shallow Copy Response Object
 
  private ResponseObject shallowCopy(ResponseObject toCopy, ResponseObject fromCopy)
  {
    toCopy.setAction(fromCopy.getAction());
    toCopy.setMessage(fromCopy.getMessage());
    toCopy.setSuccess(fromCopy.isSuccess());
    toCopy.setTime(fromCopy.getTime());
    return fromCopy;
  }
 
  ///////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////
 
  // Start of some test code
  // Run standalone RESTlet API on 8184 pointing to the right place
  // Invoke with username and password
 
  public static void main(String[] args) {
    if (args.length < 2) {
      System.out.println("*** CALL WITH username password as args");
      System.exit(-1);
    }
    InfiniteDriver.setDefaultApiRoot("http://localhost:8184/");
    InfiniteDriver infDriver = new InfiniteDriver();
    ResponseObject responseObject = new ResponseObject();
    infDriver.login(args[0], args[1], responseObject);
    System.out.println("DRIVER LOGIN = " + responseObject.isSuccess() + " : " + responseObject.getMessage());
    List<PersonPojo> people = infDriver.listPerson(responseObject);
    System.out.println("DRIVER LIST PEOPLE = " + responseObject.isSuccess() + " : " + responseObject.getMessage());
   
    if (null != people) {
      System.out.println("FOUND " + people.size());
      if (people.size() > 0) {
        System.out.println("EXAMPLE " + people.iterator().next().toDb());       
      }
    }
  }
}
TOP

Related Classes of com.ikanow.infinit.e.data_model.driver.InfiniteDriver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.