Package com.ikanow.infinit.e.api.social.community

Source Code of com.ikanow.infinit.e.api.social.community.CommunityHandler

/*******************************************************************************
* Copyright 2012, The Infinit.e Open Source Project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package com.ikanow.infinit.e.api.social.community;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.List;

import org.apache.log4j.Logger;
import org.bson.types.ObjectId;

import com.ikanow.infinit.e.api.config.source.SourceHandler;
import com.ikanow.infinit.e.api.custom.mapreduce.CustomHandler;
import com.ikanow.infinit.e.api.utils.SocialUtils;
import com.ikanow.infinit.e.api.utils.PropertiesManager;
import com.ikanow.infinit.e.api.utils.RESTTools;
import com.ikanow.infinit.e.data_model.utils.SendMail;
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.social.community.CommunityApprovalPojo;
import com.ikanow.infinit.e.data_model.api.social.community.CommunityPojoApiMap;
import com.ikanow.infinit.e.data_model.store.DbManager;
import com.ikanow.infinit.e.data_model.store.MongoDbManager;
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.DocCountPojo;
import com.ikanow.infinit.e.data_model.store.social.community.CommunityApprovePojo;
import com.ikanow.infinit.e.data_model.store.social.community.CommunityAttributePojo;
import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberContactPojo;
import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberLinkPojo;
import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberPojo;
import com.ikanow.infinit.e.data_model.store.social.community.CommunityMemberUserAttributePojo;
import com.ikanow.infinit.e.data_model.store.social.community.CommunityPojo;
import com.ikanow.infinit.e.data_model.store.social.community.CommunityUserAttributePojo;
import com.ikanow.infinit.e.data_model.store.social.person.PersonCommunityPojo;
import com.ikanow.infinit.e.data_model.store.social.person.PersonContactPojo;
import com.ikanow.infinit.e.data_model.store.social.person.PersonLinkPojo;
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.store.social.sharing.SharePojo.ShareOwnerPojo;
import com.ikanow.infinit.e.processing.generic.GenericProcessingController;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;

/**
* This class is for all operations related to the retrieval, addition
* or update of communities within the system
*/
public class CommunityHandler
{
  private static final Logger logger = Logger.getLogger(CommunityHandler.class);
  private SourceHandler sourceHandler = new SourceHandler();
 
  //////////////////////////////////////////////////////////////////////////
  ////////////////////////   REST handlers  ////////////////////////////////
  //////////////////////////////////////////////////////////////////////////
 
  /**
   * getCommunities (REST)
   * Returns information for all communities
   * @return
   */
  public ResponsePojo getCommunities(String userIdStr)
  { 
    ResponsePojo rp = new ResponsePojo();

    /////////////////////////////////////////////////////////////////////////////////////////////////
    // Note: Only Sys Admins see all communities
    boolean isSysAdmin = RESTTools.adminLookup(userIdStr);

    try
    {
      if (isSysAdmin)
      {
        DBCursor dbc = DbManager.getSocial().getCommunity().find();
       
        if ( dbc.count() > 0 )
        {
          List<CommunityPojo> communities = CommunityPojo.listFromDb(dbc, CommunityPojo.listType());
          filterCommunityMembers(communities, isSysAdmin, userIdStr);
          rp.setData(communities, new CommunityPojoApiMap());
          rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));       
        }
        else
        {
          rp.setResponse(new ResponseObject("Community Info", true, "No communities returned"))
        }
      }
      else // Get all public communities and all private communities to which the user belongs
      {
        // Set up the query
        BasicDBObject queryTerm1 = new BasicDBObject("communityAttributes.isPublic.value", "true");
        BasicDBObject queryTerm2 = new BasicDBObject("members._id", new ObjectId(userIdStr));
        BasicDBObject queryTerm3 = new BasicDBObject("ownerId", new ObjectId(userIdStr));
        BasicDBObject query = new BasicDBObject(MongoDbManager.or_, Arrays.asList(queryTerm1, queryTerm2, queryTerm3));

        DBCursor dbc = DbManager.getSocial().getCommunity().find(query);       
        if ( dbc.count() > 0 )
        {
          List<CommunityPojo> communities = CommunityPojo.listFromDb(dbc, CommunityPojo.listType());
          filterCommunityMembers(communities, isSysAdmin, userIdStr);
          //add personal community
          DBObject dbo = DbManager.getSocial().getCommunity().findOne(new BasicDBObject("_id",new ObjectId(userIdStr)));
          if ( dbo != null )
          {
            communities.add(CommunityPojo.fromDb(dbo, CommunityPojo.class));
          }
          rp.setData(communities, new CommunityPojoApiMap());
          rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));       
        }
        else
        {
          rp.setResponse(new ResponseObject("Community Info", true, "No communities returned"))
        }
      }
    }
    catch (Exception e)
    {
      logger.error("Exception Message: " + e.getMessage(), e);
      rp.setResponse(new ResponseObject("Community Info", false, "error returning community info"));
    }

    return rp;
  }
 

  /**
   * getCommunities (REST)
   * Returns information for communities where isPublic = true/false
   * @param isPublic
   * @return
   */
  public ResponsePojo getCommunities(String userIdStr, Boolean isPublic)
  {
    ResponsePojo rp = new ResponsePojo();
   
    /////////////////////////////////////////////////////////////////////////////////////////////////
    // Note: Only Sys Admins see private communities
    boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
   
    try
   
      // Set up the query
      BasicDBObject query = new BasicDBObject();
      query.put("communityAttributes.isPublic.value", isPublic.toString())
      if (!isPublic && !isSysAdmin)
      {
        //Add user ID to query so only get (private) communities of which I'm a member
        query.put("members._id", new ObjectId(userIdStr));
      }
      query.put("communityStatus", new BasicDBObject("$ne", "disabled"));
     
      DBCursor dbc = DbManager.getSocial().getCommunity().find(query);
      if ( dbc.count() > 0 )
      {
        List<CommunityPojo> communities = CommunityPojo.listFromDb(dbc, CommunityPojo.listType());
        filterCommunityMembers(communities, isSysAdmin, userIdStr);
        rp.setData(communities, new CommunityPojoApiMap());
        rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));       
      }
      else
      {
        rp.setResponse(new ResponseObject("Community Info", true, "No communities returned"))
      }
    }
    catch (Exception e)
    {
      logger.error("Exception Message: " + e.getMessage(), e);
      rp.setResponse(new ResponseObject("Community Info", false, "error returning community info"));
    }
    return rp;
  }
   
 
  /**
   * getCommunity (REST)
   * Returns information for a single community
   * @param communityIdStr
   * @return
   */
  public ResponsePojo getCommunity(String userIdStr, String communityIdStr, boolean showDocInfo)
  { 
    ResponsePojo rp = new ResponsePojo();
   
    try
    {
     
      // Set up the query
      BasicDBObject query = new BasicDBObject();
      if (communityIdStr != null)
      {
        communityIdStr = allowCommunityRegex(userIdStr, communityIdStr);
        query.put("_id", new ObjectId(communityIdStr));
      }
      else
      {
        query.put("_id", new ObjectId("4c927585d591d31d7b37097a")); // (hardwired sys community)
      }
     
      // Get GsonBuilder object with MongoDb de/serializers registered
      BasicDBObject dbo = (BasicDBObject)DbManager.getSocial().getCommunity().findOne(query);
     
      if (dbo != null)
      {
        CommunityPojo community = CommunityPojo.fromDb(dbo, CommunityPojo.class);
        if (showDocInfo) {
          DocCountPojo dc = (DocCountPojo) DbManager.getDocument().getCounts().findOne(query);
          if (null != dc) {
            dc.set_id(null);
            community.setDocumentInfo(dc);
          }
        }
        community = filterCommunityMembers(community, RESTTools.adminLookup(userIdStr), userIdStr);
        rp.setData(community, new CommunityPojoApiMap());
        rp.setResponse(new ResponseObject("Community Info", true, "Community info returned successfully"));
      }
      else
      {
        rp.setResponse(new ResponseObject("Community Info", false, "Unable to return information for the community specified."));
      }
    }
    catch (Exception e)
    {
      //logger.error("Exception Message: " + e.getMessage(), e);
      rp.setResponse(new ResponseObject("Community Info", false, "Error returning community info: " + e.getMessage()));
    }
    return rp;
  }

  /**
   * getSystemCommunity (REST)
   * @return ResponsePojo
   */
  public ResponsePojo getSystemCommunity()
  { 
    return getCommunity(null, null, false);
  }
 
  /**
   * addCommunity (REST)
   * Creates a new community
   * @param userIdStr
   * @param name
   * @param description
   * @param parentIdStr
   * @param parentName
   * @param tags
   * @param ownerId
   * @param ownerDisplayName
   * @return ResponsePojo
   */
  public ResponsePojo addCommunity(String userIdStr, String name, String description, String parentIdStr, String tags)
  {
    String userName = null;
    String userEmail = null;
    String parentName = null;
   
    try
    {
      DBObject dboperson = DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(userIdStr)));
     
      if ( dboperson != null )
      {
        PersonPojo person =  PersonPojo.fromDb(dboperson, PersonPojo.class);
        userName = person.getDisplayName();
        userEmail = person.getEmail();
     
        // Parent Community is Optional
        if (parentIdStr != null)
        {
          try {
            DBObject dboparent = DbManager.getSocial().getCommunity().findOne(new BasicDBObject("_id", new ObjectId(parentIdStr)));
            if ( dboparent != null )
            {
              CommunityPojo cp = CommunityPojo.fromDb(dboparent, CommunityPojo.class);
              parentName = cp.getName();
             
              if (cp.getIsPersonalCommunity()) {
                return new ResponsePojo(new ResponseObject("Add Community", false, "Can't create sub-community of personal community"));             
              }//TESTED
              if ((null == cp.getCommunityStatus()) || !cp.getCommunityStatus().equalsIgnoreCase("active")) {
                return new ResponsePojo(new ResponseObject("Add Community", false, "Can't create sub-community of inactive community"));             
              }//TESTED
              // Check attributes
              if (null != cp.getCommunityAttributes()) {
                CommunityAttributePojo attr = cp .getCommunityAttributes().get("usersCanCreateSubCommunities");
                if ((null == attr) || (null== attr.getValue()) || (attr.getValue().equals("false"))) {
                  if (!cp.isOwner(person.get_id()) && !SocialUtils.isModerator(userIdStr, cp) && !RESTTools.adminLookup(userIdStr)) {
                    return new ResponsePojo(new ResponseObject("Add Community", false, "Can't create sub-community when not permitted by parent"));
                  }//TESTED (owner+admin+mod)
                }
              }           
            }//TESTED - different restrictions as above
            else
            {
              return new ResponsePojo(new ResponseObject("Add Community", false, "Parent community does not exist"));
            }//TESTED
          }
          catch (Exception e) {
            return new ResponsePojo(new ResponseObject("Add Community", false, "Invalid parent community id"));
          }//TESTED
        }
      }
      else
      {
        return new ResponsePojo(new ResponseObject("Add Community", false, "Error: Unable to get person record"));
      }
    }
    catch (Exception ex)
    {
      return new ResponsePojo(new ResponseObject("Add Community", false, "General Error: " + ex.getMessage()));
    }
    return addCommunity(userIdStr, name, description, parentIdStr, parentName, tags, userIdStr, userName, userEmail);
  }
 
  /**
   * addCommunity (REST)
   * Creates a new community by id (alternate)
   */
  private ResponsePojo addCommunity(String userIdStr, String name, String description,
      String parentIdStr, String parentName, String tags, String ownerIdStr,
      String ownerDisplayName, String ownerEmail)
  {
    return addCommunity(userIdStr, null, name, description, parentIdStr, parentName, tags,
        ownerIdStr, ownerDisplayName, ownerEmail)
 
  public ResponsePojo addCommunity(String userId, String idStr, String name, String description,
      String parentIdStr, String parentName, String tags, String ownerIdStr,
      String ownerDisplayName, String ownerEmail)
  {
    ResponsePojo rp = new ResponsePojo();
   
    try
    {
      // Check to see if a community exists already with the supplied name or ID
      // do not create new one if true -
      // TODO (INF-1214): Think about need for unique names - proposed:
      //       Community names unique per parent community
      BasicDBObject query = new BasicDBObject();
      if (idStr == null)
      {
        query.put("name", name);   
      }
      else
      {
        query.put("_id", new ObjectId(idStr));
      }
      DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);     
     
      if (dbo == null)
      {
        ObjectId oId = null;
        if (idStr == null)
        {
          oId = new ObjectId();
        }
        else
        {
          oId = new ObjectId(idStr);
        }
        CommunityPojo c = new CommunityPojo();
        c.setId(oId);
        c.setCreated(new Date());
        c.setModified(new Date());
        c.setName(name);
        c.setDescription(description);
        if (parentIdStr != null && parentName != null)
        {
          c.setParentId(new ObjectId(parentIdStr));
          c.setParentName(parentName);
          c = SocialUtils.createParentTreeRecursion(c, false);
        }
        c.setIsPersonalCommunity(false);
        c.setTags(getTagsFromString(tags));
        c.setOwnerId(new ObjectId(ownerIdStr));
        c.setOwnerDisplayName(ownerDisplayName);
        c.setNumberOfMembers(0);
        c.setCommunityAttributes(getDefaultCommunityAttributes());
        c.setCommunityUserAttribute(getDefaultCommunityUserAttributes());
       
        // Insert new community document in the community collection
        DBObject commObj = c.toDb();

        // Create the index form of the community:
        try {
          GenericProcessingController.createCommunityDocIndex(c.getId().toString(), c.getParentId(), c.getIsPersonalCommunity(), c.getIsSystemCommunity(), false);
        }
        catch (Exception e) { // Can't create community
          rp.setResponse(new ResponseObject("Add Community", false, "Error adding new community because of index failure: " + e.getMessage()));
          return rp;
        }
        //TESTED
       
        DbManager.getSocial().getCommunity().save(commObj);       
       
        // If a child, update the parent:
        if (null != c.getParentId()) {
          BasicDBObject updateQuery = new BasicDBObject("_id", c.getParentId());
          BasicDBObject updateUpdate = new BasicDBObject(DbManager.addToSet_, new BasicDBObject("children", c.getId()));
          DbManager.getSocial().getCommunity().update(updateQuery, updateUpdate, false, true);
        }
        //TESTED
       
        // Update the new community record to add the owner to the list of members
        rp = addCommunityMember(userId, oId.toStringMongod(), name, ownerIdStr, ownerEmail, ownerDisplayName, "owner", "active");
        rp.setResponse(new ResponseObject("Add Community", true, "The " + name + " community has " +
          "been added."));       
      }
      else
      {
        rp.setResponse(new ResponseObject("Add Community", false,
            "Error adding new community. A community with the name " + name + " " +
            "already exists."));
      }
     
    }
    catch (Exception e)
    {
      // If an exception occurs log the error
      logger.error("Exception Message: " + e.getMessage(), e);
      rp.setResponse(new ResponseObject("Add Community", false,
          "Error adding new community " + e.getMessage()));
    }
    return rp;
  }

  /**
   * removeCommunity (REST)
   * Remove communityid only if the personid is the owner
   * TODO (INF-1214): Remove users from the groups in both personpojo and communitypojo
   *
   * @param personIdStr
   * @param communityIdStr
   * @return
   */
  public ResponsePojo removeCommunity(String personIdStr, String communityIdStr)
  {
    boolean isSysAdmin = RESTTools.adminLookup(personIdStr);
    ResponsePojo rp = new ResponsePojo();
    try
    {
      ObjectId communityId = new ObjectId(communityIdStr);
      //get the communitypojo
      communityIdStr = allowCommunityRegex(personIdStr, communityIdStr);
      DBObject communitydbo = DbManager.getSocial().getCommunity().findOne(new BasicDBObject("_id",communityId));
      if ( communitydbo != null )
      {
        CommunityPojo cp = CommunityPojo.fromDb(communitydbo, CommunityPojo.class);
        //get the personpojo
        DBObject persondbo = DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id",new ObjectId(personIdStr)));
        if ( persondbo != null )
        {
          //PersonPojo pp = gson.fromJson(persondbo.toString(),PersonPojo.class);
          if ( !cp.getIsPersonalCommunity() )
          {
            if ( cp.isOwner(new ObjectId(personIdStr)) || isSysAdmin )
            {
              if (cp.getCommunityStatus().equals("disabled")) { // Delete for good, this is going to be ugly...
               
                if ((null != cp.getChildren()) && !cp.getChildren().isEmpty()) {
                  rp.setResponse(new ResponseObject("Delete community", false, "Undeleted sub-communities exist, please delete them first"));
                  return rp;
                }
                //TESTED
               
                // 1] Remove from all shares (delete shares if that leaves them orphaned)
               
                BasicDBObject deleteQuery1 = new BasicDBObject(ShareCommunityPojo.shareQuery_id_, communityId);
                BasicDBObject deleteFields1 = new BasicDBObject(SharePojo.communities_, 1);
                List<SharePojo> shares = SharePojo.listFromDb(DbManager.getSocial().getShare().find(deleteQuery1, deleteFields1), SharePojo.listType());       
                for (SharePojo share: shares) {
                  if (1 == share.getCommunities().size()) { // delete this share
                    DbManager.getSocial().getShare().remove(new BasicDBObject(SharePojo._id_, share.get_id()));
                  }
                }
                BasicDBObject update1 = new BasicDBObject(DbManager.pull_, new BasicDBObject(SharePojo.communities_,
                                              new BasicDBObject(ShareOwnerPojo._id_, communityId)));
                DbManager.getSocial().getShare().update(deleteQuery1, update1, false, true);
               
                //TESTED (both types)
               
                // 2] Remove from all sources (also delete the documents)
                // (In most cases this will leave the source orphaned, so delete it)
               
                BasicDBObject deleteQuery2 = new BasicDBObject(SourcePojo.communityIds_, communityId);
                BasicDBObject deleteFields2 = new BasicDBObject(SourcePojo.communityIds_, 1);
                List<SourcePojo> sources = SourcePojo.listFromDb(DbManager.getIngest().getSource().find(deleteQuery2, deleteFields2), SourcePojo.listType());
                List<SourcePojo> failedSources = new ArrayList<SourcePojo>();
                for (SourcePojo source: sources)
                {
                  ResponsePojo rp1 = null;
                  SourceHandler tmpHandler = new SourceHandler();
                  if (1 == source.getCommunityIds().size()) { // delete this source
                    rp1 = tmpHandler.deleteSource(source.getId().toString(), communityIdStr, personIdStr, false);
                      // (deletes all docs and removes from the share)
                  }
                  else { // Still need to delete docs from this share from this community
                    rp1 = tmpHandler.deleteSource(source.getId().toString(), communityIdStr, personIdStr, true);                   
                  }
                  if ( rp1 != null && !rp1.getResponse().isSuccess() )
                  {
                    failedSources.add(source);
                  }
                }
               
                //if we have more than 1 failed source, bail out w/ error
                if (failedSources.size() > 0 )
                {
                  StringBuilder sb = new StringBuilder();
                  for ( SourcePojo source : failedSources )
                    sb.append(source.getId().toString() + " ");
                  rp.setResponse(new ResponseObject("Delete community", false, "Could not stop sources (they might be currently running): " + sb.toString()));
                  return rp;
                }
               
                BasicDBObject update2 = new BasicDBObject(DbManager.pull_, new BasicDBObject(SourcePojo.communityIds_, communityId));
                DbManager.getSocial().getShare().update(deleteQuery2, update2, false, true);

                //TESTED (both types, check docs deleted)
               
                // 3] Remove from all map reduce jobs (delete any that it is only comm left on)
                String customJobsMessage = removeCommunityFromJobs(personIdStr, communityId);
                if ( customJobsMessage.length() > 0)
                {
                  rp.setResponse(new ResponseObject("Delete community", false, "Could not stop all map reduce jobs (they might be currently running): " + customJobsMessage));
                  return rp;
                }
               
                // 4] Finally delete the object itself
               
                DbManager.getSocial().getCommunity().remove(new BasicDBObject("_id", communityId));
               
                // Remove from index:
                GenericProcessingController.deleteCommunityDocIndex(communityId.toString(), cp.getParentId(), false);
                //TESTED
               
                // 5] Finally finally remove from parent communities
                if (null != cp.getParentId()) {
                  BasicDBObject updateQuery = new BasicDBObject("_id", cp.getParentId());
                  BasicDBObject updateUpdate = new BasicDBObject(DbManager.pull_, new BasicDBObject("children", cp.getId()));
                  DbManager.getSocial().getCommunity().update(updateQuery, updateUpdate, false, true);                 
                }
                //TESTED
               
                rp.setResponse(new ResponseObject("Delete community", true, "Community deleted forever. " + customJobsMessage));
              }
              else { // First time, just remove all users and disable
                //at this point, we have verified, community/user exist, not a personal group, user is member and owner
                //set community as inactive (for some reason we don't delete it)
                DbManager.getSocial().getCommunity().update(new BasicDBObject("_id", communityId),
                                      new BasicDBObject(DbManager.set_, new BasicDBObject("communityStatus","disabled")));
               
                //remove all members
                for ( CommunityMemberPojo cmp : cp.getMembers())
                  removeCommunityMember(personIdStr, communityIdStr, cmp.get_id().toString());
                rp.setResponse(new ResponseObject("Delete community", true, "Community disabled successfully - call delete again to remove for good, including all sources, shares, and documents"));
              }
            }
            else
            {
              rp.setResponse(new ResponseObject("Delete community", false, "You are not the owner of this community"));
            }
          }
          else
          {
            rp.setResponse(new ResponseObject("Delete community", false, "Cannot delete personal community."));
          }         
        }
        else
        {
          rp.setResponse(new ResponseObject("Delete community", false, "Person ID was incorrect, no matching person found"));
        }
      }
      else
      {
        rp.setResponse(new ResponseObject("Delete community", false, "Community ID was incorrect, no matching commmunity found"));
      }

    }
    catch (Exception ex)
    {
      rp.setResponse(new ResponseObject("Delete community", false, "Error returning community info: " + ex.getMessage()));     
    }
   
    return rp;
  }
 
  /**
   * Removes this community from any map reduce jobs, then deletes any jobs where it was the only community
   *
   * @param communityId
   * @return
   */
  private String removeCommunityFromJobs(String personIdStr, ObjectId communityId)
  {
    StringBuilder sb = new StringBuilder();   
    List<CustomMapReduceJobPojo> failedToRemove = CustomHandler.removeCommunityJobs(communityId);       
    //return a list of job ids
    for ( CustomMapReduceJobPojo cmr : failedToRemove )
    {
      sb.append(cmr.jobtitle + " ");
    }
    if ( sb.length() > 0 )
    {
      sb.insert(0, "These map reduce jobs could not be removed: " );
    }
    return sb.toString();
  }

  // (Note supports personId as either Id or username (email) both are unique indexes)

  /**
   * updateMemberStatus (REST)
   */
 
  public ResponsePojo updateMemberStatus(String callerIdStr, String personIdStr, String communityIdStr, String userStatus)
  {
    boolean isSysAdmin = RESTTools.adminLookup(callerIdStr);
    ResponsePojo rp = new ResponsePojo();
    try
    {
      communityIdStr = allowCommunityRegex(callerIdStr, communityIdStr);
     
      //verify user is in this community, then update status
      BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
      DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
      if ( dbo != null )
      {
        // PersonId can be _id or username/email
        BasicDBObject dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("email", personIdStr));
        if (null == dboPerson) { // (ie personId isn't an email address... convert to ObjectId and try again)
          dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(personIdStr)));
        }
        else {
          personIdStr = dboPerson.getString("_id");
        }
        // OK from here on, personId is the object Id...
               
        boolean bAuthorized = isSysAdmin || SocialUtils.isOwnerOrModerator(communityIdStr, callerIdStr);
        if (bAuthorized) {
         
          CommunityPojo cp = CommunityPojo.fromDb(dbo,CommunityPojo.class);
          ObjectId personId = new ObjectId(personIdStr);
         
          if ( cp.isOwner(personId) && !userStatus.equalsIgnoreCase("active")) {           
            rp.setResponse(new ResponseObject("Update member status",false,"Can't change owner status, remove their ownership first"));
            return rp;
          }//TESTED (tried as owner+admin (failed both times), tested owner works fine if setting/keeping active)
          else if ( cp.isMember(personId) )
          {
            // Remove user:
            if (userStatus.equalsIgnoreCase("remove"))
            {
              //removeCommunityMember(callerIdStr, communityIdStr, personIdStr);
              rp = removeCommunityMember(callerIdStr, communityIdStr, personIdStr); //.setResponse(new ResponseObject("Update member status",true,"Member removed from community."));
            }
            else
            {
              //verified user, update status
              if ( cp.updateMemberStatus(personIdStr, userStatus) )
              {
                /////////////////////////////////////////////////////////////////////////////////////////////////
                // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
                // Caleb: this means change update to $set
                /////////////////////////////////////////////////////////////////////////////////////////////////
                DbManager.getSocial().getCommunity().update(query, cp.toDb());
                rp.setResponse(new ResponseObject("Update member status",true,"Updated member status successfully"));
              }
              else
              {
                rp.setResponse(new ResponseObject("Update member status",false,"Failed to update status"));
              }
            }
          }
          else
          {
            rp.setResponse(new ResponseObject("Update member status",false,"User was not a member of the community"));
          }
        }
        else
        {
          rp.setResponse(new ResponseObject("Update member status",false,"Caller must be admin, or a community owner or moderator"));
        }//TESTED - tried to update my status as member (failed), as admin (succeeded), as moderator (succeeded), as owner (succeeded) 
      }
      else
      {
        rp.setResponse(new ResponseObject("Update member status",false,"Community does not exist"));
      }     
    }
    catch(Exception ex)
    {
      rp.setResponse(new ResponseObject("Update member status",false,"General Error, bad params maybe? " + ex.getMessage()));
    }
    return rp;
  }//TESTED

  // (Note supports personId as either Id or username (email) both are unique indexes)

  /**
   * updateMemberType (REST)
   */
  public ResponsePojo updateMemberType(String callerIdStr, String personIdStr, String communityIdStr, String userType)
  {
    boolean isSysAdmin = RESTTools.adminLookup(callerIdStr);
    ResponsePojo rp = new ResponsePojo();
    try
    {
      if (!userType.equalsIgnoreCase("owner") && !userType.equalsIgnoreCase("moderator") && !userType.equalsIgnoreCase("member") && !userType.equalsIgnoreCase("content_publisher"))
      {
        rp.setResponse(new ResponseObject("Update member type",false,"Invalid user type: " + userType));
        return rp;
      }//TESTED - tested all the types work, hacked members.jsp to insert invalid type
     
      //verify user is in this community, then update status
      communityIdStr = allowCommunityRegex(callerIdStr, communityIdStr);
      BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
      DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
      if ( dbo != null )
      {
        // PersonId can be _id or username/email
        BasicDBObject dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("email", personIdStr));
        if (null == dboPerson) { // (ie personId isn't an email address... convert to ObjectId and try again)
          dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(personIdStr)));
        }
        else {
          personIdStr = dboPerson.getString("_id");
        }
        // OK from here on, personId is the object Id...

        CommunityPojo cp = CommunityPojo.fromDb(dbo,CommunityPojo.class);
       
        boolean bOwnershipChangeRequested = userType.equalsIgnoreCase("owner");
        boolean bAuthorized = isSysAdmin;
        if (!bAuthorized) {
          if (bOwnershipChangeRequested) { // must be owner or admin       
            bAuthorized = cp.isOwner(new ObjectId(callerIdStr));
          }//TESTED - tried to update myself as moderator to owner (failed), gave up my community (succeeded), changed ownership as admin (FAILED)
          else { // Can also be moderator
            bAuthorized = SocialUtils.isOwnerOrModerator(communityIdStr, callerIdStr);         
          }//TESTED - tried to update my role as member (failed), as admin->moderator (succeeded), as moderator (succeeded)
        }
       
        if (bAuthorized) // (see above)
        {
          if ( cp.isMember(new ObjectId(personIdStr)))
          {
            boolean bChangedMembership = false;
            boolean bChangedOwnership = !bOwnershipChangeRequested;
           
            ObjectId personId = new ObjectId(personIdStr);
           
            // Check that not trying to downgrade owner...
            if (cp.isOwner(personId) && !bOwnershipChangeRequested) {
              rp.setResponse(new ResponseObject("Update member type",false,"To change ownership, set new owner, will automatically downgrade existing owner to moderator"));
              return rp;
            }//TESTED
           
            String personDisplayName = null;
            //verified user, update status
            for ( CommunityMemberPojo cmp : cp.getMembers())
            {
              if ( cmp.get_id().equals(personId) )
              {
                cmp.setUserType(userType)
                personDisplayName = cmp.getDisplayName();
                bChangedMembership = true;
               
                if (bChangedOwnership) { // (includes case where didn't need to)
                  break;
                }
               
              }//TESTED
              if (bOwnershipChangeRequested && cmp.get_id().equals(cp.getOwnerId())) {
                cmp.setUserType("moderator");
                bChangedOwnership = true;
               
                if (bChangedMembership) {
                  break;
                }
               
              }//TESTED
            }
            if (bChangedMembership) {
              if (bOwnershipChangeRequested) {
                cp.setOwnerId(personId);
                cp.setOwnerDisplayName(personDisplayName);
              }//TESTED
             
              /////////////////////////////////////////////////////////////////////////////////////////////////
              // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
              // Caleb: this means change update to $set
              /////////////////////////////////////////////////////////////////////////////////////////////////
              DbManager.getSocial().getCommunity().update(query, cp.toDb());
              rp.setResponse(new ResponseObject("Update member type",true,"Updated member type successfully"));
            }//TESTED                 
          }
          else
          {
            rp.setResponse(new ResponseObject("Update member type",false,"User was not a member of the community"));
          }
        }
        else
        {
          rp.setResponse(new ResponseObject("Update member type",false,"Caller must be admin/owner/moderator (unless changing ownership)"));
        }
      }
      else
      {
        rp.setResponse(new ResponseObject("Update member type",false,"Community does not exist"));
      }     
    }
    catch(Exception ex)
    {
      rp.setResponse(new ResponseObject("Update member type",false,"General Error, bad params maybe? " + ex.getMessage()));
    }
    return rp;
  }//TESTED (see sub-clauses for details)

  /**
   * joinCommunity (REST)
   */
  public ResponsePojo joinCommunity(String personIdStr, String communityIdStr)
  {
    boolean isSysAdmin = RESTTools.adminLookup(personIdStr);
    return joinCommunity(personIdStr, communityIdStr, isSysAdmin);
  }
 
  public ResponsePojo joinCommunity(String personIdStr, String communityIdStr, boolean isSysAdmin)
  {   
    ResponsePojo rp = new ResponsePojo();
    try
    {     
      communityIdStr = allowCommunityRegex(personIdStr, communityIdStr);
      BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
      DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
      if ( dboComm != null )
      {
        CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
        if ( !cp.getIsPersonalCommunity() )
        {
          BasicDBObject queryPerson = new BasicDBObject("_id",new ObjectId(personIdStr));
          DBObject dboPerson = DbManager.getSocial().getPerson().findOne(queryPerson);
          PersonPojo pp = PersonPojo.fromDb(dboPerson,PersonPojo.class);
          boolean isPending = isMemberPending(cp, pp);
         
          if ( !cp.isMember(new ObjectId(personIdStr)) || isPending )
          {
            Map<String,CommunityAttributePojo> commatt = cp.getCommunityAttributes();
            if ( isSysAdmin || (commatt.containsKey("usersCanSelfRegister") && commatt.get("usersCanSelfRegister").getValue().equals("true") ))
            {   
              boolean requiresApproval = false;
              if ( !isSysAdmin && commatt.containsKey("registrationRequiresApproval") )
                requiresApproval = commatt.get("registrationRequiresApproval").getValue().equals("true");
              //if approval is required, add user to comm, wait for owner to approve
              //otherwise go ahead and add as a member
              if ( requiresApproval )
              {
                cp.addMember(pp,true);
                //write both objects back to db now
                /////////////////////////////////////////////////////////////////////////////////////////////////
                // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
                // Caleb: this means change update to $set
                /////////////////////////////////////////////////////////////////////////////////////////////////
                DbManager.getSocial().getCommunity().update(query, cp.toDb());
                             
                //send email out to owner for approval
                CommunityApprovePojo cap = cp.createCommunityApprove(personIdStr,communityIdStr,"join",personIdStr);
                DbManager.getSocial().getCommunityApprove().insert(cap.toDb());
               
                // Get to addresses for Owner and Moderators
                String toAddresses = getToAddressesFromCommunity(cp);
               
                PropertiesManager propManager = new PropertiesManager();
                String rootUrl = propManager.getUrlRoot();
               
                String subject = pp.getDisplayName() + " is trying to join infinit.e community: " + cp.getName();
                String body = pp.getDisplayName() + " is trying to join infinit.e community: " + cp.getName() + "<br/>Do you want to accept this request?" +
                "<br/><a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/true\">Accept</a> " +
                "<a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/false\">Deny</a>";
               
                SendMail mail = new SendMail(new PropertiesManager().getAdminEmailAddress(), toAddresses, subject, body);
               
                if (mail.send("text/html"))
                {
                  rp.setResponse(new ResponseObject("Join Community",true,"Joined community successfully, awaiting owner approval"));
                  rp.setData(new CommunityApprovalPojo(false));
                }
                else
                {
                  rp.setResponse(new ResponseObject("Join Community",false,"The system was uable to send an email to the owner"));               
                }
              }
              else
              {
                cp.addMember(pp);
                pp.addCommunity(cp);
                //write both objects back to db now
                /////////////////////////////////////////////////////////////////////////////////////////////////
                // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
                // Caleb: this means change update to $set
                /////////////////////////////////////////////////////////////////////////////////////////////////
                DbManager.getSocial().getCommunity().update(query, cp.toDb());
                DbManager.getSocial().getPerson().update(queryPerson, pp.toDb());
                rp.setResponse(new ResponseObject("Join Community",true,"Joined community successfully"));
                rp.setData(new CommunityApprovalPojo(true));
              }           
            }
            else
            {
              rp.setResponse(new ResponseObject("Join Community",false,"You must be invited to this community"));
            }
          }
          else
          {
            rp.setResponse(new ResponseObject("Join Community",false,"You are already a member of this community"));
          }
        }
        else
        {
          rp.setResponse(new ResponseObject("Join Community",false,"Cannot add members to personal community"));
        }
      }
      else
      {
        rp.setResponse(new ResponseObject("Join Community",false,"Community does not exist"));
      }
    }
    catch(Exception ex)
    {
      rp.setResponse(new ResponseObject("Join Community",false,"General Error, bad params maybe? " + ex.getMessage()));
    }
    return rp;
  }
 
  /**
   * leaveCommunity (REST)
   */
 
  public ResponsePojo leaveCommunity(String personIdStr, String communityIdStr)
  {
    ResponsePojo rp = new ResponsePojo();
    try
    {
      communityIdStr = allowCommunityRegex(personIdStr, communityIdStr);
      BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
      DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
      if ( dboComm != null )
      {
        CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
        if ( !cp.getIsPersonalCommunity())
        {
          BasicDBObject queryPerson = new BasicDBObject("_id",new ObjectId(personIdStr));
          DBObject dboPerson = DbManager.getSocial().getPerson().findOne(queryPerson);
          PersonPojo pp = PersonPojo.fromDb(dboPerson,PersonPojo.class);
          cp.removeMember(new ObjectId(personIdStr));
          pp.removeCommunity(cp);         
          //write both objects back to db now
          /////////////////////////////////////////////////////////////////////////////////////////////////
          // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
          // Caleb: this means change update to $set
          /////////////////////////////////////////////////////////////////////////////////////////////////
          DbManager.getSocial().getCommunity().update(query, cp.toDb());
          DbManager.getSocial().getPerson().update(queryPerson, pp.toDb());
          rp.setResponse(new ResponseObject("Leave Community",true,"Left community successfully"));
        }
        else
        {
          rp.setResponse(new ResponseObject("Leave Community",false,"Cannot leave personal community"));
        }
      }
      else
      {
        rp.setResponse(new ResponseObject("Leave Community",false,"Community does not exist"));
      }
    }
    catch(Exception ex)
    {
      rp.setResponse(new ResponseObject("Leave Community",false,"General Error, bad params maybe? " + ex.getMessage()));
    }
    return rp;
  }


  /**
   * inviteCommunity (REST)
   * Invite a user to a community, only add them as pending to community
   * and do not add community into the person object yet
   * Need to send email out
  // (Note supports personId as either Id or username (email) both are unique indexes)
   * @param personIdStr
   * @param userIdStr
   * @param communityIdStr
   * @return
   */
  public ResponsePojo inviteCommunity(String userIdStr, String personIdStr, String communityIdStr, String skipInvitation)
  {
    ResponsePojo rp = new ResponsePojo();
    try {
      communityIdStr = allowCommunityRegex(userIdStr, communityIdStr);
    }
    catch (Exception e) {
      rp.setResponse(new ResponseObject("Invite Community", false, "Error returning community info: " + e.getMessage()));
      return rp;
    }
   
    boolean skipInvite = ((null != skipInvitation) && (skipInvitation.equalsIgnoreCase("true"))) ? true : false;
   
    /////////////////////////////////////////////////////////////////////////////////////////////////
    // Note: Only Sys Admins, Community Owner, and Community Moderators can invite users to
    // private communities however any member can be able to invite someone to a public community
    boolean isOwnerOrModerator = SocialUtils.isOwnerOrModerator(communityIdStr, userIdStr);
    boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
    boolean canInvite = (isOwnerOrModerator || isSysAdmin) ? true : false;

    try
    {
      BasicDBObject query = new BasicDBObject("_id",new ObjectId(communityIdStr));
      DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
     
      if ( dboComm != null )
      {
        CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
       
        // Make sure this isn't a personal community
        if ( !cp.getIsPersonalCommunity() )
        {
          // Check to see if the user has permissions to invite or selfregister
          boolean selfRegister = canSelfRegister(cp);
          if ( canInvite || cp.getOwnerId().toString().equalsIgnoreCase(userIdStr) || selfRegister )
          {
            BasicDBObject dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("email", personIdStr));
            if (null == dboPerson) { // (ie personId isn't an email address... convert to ObjectId and try again)
              dboPerson = (BasicDBObject) DbManager.getSocial().getPerson().findOne(new BasicDBObject("_id", new ObjectId(personIdStr)));
            }
            else {
              personIdStr = dboPerson.getString("_id");
            }
            // OK from here on, personId is the object Id...
           
            if ( dboPerson != null )
            {
              PersonPojo pp = PersonPojo.fromDb(dboPerson,PersonPojo.class);             
              //need to check for if a person is pending, and skipInvite and isSysAdmin, otherwise
              //they would just get sent an email again, so leave it be
              boolean isPending = false;
              if ( isSysAdmin && skipInvite )
              {
                isPending = isMemberPending(cp, pp);
              }
             
              if ( selfRegister )
              {
                //If the comm allows for self registering, just call join community
                //instead of invite, it will handle registration
                return this.joinCommunity(pp.get_id().toString(), communityIdStr, isSysAdmin);
              }
              else if ( !cp.isMember(pp.get_id()) || isPending )
              {
                if (isSysAdmin && skipInvite) // Can only skip invite if user is Admin
                {
                  // Update community with new member
                  cp.addMember(pp, false); // Member status set to Active
                  cp.setNumberOfMembers(cp.getNumberOfMembers() + 1); // Increment number of members
                  /////////////////////////////////////////////////////////////////////////////////////////////////
                  // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
                  // Caleb: this means change update to $set
                  /////////////////////////////////////////////////////////////////////////////////////////////////
                  DbManager.getSocial().getCommunity().update(query, cp.toDb());
                 
                  // Add community to persons object and save to db
                  pp.addCommunity(cp);
                  /////////////////////////////////////////////////////////////////////////////////////////////////
                  // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
                  // Caleb: this means change update to $set
                  /////////////////////////////////////////////////////////////////////////////////////////////////
                  DbManager.getSocial().getPerson().update(new BasicDBObject("_id", pp.get_id()), pp.toDb());
                 
                  rp.setResponse(new ResponseObject("Invite Community",true,"User added to community successfully."));
                }
                else
                {
                  cp.addMember(pp, true); // Member status set to Pending
                  /////////////////////////////////////////////////////////////////////////////////////////////////
                  // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
                  // Caleb: this means change update to $set
                  /////////////////////////////////////////////////////////////////////////////////////////////////
                  DbManager.getSocial().getCommunity().update(query, cp.toDb());
                 
                  //send email out inviting user
                  CommunityApprovePojo cap = cp.createCommunityApprove(personIdStr,communityIdStr,"invite",userIdStr);
                  DbManager.getSocial().getCommunityApprove().insert(cap.toDb());
                 
                  PropertiesManager propManager = new PropertiesManager();
                  String rootUrl = propManager.getUrlRoot();
                 
                  if (null == rootUrl) {
                    rp.setResponse(new ResponseObject("Invite Community",false,"The system was unable to email the invite because an invite was required and root.url is not set up."));
                    return rp;
                  }
                 
                  String subject = "Invite to join infinit.e community: " + cp.getName();
                  String body = "You have been invited to join the community " + cp.getName() +
                    "<br/><a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/true\">Accept</a> " +
                    "<a href=\"" + rootUrl + "social/community/requestresponse/"+cap.get_id().toString() + "/false\">Deny</a>";
                 
                  SendMail mail = new SendMail(new PropertiesManager().getAdminEmailAddress(), pp.getEmail(), subject, body);
                 
                  if (mail.send("text/html"))
                  {
                    if (isSysAdmin) {
                      rp.setResponse(new ResponseObject("Invite Community",true,"Invited user to community successfully: " + cap.get_id().toString()));
                    }
                    else {
                      rp.setResponse(new ResponseObject("Invite Community",true,"Invited user to community successfully"));                 
                    }
                  }
                  else
                  {
                    rp.setResponse(new ResponseObject("Invite Community",false,"The system was unable to email the invite for an unknown reason (eg an invite was required and the mail server is not setup)."));
                  }
                }
              }
              else
              {               
                //otherwise just return we failed
                rp.setResponse(new ResponseObject("Invite Community",false,"The user is already a member of this community."));
              }
            }
            else
            {
              rp.setResponse(new ResponseObject("Invite Community",false,"Person does not exist"));
            }
          }
          else
          {
            rp.setResponse(new ResponseObject("Invite Community",false,"You must be owner to invite other members, if you received an invite, you must accept it through that"));
          }
        }
        else
        {
          rp.setResponse(new ResponseObject("Invite Community",false,"Cannot invite members to personal community"));
        }
      }
      else
      {
        rp.setResponse(new ResponseObject("Invite Community",false,"Community does not exist"));
      }
    }
    catch(Exception ex)
    {
      rp.setResponse(new ResponseObject("Invite Community",false,"General Error, bad params maybe? " + ex.getMessage()));
    }
    return rp;
  }
 
  /**
   * Returns true if users can self register to this community
   *
   * @param cp
   * @return
   */
  private boolean canSelfRegister(CommunityPojo cp)
  {
    if ( cp != null )
    {
      if ( cp.getCommunityAttributes().containsKey("usersCanSelfRegister") &&
          cp.getCommunityAttributes().get("usersCanSelfRegister").getValue().equals("true"))
      {
        return true;
      }
    }
    return false;
  }
 
  /**
   * Returns true if the given member is pending in the given community
   *
   * @return
   */
  private boolean isMemberPending( CommunityPojo cp, PersonPojo pp)
  {                 
    for ( CommunityMemberPojo cmp : cp.getMembers() )
    {
      if ( cmp.get_id().equals(pp.get_id()) )
      {
        if ( cmp.getUserStatus().equals("pending") )
        {
          //found the user, and his status is pending
          return true;
        }
        return false;
      }
    }
    return false;
    //TESTED only finds members that are pending while sysadmin
  }


  /**
   * requestResponse (REST)
   * @param requestIdStr
   * @param resp
   * @return
   */
  public ResponsePojo requestResponse(String requestIdStr, String resp)
  {
    ResponsePojo rp = new ResponsePojo();
    try
    {
      // Check for valid text response value
      if ( resp.equals("true") || resp.equals("false") )
      {
        // Attempt to retrieve the invite from the social.communityapprove collection
        DBObject dbo = DbManager.getSocial().getCommunityApprove().findOne(new BasicDBObject("_id", new ObjectId(requestIdStr)));
       
        if (dbo != null )
        {
          CommunityApprovePojo cap = CommunityApprovePojo.fromDb(dbo, CommunityApprovePojo.class);
          if ( cap.getType().equals("source"))
          {
            //approving a source
            if ( resp.equals("true"))
            {
              rp = sourceHandler.approveSource(cap.getSourceId(), cap.getCommunityId(), cap.getRequesterId());
            }
            else
            {
              rp = sourceHandler.denySource(cap.getSourceId(), cap.getCommunityId(), cap.getRequesterId());
            }
            if ( rp.getResponse().isSuccess() )
            {
              //remove request object now
              DbManager.getSocial().getCommunityApprove().remove(new BasicDBObject("_id",new ObjectId(requestIdStr)));
            }
          }
          else
          {
            //approving a user joining a community
            BasicDBObject query = new BasicDBObject("_id",new ObjectId(cap.getCommunityId()));
            DBObject dboComm = DbManager.getSocial().getCommunity().findOne(query);
           
            //get user
            BasicDBObject queryPerson = new BasicDBObject("_id",new ObjectId(cap.getPersonId()));
            DBObject dboperson = DbManager.getSocial().getPerson().findOne(queryPerson);
            PersonPojo pp = PersonPojo.fromDb(dboperson, PersonPojo.class);
           
            if ( dboComm != null )
            {
              CommunityPojo cp = CommunityPojo.fromDb(dboComm, CommunityPojo.class);
              boolean isStillPending = isMemberPending(cp, pp);
              //make sure the user is still waiting to join the community, otherwise remove this request and return
              if ( isStillPending )
              {
                if ( resp.equals("false"))
                {
                  //if response is false (deny), always just remove user from community             
                  cp.removeMember(new ObjectId(cap.getPersonId()));
                  /////////////////////////////////////////////////////////////////////////////////////////////////
                  // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
                  // Caleb: this means change update to $set
                  /////////////////////////////////////////////////////////////////////////////////////////////////
                  DbManager.getSocial().getCommunity().update(query, cp.toDb());
                }
                else
                {
                  //if response is true (allow), always just add community info to user, and change status to active
                 
                  if ( dboperson != null)
                  {
                    cp.updateMemberStatus(cap.getPersonId(), "active");
                    cp.setNumberOfMembers(cp.getNumberOfMembers()+1);
                    /////////////////////////////////////////////////////////////////////////////////////////////////
                    // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
                    // Caleb: this means change update to $set
                    /////////////////////////////////////////////////////////////////////////////////////////////////
                    DbManager.getSocial().getCommunity().update(query, cp.toDb());
                    pp.addCommunity(cp);
                    /////////////////////////////////////////////////////////////////////////////////////////////////
                    // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
                    // Caleb: this means change update to $set
                    /////////////////////////////////////////////////////////////////////////////////////////////////
                    DbManager.getSocial().getPerson().update(queryPerson, pp.toDb());
                  }
                  else
                  {
                    rp.setResponse(new ResponseObject("Request Response",false,"The person does not exist."));
                  }
                }
                //return successfully
                rp.setResponse(new ResponseObject("Request Response",true,"Request answered successfully!"));
              }
              else
              {
                //return fail
                rp.setResponse(new ResponseObject("Request Response",false,"Request has already been answered!"));
              }
              //remove request object now
              DbManager.getSocial().getCommunityApprove().remove(new BasicDBObject("_id",new ObjectId(requestIdStr)));
             
            }
            else
            {
              rp.setResponse(new ResponseObject("Request Response",false,"The community does not exist."));
            }
          }
        }
        else
        {
          rp.setResponse(new ResponseObject("Request Response",false,"This request does not exist, possibly answered already?"));
        }
      }
      else
      {
        rp.setResponse(new ResponseObject("Request Response",false,"Reponse must be true or false"));
      }
    }
    catch(Exception ex)
    {
      rp.setResponse(new ResponseObject("Request Response",false,"General Error, bad params maybe?"  + ex.getMessage()));
    }
    return rp;
  }
 

  /**
   * updateCommunity (REST)
   * Updates a community found with communityId with fields from updateItem (communitypojo in json form)
   * Must be owner of communityId to update
   * @param userIdStr
   * @param communityIdStr
   * @param json
   * @return
   */
  public ResponsePojo updateCommunity(String userIdStr, String communityIdStr, String json)
  {
    ResponsePojo rp = new ResponsePojo();
    try {
      communityIdStr = allowCommunityRegex(userIdStr, communityIdStr);
    }
    catch (Exception e) {
      rp.setResponse(new ResponseObject("Update Community", false, "Error returning community info: " + e.getMessage()));
      return rp;
    }
   
    /////////////////////////////////////////////////////////////////////////////////////////////////
    // Note: Only Sys Admins, Community Owner, and Community Moderators can add update communities
    boolean isOwnerOrModerator = SocialUtils.isOwnerOrModerator(communityIdStr, userIdStr);
    boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
    boolean canUpdate = (isOwnerOrModerator || isSysAdmin) ? true : false
    if (!canUpdate)
    {
      rp.setResponse(new ResponseObject("Update Community",false,"User does not have permission to update the community."));
      return rp;
    }
   
    /////////////////////////////////////////////////////////////////////////////////////////////////
    // Attempt to parse the JSON passed in to a CommunityPojo
    CommunityPojo updateCommunity = null;
    try
    {
      updateCommunity = ApiManager.mapFromApi(json, CommunityPojo.class, new CommunityPojoApiMap());
    }
    catch (Exception ex)
    {
      rp.setResponse(new ResponseObject("Update Community",false,"Update json is badly formatted, could not deserialize."));
      return rp;
    }
   
    try
    {
      // Retrieve community we are trying to update from the database
      BasicDBObject query = new BasicDBObject("_id", new ObjectId(communityIdStr));
      DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);
      String originalName = null;
     
      if ( dbo != null )
      {
       
        CommunityPojo cp = CommunityPojo.fromDb(dbo, CommunityPojo.class);
       
        if (null == cp) {
          rp.setResponse(new ResponseObject("Update Community",false,"Community to update does not exist"));
          return rp;
        }
        // Here are the fields you are allowed to change:
        // name:
        if (null != updateCommunity.getName())
        {
          // If you're changing name then ensure it's unique for consistency
          //TODO (INF-1214): see addCommunity, this is currently something of a security hole
          BasicDBObject nameCheck = new BasicDBObject("name", updateCommunity.getName());
          nameCheck.put("_id", new BasicDBObject(MongoDbManager.ne_, cp.getId()));
          if (null != MongoDbManager.getSocial().getCommunity().findOne(nameCheck)) {
            rp.setResponse(new ResponseObject("Update Community",false,"Can't change name to an existing community"));
            return rp;           
          }//TESTED (tested changing names of existing community works...)   
          originalName = cp.getName();
          cp.setName(updateCommunity.getName());
        }
        if (null != updateCommunity.getDescription()) {
          cp.setDescription(updateCommunity.getDescription());         
        }
        if (null != updateCommunity.getTags()) {
          cp.setTags(updateCommunity.getTags());         
        }
        if ((null != updateCommunity.getCommunityAttributes() && !updateCommunity.getCommunityAttributes().isEmpty()))
        {
          cp.setCommunityAttributes(updateCommunity.getCommunityAttributes());         
        }
        if ((null != updateCommunity.getCommunityUserAttribute() && !updateCommunity.getCommunityUserAttribute().isEmpty()))
        {
          cp.setCommunityUserAttribute(updateCommunity.getCommunityUserAttribute());         
        }
        // Change owner: not allowed here, use community/update/status
        if ((null != updateCommunity.getOwnerId()) && !updateCommunity.getOwnerId().equals(cp.getOwnerId()))
        {
          rp.setResponse(new ResponseObject("Update Community",false,"Use community/update/status to change ownership"));
          return rp;
        }//TESTED
               
        DbManager.getSocial().getCommunity().update(query, cp.toDb());
               
        // Community name has changed, member records need to be updated to reflect the name change
        if (originalName != null)
        {
          DBObject query_person = new BasicDBObject("communities.name", originalName);
          DBObject update_person = new BasicDBObject("$set",new BasicDBObject("communities.$.name", updateCommunity.getName()));         
          DbManager.getSocial().getPerson().update(query_person, update_person, false, true);
         
          //Also need to update share community names to reflect the name change
          DBObject query_share = new BasicDBObject("communities.name", originalName);
          DBObject update_share = new BasicDBObject("$set",new BasicDBObject("communities.$.name", updateCommunity.getName()));         
          DbManager.getSocial().getShare().update(query_share, update_share, false, true);
        }
       
       
        /////////////////////////////////////////////////////////////////////////////////////////////////
        // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
        // propagate out to other records like Person
        // caleb note: 1/7 (change this to use $set is what this means,
        // including above DbManager.getSocial().getCommunity().update(query, cp.toDb()); )
        // and the below unwritten communityuserattri
        /////////////////////////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////////////////////////
        // Community.communityUserAttribute
        // If user attributes have changed we might need to update member records...

       
        rp.setResponse(new ResponseObject("Update Community", true, "Community updated successfully."));
      }
      else
      {
        rp.setResponse(new ResponseObject("Update Community",false,"Community does not exist"));
      }
    }
    catch (Exception ex)
    {
      rp.setResponse(new ResponseObject("Update Community",false,"Unable to update community. Error:" + ex.getMessage()));
    }
    return rp;
  }
 
  //////////////////////////////////////////////////////////////////////////
  //////////////////////// Helper Functions ////////////////////////////////
  //////////////////////////////////////////////////////////////////////////

  /**
   * addCommunityMember (only called internally and by PersonHandler)
   * @param communityIdStr
   * @param personIdStr
   * @param email
   * @param displayName
   * @param userType
   * @param userStatus
   * @return
   */
  private ResponsePojo addCommunityMember(String userIdStr, String communityIdStr, String communityName,
      String personIdStr, String email, String displayName, String userType, String userStatus)
  {
    return addCommunityMember(userIdStr,communityIdStr,communityName,personIdStr,email,displayName,userType,userStatus,false);
  }
 
  public ResponsePojo addCommunityMember(String userIdStr, String communityIdStr, String communityName,
      String personIdStr, String email, String displayName, String userType, String userStatus, boolean override)
  {
    /////////////////////////////////////////////////////////////////////////////////////////////////
    // Note: Only Sys Admins, Community Owner, and Community Moderators can add users to communities
    boolean isOwnerOrModerator = SocialUtils.isOwnerOrModerator(communityIdStr, userIdStr);
    boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
    boolean canAdd = (isOwnerOrModerator || isSysAdmin || override) ? true : false;
   
    ResponsePojo rp = new ResponsePojo();
   
    if (canAdd)
    {
      try
      {
        // Find person record to update
        BasicDBObject query = new BasicDBObject();
        query.put("_id", new ObjectId(communityIdStr));

        DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);

        if (dbo != null)
        {
          // Get GsonBuilder object with MongoDb de/serializers registered
          CommunityPojo community = CommunityPojo.fromDb(dbo, CommunityPojo.class);

          // Get the list of existing members, check to see if user is already
          // a member of the community, make sure CommunityMember obj isn't null/empty
          Boolean alreadyMember = false;       
          Set<CommunityMemberPojo> cmps = null;
          if (community.getMembers() != null)
          {
            cmps = community.getMembers();
            for (CommunityMemberPojo c : cmps)
            {
              if (c.get_id().toStringMongod().equals(personIdStr)) alreadyMember = true;
            }
          }
          else
          {
            cmps = new HashSet<CommunityMemberPojo>();
            community.setMembers(cmps);
          }

          if (!alreadyMember)
          {
            // Note: This changes community owner
            if (userType.equals("owner"))
            {
              community.setOwnerId(new ObjectId(personIdStr));
              community.setOwnerDisplayName(displayName);
            }

            // Create the new member object
            CommunityMemberPojo cmp = new CommunityMemberPojo();
            cmp.set_id(new ObjectId(personIdStr));
            cmp.setEmail(email);
            cmp.setDisplayName(displayName);
            cmp.setUserStatus(userStatus);
            cmp.setUserType(userType);

            // Set the userAttributes based on default
            Set<CommunityMemberUserAttributePojo> cmua = new HashSet<CommunityMemberUserAttributePojo>();
            Map<String,CommunityUserAttributePojo> cua = community.getCommunityUserAttribute();

            Iterator<Map.Entry<String,CommunityUserAttributePojo>> it = cua.entrySet().iterator();
            while (it.hasNext())
            {
              CommunityMemberUserAttributePojo c = new CommunityMemberUserAttributePojo();
              Map.Entry<String,CommunityUserAttributePojo> pair = it.next();
              c.setType(pair.getKey().toString());
              CommunityUserAttributePojo v = (CommunityUserAttributePojo)pair.getValue();
              c.setValue(v.getDefaultValue());
              cmua.add(c);
            }
            cmp.setUserAttributes(cmua);

            // Get Person data to added to member record
            BasicDBObject query2 = new BasicDBObject();
            query2.put("_id", new ObjectId(personIdStr));
            DBObject dbo2 = DbManager.getSocial().getPerson().findOne(query2);
            PersonPojo p = PersonPojo.fromDb(dbo2, PersonPojo.class);

            if (p.getContacts() != null)
            {
              // Set contacts from person record
              Set<CommunityMemberContactPojo> contacts = new HashSet<CommunityMemberContactPojo>();
              Map<String, PersonContactPojo> pcp = p.getContacts();
              Iterator<Map.Entry<String, PersonContactPojo>> it2 = pcp.entrySet().iterator();
              while (it2.hasNext())
              {
                CommunityMemberContactPojo c = new CommunityMemberContactPojo();
                Map.Entry<String, PersonContactPojo> pair = it2.next();
                c.setType(pair.getKey().toString());
                PersonContactPojo v = (PersonContactPojo)pair.getValue();
                c.setValue(v.getValue());
                contacts.add(c);
              }
              cmp.setContacts(contacts);
            }

            // Set links from person record
            if (p.getLinks() != null)
            {
              // Set contacts from person record
              Set<CommunityMemberLinkPojo> links = new HashSet<CommunityMemberLinkPojo>();
              Map<String, PersonLinkPojo> plp = p.getLinks();
              Iterator<Map.Entry<String, PersonLinkPojo>> it3 = plp.entrySet().iterator();
              while (it.hasNext())
              {
                CommunityMemberLinkPojo c = new CommunityMemberLinkPojo();
                Map.Entry<String, PersonLinkPojo> pair = it3.next();
                c.setTitle(pair.getKey().toString());
                PersonLinkPojo v = (PersonLinkPojo)pair.getValue();
                c.setUrl(v.getUrl());
                links.add(c);
              }
              cmp.setLinks(links);
            }

            // Add new member object to the set
            cmps.add(cmp);

            // Increment number of members by 1
            community.setNumberOfMembers(community.getNumberOfMembers() + 1);

            /////////////////////////////////////////////////////////////////////////////////////////////////
            // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
            // Caleb: this means change update to $set
            /////////////////////////////////////////////////////////////////////////////////////////////////
            DbManager.getSocial().getCommunity().update(query, community.toDb());

            PersonHandler person = new PersonHandler();
            person.addCommunity(personIdStr, communityIdStr, communityName);

            rp.setData(community, new CommunityPojoApiMap());

            rp.setResponse(new ResponseObject("Add member to community", true, "Person has been added as member of community"))
          }         
          else
          {
            rp.setResponse(new ResponseObject("Add member to community",true,"Person is already a member of the community."))
          }
        }
        else
        {
          rp.setResponse(new ResponseObject("Add member to community", false, "Community not found."));
        }
      }
      catch (Exception e)
      {     
        // If an exception occurs log the error
        logger.error("Exception Message: " + e.getMessage(), e);
        rp.setResponse(new ResponseObject("Add member to community", false,
            "Error adding member to community " + e.getMessage()));
     
    }
    else
    {
      rp.setResponse(new ResponseObject("Add member to community", false,
        "The user does not have permissions to add a user to the community."));
    }
   
    return rp;
  }

 
  /**
   * removeCommunityMember (only called internally and from PersonHandler)
   * @param userIdStr
   * @param communityIdStr
   * @param personIdStr
   * @return ResponsePojo
   */
  public ResponsePojo removeCommunityMember(String userIdStr, String communityIdStr, String personIdStr)
  {
    /////////////////////////////////////////////////////////////////////////////////////////////////
    // Note: Only Sys Admins, Community Owner, and Community Moderators can remove users
    boolean isOwnerOrModerator = SocialUtils.isOwnerOrModerator(communityIdStr, userIdStr);
    boolean isSysAdmin = RESTTools.adminLookup(userIdStr);
    boolean canRemove = (isOwnerOrModerator || isSysAdmin) ? true : false;
   
    ResponsePojo rp = new ResponsePojo();
   
    if (canRemove)
    {
      try
      {
        // Find person record to update
        BasicDBObject query = new BasicDBObject();
        query.put("_id", new ObjectId(communityIdStr));
        DBObject dbo = DbManager.getSocial().getCommunity().findOne(query);

        if (dbo != null)
        {
          // Get GsonBuilder object with MongoDb de/serializers registered
          CommunityPojo community = CommunityPojo.fromDb(dbo, CommunityPojo.class);

          Boolean isMember = false;

          Set<CommunityMemberPojo> cmps = null;
          CommunityMemberPojo cmp = null;
          if (community.getMembers() != null)
          {
            cmps = community.getMembers();
            for (CommunityMemberPojo c : cmps)
            {
              if (c.get_id().toStringMongod().equals(personIdStr))
              {
                cmp = c;
                isMember = true;
              }
            }
          }

          if (isMember)
          {
            cmps.remove(cmp);

            community.setNumberOfMembers(community.getNumberOfMembers() - 1);

            /////////////////////////////////////////////////////////////////////////////////////////////////
            // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
            // Caleb: this means change update to $set
            /////////////////////////////////////////////////////////////////////////////////////////////////         
            DbManager.getSocial().getCommunity().update(query, community.toDb());

            PersonHandler person = new PersonHandler();
            person.removeCommunity(personIdStr, communityIdStr);

            rp.setData(community, new CommunityPojoApiMap());
            rp.setResponse(new ResponseObject("Remove member from community", true, "Member has been removed from community"))
          }         
          else
          {
            rp.setResponse(new ResponseObject("Remove member from community",true,"Person is not a member of this community."))
          }
        }
        else
        {
          rp.setResponse(new ResponseObject("Remove member from community", false, "Community not found."));
        }
      }
      catch (Exception e)
      {     
        // If an exception occurs log the error
        logger.error("Exception Message: " + e.getMessage(), e);
        rp.setResponse(new ResponseObject("Remove member from community", false,
            "Error removing member from community " + e.getMessage()));
     
    }
    else
    {
      rp.setResponse(new ResponseObject("Remove member from community", false,
          "The user does not have permissions to remove a user from the community."));
    }
   
    return rp;
  }
 
  /**
   * createSelfCommunity
   * Creates a personal group for the given user and adds them to it.
   * @param person
   */
  public void createSelfCommunity(PersonPojo person)
  {
    try
    {
      //create community
      CommunityPojo selfCommunity = new CommunityPojo();
      selfCommunity.setId(person.get_id()); //set to same as users
      selfCommunity.setName(person.getDisplayName() + "'s Personal Community");
      selfCommunity.setDescription(person.getDisplayName() + "'s Personal Community");
      selfCommunity.setCreated(new Date());
      selfCommunity.setModified(new Date());
      selfCommunity.setIsPersonalCommunity(true);   
      Map<String,CommunityAttributePojo> commAttributes = new HashMap<String,CommunityAttributePojo>();
      commAttributes.put("isPublic", new CommunityAttributePojo("boolean","false") );
      commAttributes.put("usersCanSelfRegister", new CommunityAttributePojo("boolean","false") );
      commAttributes.put("registrationRequiresApproval", new CommunityAttributePojo("boolean","false") );
      commAttributes.put("usersCanCreateSubCommunities", new CommunityAttributePojo("boolean","false") );
      selfCommunity.setCommunityAttributes(commAttributes);
      Map<String,CommunityUserAttributePojo> commUserAttributes = new HashMap<String,CommunityUserAttributePojo>();
      commUserAttributes.put("publishLoginToActivityFeed", new CommunityUserAttributePojo("boolean","true",true));
      commUserAttributes.put("publishCommentsToActivityFeed", new CommunityUserAttributePojo("boolean","true",true));
      commUserAttributes.put("publishSharingToActivityFeed", new CommunityUserAttributePojo("boolean","true",true));
      commUserAttributes.put("publishQueriesToActivityFeed", new CommunityUserAttributePojo("boolean","true",true));
      commUserAttributes.put("publishCommentsPublicly", new CommunityUserAttributePojo("boolean","false",true));
      selfCommunity.setCommunityUserAttribute(commUserAttributes);
      selfCommunity.setNumberOfMembers(0);
     
      // Create the index form of the community:
      try {
        GenericProcessingController.createCommunityDocIndex(selfCommunity.getId().toString(), null, true, false, false);
        //TESTED
      }
      catch (Exception e) {} // Do nothing, will have to update the user to stop bad things from happening on query though
     
      //write community to db
      DbManager.getSocial().getCommunity().insert(selfCommunity.toDb());
      //update user to be in this community
      PersonCommunityPojo pcpSelf = new PersonCommunityPojo(person.get_id(), selfCommunity.getName());
      person.getCommunities().add(pcpSelf);
      /////////////////////////////////////////////////////////////////////////////////////////////////
      // TODO (INF-1214): Make this code more robust to handle changes to the community that need to
      // Caleb: this means change update to $set
      /////////////////////////////////////////////////////////////////////////////////////////////////
      DbManager.getSocial().getPerson().update(new BasicDBObject("_id",person.get_id()), person.toDb());
    }
    catch (Exception ex)
    {
     
    }
  }
 


  //////////////////////////////////////////////////////////////////////////
  //////////////////////// Helper Functions ////////////////////////////////
  ///////// These functions do not get called from the public API //////////
  //////////////////////////////////////////////////////////////////////////
 
  /**
   * getToAddressesFromCommunity (Internal)
   * @param cp
   * @return
   */
  private static String getToAddressesFromCommunity(CommunityPojo cp)
  {
    StringBuffer emailAddresses = new StringBuffer();
    emailAddresses.append(cp.getOwner().getEmail());
   
    for (CommunityMemberPojo cm : cp.getMembers())
    {
      if (cm.getUserType().equalsIgnoreCase("moderator"))
      {
        emailAddresses.append(";" + cm.getEmail());
      }
    }
   
    return emailAddresses.toString();
  }
 
  /**
   * getTagsFromString
   * @param t
   * @return List<String>
   */
  private List<String> getTagsFromString(String t)
  {
    List<String> tags = new ArrayList<String>();
    if (t != null)
    { 
      try
      {
        String[] a = t.split(",");
        for (String v : a)
        {
          tags.add(v);
        }
      }
      catch (Exception e)
      {
      }
    }
    return tags;
 
 
  /**
   * getDefaultCommunityAttributes
   * @return Map<String, CommunityAttributePojo
   */
  private Map<String, CommunityAttributePojo> getDefaultCommunityAttributes()
  {
    Map<String, CommunityAttributePojo> c = new HashMap<String, CommunityAttributePojo>();
    CommunityAttributePojo v = new CommunityAttributePojo()
    v.setType("Boolean");
    v.setValue("false");
    c.put("isPublic", v);
    v = new CommunityAttributePojo();
    v.setType("Boolean");
    v.setValue("true");
    c.put("usersCanSelfRegister", v);
    v = new CommunityAttributePojo();
    v.setType("Boolean");
    v.setValue("true");
    c.put("registrationRequiresApproval", v);
    v = new CommunityAttributePojo();
    v.setType("Boolean");
    v.setValue("false");
    c.put("usersCanCreateSubCommunities", v);
    return c;
  }
 
  /**
   * getDefaultCommunityUserAttributes
   * @return Map<String, CommunityUserAttributePojo>
   */
  private Map<String, CommunityUserAttributePojo> getDefaultCommunityUserAttributes()
  {
    Map<String, CommunityUserAttributePojo> c = new HashMap<String, CommunityUserAttributePojo>();
    CommunityUserAttributePojo v = new CommunityUserAttributePojo();
    v.setType("Boolean");
    v.setDefaultValue("true");
    v.setAllowOverride(false);
    c.put("publishLoginToActivityFeed", v);
    v = new CommunityUserAttributePojo();
    v.setType("Boolean");
    v.setDefaultValue("true");
    v.setAllowOverride(false);
    c.put("publishCommentsToActivityFeed", v);
    v = new CommunityUserAttributePojo();
    v.setType("Boolean");
    v.setDefaultValue("true");
    v.setAllowOverride(false);
    c.put("publishSharingToActivityFeed", v);
    v = new CommunityUserAttributePojo();
    v.setType("Boolean");
    v.setDefaultValue("true");
    v.setAllowOverride(false);
    c.put("publishQueriesToActivityFeed", v);
    v = new CommunityUserAttributePojo();
    v.setType("Boolean");
    v.setDefaultValue("false");
    v.setAllowOverride(false);
    c.put("publishCommentsPublicly", v);
    return c;
  }
 
  /**
   * Utility function to remove members if users are not suppose to see them
   *
   * @param inputCommunities
   * @param isAdminModerator
   * @return
   */
  private CommunityPojo filterCommunityMembers(CommunityPojo community, boolean isAdmin, String userId)
  {
    //an admin can see everything
    if ( !(isAdmin || SocialUtils.isOwnerOrModerator(community.getId().toString(), userId) ) )
    {
      //if community has publish members turned off, remove the members
      if ( community.getCommunityAttributes().containsKey("publishMemberOverride") &&
          community.getCommunityAttributes().get("publishMemberOverride").getValue().equals("false") )
      {
        community.setMembers(null);
      }       
    }
    return community;
  }
  private List<CommunityPojo> filterCommunityMembers(List<CommunityPojo> inputCommunities, boolean isAdmin, String userId)
  {
    //an admin can see everything
    if ( !isAdmin )
    {
      for ( CommunityPojo community : inputCommunities )
      {
        filterCommunityMembers(community, isAdmin, userId);
      }     
    }
    return inputCommunities;
  }
 
  // Utility: make life easier in terms of adding/update/inviting/leaving from the command line
 
  private static String allowCommunityRegex(String userIdStr, String communityIdStr) {
    if (communityIdStr.startsWith("*")) {
      String[] communityIdStrs = SocialUtils.getCommunityIds(userIdStr, communityIdStr)
      if (1 == communityIdStrs.length) {
        communityIdStr = communityIdStrs[0];
      }
      else if (communityIdStrs.length > 0) {
        throw new RuntimeException("Invalid community pattern (many): " + Arrays.toString(communityIdStrs));       
      }
      else {
        throw new RuntimeException("Invalid community pattern (none)");
      }
    } 
    return communityIdStr;
  }   
 
 
}
TOP

Related Classes of com.ikanow.infinit.e.api.social.community.CommunityHandler

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.