com.eywa.impl.app.mongo.services.ContactService.java Source code

Java tutorial

Introduction

Here is the source code for com.eywa.impl.app.mongo.services.ContactService.java

Source

/*
 * EYWA.COM (Eywa Commerce)
 * This program is an integrated platform with E-Commerce and Configurator system.
 * Support: Please, contact the Author on http://www.smartfeeling.org.
 * Copyright (C) 2014  Gian Angelo Geminiani
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * 
 */
package com.eywa.impl.app.mongo.services;

import com.eywa.impl.app.mongo.entities.Contact;
import com.eywa.impl.app.mongo.entities.Hub;
import com.eywa.impl.app.mongo.entities.User;
import com.eywa.impl.app.mongo.entities.items.ItemBillingUser;
import com.eywa.impl.app.server.utils.HtmlUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import org.json.JSONObject;
import org.ly.Smartly;
import org.ly.commons.logging.Level;
import org.ly.commons.util.CollectionUtils;
import org.ly.commons.util.StringUtils;
import org.ly.packages.mongo.impl.AbstractMongoService;
import org.ly.packages.mongo.impl.MongoPage;
import org.ly.packages.mongo.impl.StandardCodedException;
import org.ly.packages.mongo.impl.util.MongoUtils;
import org.ly.proxies.DBProxy;

import java.util.*;
import java.util.regex.Pattern;

/**
 * @author angelo.geminiani
 */
public class ContactService extends AbstractMongoService {

    private static final String SPECIAL_FILTER_COLLABORATOR = "#collaborator";
    private static final String SPECIAL_FILTER_USER = "#user";

    // --------------------------------------------------------------------
    //               c o n s t r u c t o r
    // --------------------------------------------------------------------

    public ContactService() throws Exception {
        super((DB) DBProxy.get().getDBMain(), Contact.COLLECTION, Smartly.getLanguages());
    }

    // --------------------------------------------------------------------
    //               p u b l i c
    // --------------------------------------------------------------------

    // use only for test unit
    public int upsertSimple(final DBObject item) throws StandardCodedException {
        return super.upsert(item);
    }

    public DBObject create(final String hubId, final JSONObject item) throws StandardCodedException {
        final DBObject hub = HubService.getHub(hubId);
        if (null != hub) {
            final Contact contact = new Contact(item.toString());
            final String ownerId = Hub.getUserId(hub);

            Contact.setId(contact, Contact.createUUID());
            Contact.setOwnerId(contact, ownerId);
            Contact.setHubId(contact, hubId);
            Contact.setDomainId(contact, Hub.getDomainId(hub));

            this.upsert(contact);

            return contact;
        }
        return null;
    }

    @Override
    public int upsert(final DBObject item) throws StandardCodedException {

        // description
        final String description = Contact.getDescription(item);
        if (StringUtils.hasText(description)) {
            final HtmlUtils.HtmlText html = HtmlUtils.toHtml(description);
            Contact.setDescriptionHtml(item, html.getHtml());
            Contact.setKeywords(item, html.getTagsList());
        }

        // realname
        final String name = Contact.getName(item);
        final String second_name = Contact.getSurname(item);
        Contact.setRealname(item, name.concat(" ").concat(second_name));

        // emails
        Contact.addEmail(item, Contact.getEmail(item));

        // account_id
        final String accountId = Contact.getAccountId(item);
        if (!StringUtils.hasText(accountId)) {
            final DBObject user = UserService.getOneByEmails(item, new String[] { User.ID });
            if (null != user) {
                Contact.setAccountId(item, User.getId(user));
                if (StringUtils.hasText(User.getImage(user))) {
                    Contact.setImage(item, User.getImage(user));
                }
            }
        }

        // search keys
        Contact.regenerateDescription(item);
        Contact.regenerateParallelArrayKey(item);

        //-- save hashtags --//
        HashtagService.asyncAdd(Contact.COLLECTION, Contact.getOwnerId(item), Contact.getHubId(item),
                Contact.getKeywords(item));

        return super.upsert(item);
    }

    public DBObject createHubOwner(final String hubId) throws StandardCodedException {
        final DBObject hub = HubService.getHub(hubId);
        if (null != hub) {
            final String ownerId = Hub.getUserId(hub);
            return this.createFromUser(hub, ownerId);
        }
        return null;
    }

    public DBObject createHubOwner(final DBObject hub) throws StandardCodedException {
        if (null != hub) {
            final String ownerId = Hub.getUserId(hub);
            return this.createFromUser(hub, ownerId);
        }
        return null;
    }

    public DBObject createFromUser(final String hubId, final String userId) throws StandardCodedException {
        final DBObject hub = HubService.getHub(hubId);
        if (null != hub) {
            return this.createFromUser(hub, userId);
        }
        return null;
    }

    /**
     * Search all contacts for user matching by "email".
     * All matching items "accountId" fields are updated to current userId.
     *
     * @param user User to match by email
     * @return List of contact's id
     * @throws org.ly.packages.mongo.impl.StandardCodedException
     */
    public Set<String> matchAndUpdate(final DBObject user) throws StandardCodedException {
        final Set<String> result = new HashSet<String>();
        // get all user emails
        final List<String> emails = User.getEmails(user);
        if (!CollectionUtils.isEmpty(emails)) {
            final String[] emails_array = emails.toArray(new String[emails.size()]);
            final DBObject query = MongoUtils.queryIn(Contact.EMAILS, emails_array); // new BasicDBObject(Contact.EMAILS, emails_array);
            final List<DBObject> matched_users = super.find(query);
            if (!CollectionUtils.isEmpty(matched_users)) {
                final String accountId = User.getId(user);
                final String image = User.getImage(user);
                final String lang = User.getLang(user);
                for (final DBObject item : matched_users) {
                    result.add(Contact.getId(item)); // add contactId to result
                    Contact.setAccountId(item, accountId);
                    Contact.setLang(item, lang);
                    if (StringUtils.hasText(image)) {
                        Contact.setImage(item, image);
                    }
                    super.upsert(item);
                }
            }
        }
        return result;
    }

    /**
     * Move Contact to recycle bin.
     *
     * @param id ID of Contact
     * @return List of moved Contacts
     * @throws org.ly.packages.mongo.impl.StandardCodedException
     */
    public List<DBObject> moveToRecycleBin(final String id) throws StandardCodedException {
        final List<DBObject> result = new LinkedList<DBObject>();
        final DBObject resource = super.findOne(new BasicDBObject(Contact.ID, id));
        if (null != resource) {
            final String ownerID = Contact.getOwnerId(resource);
            final DBObject recycleBin = HubService.getRecycleBin(ownerID);
            final String recycleBinId = Hub.getId(recycleBin);
            // change contact container (HUB_ID)
            Contact.setPrevHubId(resource, Contact.getHubId(resource));
            Contact.setHubId(resource, recycleBinId);
            super.upsert(resource);
            result.add(resource);
        }
        return result;
    }

    public DBObject getByEmail(final String email) {
        final DBObject query = new BasicDBObject();
        query.put(Contact.EMAILS, email);
        return super.findOne(query);
    }

    public List<DBObject> getByHubAndKeywords(final String hubId, final Collection<String> keywords,
            final String[] fieldNames) {
        final DBObject query = new BasicDBObject();
        query.put(Contact.HUB_ID, hubId);
        MongoUtils.queryIn(query, Contact.PARALLEL_ARRAY_KEY, keywords.toArray(new String[keywords.size()]));

        final String[] sortAsc = new String[] { Contact.NAME };
        final String[] sortDes = new String[] {};

        return super.find(query, fieldNames, sortAsc, sortDes);
    }

    public MongoPage lookup(final String hubId, final int skip, final int limit,
            final Collection<String> keywords) {
        final DBObject query = new BasicDBObject();
        query.put(Contact.HUB_ID, hubId);
        MongoUtils.queryIn(query, Contact.PARALLEL_ARRAY_KEY, keywords.toArray(new String[keywords.size()]));

        final String[] fieldNames = null;
        final String[] sortAsc = new String[] { Contact.NAME };
        final String[] sortDes = new String[] {};

        return super.paged(query, fieldNames, skip, limit, sortAsc, sortDes);
    }

    public MongoPage lookup(final String hubId, final int skip, final int limit, final String searchText) {

        DBObject query1 = null;
        DBObject query2 = null;

        if (!StringUtils.isNULL(hubId)) {
            query1 = new BasicDBObject();
            // lookup in current hub and between "cross-hub" contacts
            final BasicDBList conditions = new BasicDBList();
            conditions.add(MongoUtils.queryEquals(Contact.HUB_ID, hubId, MongoUtils.CASE_INSENSITIVE));
            conditions.add(MongoUtils.queryEquals(Contact.HUB_ID, Hub.HUB_ALL, MongoUtils.CASE_INSENSITIVE));
            query1.put(MongoUtils.OP_OR, conditions);
        }

        if (!StringUtils.isNULL(searchText)) {
            if (SPECIAL_FILTER_COLLABORATOR.equalsIgnoreCase(searchText)) {
                query2 = new BasicDBObject();
                query2.put(Contact.COLLABORATION_HUBS, hubId);
            } else if (SPECIAL_FILTER_USER.equalsIgnoreCase(searchText)) {
                query2 = new BasicDBObject();
                MongoUtils.queryNotEmpty(query2, Contact.ACCOUNT_ID);
            } else if (searchText.startsWith("#")) {
                query2 = new BasicDBObject();
                query2.put(Contact.PARALLEL_ARRAY_KEY, searchText.substring(1));
            } else {
                query2 = new BasicDBObject();
                final BasicDBList conditions = new BasicDBList();
                conditions.add(MongoUtils.queryEquals(Contact.ID, searchText, MongoUtils.CASE_INSENSITIVE));
                conditions.add(MongoUtils.queryEquals(Contact.OWNER_ID, searchText, MongoUtils.CASE_INSENSITIVE));
                conditions.add(MongoUtils.queryContains(Contact.NAME, searchText, MongoUtils.CASE_INSENSITIVE));
                conditions.add(MongoUtils.queryContains(Contact.SURNAME, searchText, MongoUtils.CASE_INSENSITIVE));
                conditions.add(
                        MongoUtils.queryContains(Contact.DESCRIPTION, searchText, MongoUtils.CASE_INSENSITIVE));
                // conditions.add(MongoUtils.queryEquals(Contact.EMAIL, searchText, MongoUtils.CASE_INSENSITIVE));
                //conditions.add(MongoUtils.queryEquals(Contact.KEYWORDS, searchText, MongoUtils.CASE_INSENSITIVE));
                conditions.add(MongoUtils.queryEquals(Contact.PARALLEL_ARRAY_KEY, searchText,
                        MongoUtils.CASE_INSENSITIVE));

                query2.put(MongoUtils.OP_OR, conditions);
            }
        }

        DBObject query = null;
        if (null != query1 && null != query2) {
            query = new BasicDBObject();
            final BasicDBList conditions = new BasicDBList();
            conditions.add(query1);
            conditions.add(query2);
            query.put(MongoUtils.OP_AND, conditions);
        } else if (null == query2) {
            query = query1;
        } else {
            query = query2;
        }

        final String[] fieldNames = null;
        final String[] sortAsc = new String[] { Contact.SURNAME, Contact.NAME };
        final String[] sortDes = new String[] {};

        return super.paged(query, fieldNames, skip, limit, sortAsc, sortDes);
    }

    public int countByOwner(final String ownerId) {
        return this.countAllByUserId(ownerId);
    }

    public int countContactsByHub(final String hubId) {
        return this.countAllByHubId(hubId);
    }

    public int countByHubAndKeywords(final String hubId, final Collection<String> keywords) {
        return this.countAllByHubIdAndKeywords(hubId, keywords);
    }

    public List<DBObject> getByHubId(final String userId, final String hubId, final String[] fieldNames) {
        final DBObject user = UserService.getEnabled(userId);
        if (null != user) {
            final DBObject query = MongoUtils.queryEquals(Contact.HUB_ID, hubId);
            return super.find(query, fieldNames, new String[] { Contact.REALNAME }, null);
        }
        return new ArrayList<DBObject>();
    }

    public DBObject collaborate(final boolean add, final String hubId, final String contactId) {
        try {
            if (StringUtils.hasText(hubId) && StringUtils.hasText(contactId)) {
                final ContactService contactSrvc = new ContactService();
                final HubService hubSrvc = new HubService();
                final UserService userSrvc = new UserService();
                final DBObject contact = contactSrvc.findById(contactId);
                final String accountId = Contact.getAccountId(contact);
                if (StringUtils.hasText(accountId)) {
                    final DBObject hub = hubSrvc.findById(hubId);
                    final DBObject user = userSrvc.findById(accountId);
                    if (null != contact && null != hub && null != user) {
                        if (add) {
                            // add
                            Hub.addCollaborator(hub, accountId);
                            Contact.addCollaboration(contact, hubId);
                            User.addCollaboration(user, hubId);
                        } else {
                            // remove
                            Hub.removeCollaborator(hub, accountId);
                            Contact.removeCollaboration(contact, hubId);
                            User.removeCollaboration(user, hubId);
                        }
                        super.upsert(contact);
                        hubSrvc.upsert(hub);
                        userSrvc.upsert(user);

                        return contact;
                    }
                }
            }
        } catch (final Throwable t) {
            super.getLogger().log(Level.SEVERE, null, t);
        }
        // contact cannot be added as collaborator
        return null;
    }
    // --------------------------------------------------------------------
    //               p r i v a t e
    // --------------------------------------------------------------------

    private List<DBObject> getAllByUserId(final String userId) {
        final DBObject query = MongoUtils.queryEquals(Contact.ACCOUNT_ID, userId);
        return super.find(query, null, 0, 0, new String[] { Contact.NAME }, null);
    }

    private int countAllByUserId(final String userId) {
        final DBObject query = MongoUtils.queryEquals(Contact.ACCOUNT_ID, userId);
        return super.count(query);
    }

    private int countAllByHubId(final String hubId) {
        final DBObject query = MongoUtils.queryEquals(Contact.HUB_ID, hubId);
        return super.count(query);
    }

    private int countAllByHubIdAndKeywords(final String hubId, final Collection<String> keywords) {
        final DBObject query = new BasicDBObject();
        query.put(Contact.HUB_ID, hubId);
        MongoUtils.queryIn(query, Contact.PARALLEL_ARRAY_KEY, keywords.toArray(new String[keywords.size()]));

        return super.count(query);
    }

    private DBObject createFromUser(final DBObject hub, final String userId) throws StandardCodedException {
        final String hubId = Hub.getId(hub);

        final DBObject query = new BasicDBObject();
        query.put(Contact.ACCOUNT_ID, userId);
        query.put(Contact.HUB_ID, hubId);

        DBObject result = super.findOne(query);
        if (null == result) {
            final DBObject user = UserService.getEnabled(userId);
            if (null != hub && null != user) {
                final String ownerId = Hub.getUserId(hub);

                result = new Contact(); // already contains id

                Contact.setOwnerId(result, ownerId);
                Contact.setAccountId(result, userId);
                Contact.setLang(result, User.getLang(user));
                Contact.setHubId(result, hubId);
                Contact.setEmail(result, User.getEmail(user));
                Contact.setEmails(result, User.getEmails(user));
                final String brand = ItemBillingUser.getBrand(User.getBilling(user));
                final String name = User.getName(user);
                final String surname = User.getSurname(user);
                final String realname = User.getRealname(user);
                if (StringUtils.hasText(name) && StringUtils.hasText(surname)) {
                    Contact.setName(result, name.concat(" ").concat(surname));
                    if (StringUtils.hasText(brand)) {
                        Contact.setSurname(result, "(".concat(brand).concat(")"));
                    } else {
                        Contact.setSurname(result, "(".concat(User.getEmail(user)).concat(")"));
                    }
                } else if (StringUtils.hasText(realname)) {
                    Contact.setName(result, realname);
                    if (StringUtils.hasText(brand)) {
                        Contact.setSurname(result, "(".concat(brand).concat(")"));
                    } else {
                        Contact.setSurname(result, "(".concat(User.getEmail(user)).concat(")"));
                    }
                } else {
                    Contact.setName(result, User.getEmail(user));
                    Contact.setSurname(result, "");
                }

                // Contact.regenerateParallelArrayKey(result); generated in upsert

                this.upsert(result);
            }
        }

        return result;
    }

    // --------------------------------------------------------------------
    //               S T A T I C
    // --------------------------------------------------------------------

    public static DBObject get(final String id) {
        try {
            final ContactService srvc = new ContactService();
            return srvc.findById(id);
        } catch (final Throwable ignored) {
        }
        return null;
    }

    public static DBObject get(final String id, final String[] fieldNames) {
        try {
            final ContactService srvc = new ContactService();
            return srvc.findById(id, fieldNames);
        } catch (final Throwable ignored) {
        }
        return null;
    }

    public static String getAccountId(final String id) {
        try {
            final ContactService srvc = new ContactService();
            final DBObject contact = srvc.findById(id, new String[] { Contact.ACCOUNT_ID });
            return Contact.getAccountId(contact);
        } catch (final Throwable ignored) {
        }
        return "";
    }

    /**
     * Returns a Set of Contact's IDs.
     * An account (user) can be registered as contact from different users.
     *
     * @param accountId Id of User
     * @return Set of Contact's IDs
     */
    public static Set<String> getContactIdsFromUserId(final String accountId) {
        final Set<String> result = new HashSet<String>();
        try {
            final ContactService srvc = new ContactService();
            final DBObject query = new BasicDBObject();
            final Pattern equal = MongoUtils.patternEquals(accountId); //Pattern.compile("\\A" + email + "\\z", BeeMongoUtils.CASE_INSENSITIVE);
            query.put(Contact.ACCOUNT_ID, equal);
            final List<DBObject> contacts = srvc.find(query, new String[] { Contact.ID }, null, null);
            for (final DBObject item : contacts) {
                final String id = Contact.getId(item);
                if (StringUtils.hasText(id)) {
                    result.add(id);
                }
            }
        } catch (Throwable ignored) {
            // something wrong in database
        }
        return result;
    }

    public static String getUserIdFromContactId(final String contactId) {
        final Set<String> result = new HashSet<String>();
        try {
            final DBObject contact = get(contactId, new String[] { Contact.ACCOUNT_ID });
            if (null != contact) {
                return Contact.getAccountId(contact);
            }
        } catch (Throwable ignored) {
            // something wrong in database
        }
        return null;
    }

    public static Set<String> getUserIdsFromContactIds(final Collection<String> contactIds) {
        final Set<String> result = new HashSet<String>();
        try {
            final List<DBObject> contacts = getContactsFromIds(contactIds, new String[] { Contact.ACCOUNT_ID });
            for (final DBObject contact : contacts) {
                result.add(Contact.getAccountId(contact));
            }
        } catch (Throwable ignored) {
            // something wrong in database
        }
        return result;
    }

    public static List<DBObject> getContactsFromIds(final Collection<String> ids, final String[] fieldNames) {
        if (null != ids) {
            return getContactsFromIds(ids.toArray(new String[ids.size()]), fieldNames);
        }
        return new ArrayList<DBObject>();
    }

    public static List<DBObject> getContactsFromIds(final String[] ids, final String[] fieldNames) {
        try {
            final DBObject query = MongoUtils.queryIn(Contact.ID, ids);
            final ContactService srvc = new ContactService();
            return srvc.find(query, fieldNames, new String[] { Contact.REALNAME }, null);
        } catch (final Throwable ignored) {
        }
        return new ArrayList<DBObject>();
    }

    public static List<DBObject> removeByHubId(final String userId, final String hubId) throws Exception {
        final List<DBObject> result = new LinkedList<DBObject>();
        final ContactService srvc = new ContactService();
        final DBObject query = new BasicDBObject(Contact.HUB_ID, hubId);
        final List<DBObject> resources = srvc.find(query);
        for (final DBObject resource : resources) {
            result.addAll(remove(userId, resource));
        }
        return result;
    }

    public static List<DBObject> remove(final String userId, final String id) throws Exception {
        final DBObject resource = get(id);
        return remove(userId, resource);
    }

    public static List<DBObject> remove(final String userId, final DBObject item) throws Exception {
        final List<DBObject> result = new LinkedList<DBObject>();
        if (null != item) {
            final ContactService srvc = new ContactService();
            final String id = Contact.getId(item);
            srvc.removeById(id);
            result.add(item);
        }
        return result;
    }

    /**
     * Add user at Hub home of some recipients if they have an account.
     *
     * @param user_id    User to add as contact
     * @param recipients List of recipients
     */
    public static void addUserContactToRecipientsAccount(final String user_id, final List<String> recipients) {
        try {
            final ContactService srvc = new ContactService();
            for (final String user_or_contact : recipients) {
                final String account_id = Contact.is(user_or_contact) ? getAccountId(user_or_contact)
                        : user_or_contact;// already a user account id
                final DBObject hub_home = HubService.getHome(account_id);
                if (null != hub_home) {
                    srvc.createFromUser(hub_home, user_id);
                }
            }
        } catch (Throwable ignored) {
        }
    }

    public static void addUserContactToRecipientAccount(final String user_id, final String recipient_id) {
        final String account_id = ContactService.getUserIdFromContactId(recipient_id);
        addUserContactToAccount(user_id, account_id);
    }

    public static void addUserContactToAccount(final String user_id, final String account_id) {
        try {
            if (StringUtils.hasText(account_id)) {
                final ContactService srvc = new ContactService();
                final DBObject hub_home = HubService.getHome(account_id);
                if (null != hub_home) {
                    srvc.createFromUser(hub_home, user_id);
                }
            }
        } catch (Throwable ignored) {
        }
    }

    public static int countByHub(final String hubId) {
        try {
            if (StringUtils.hasText(hubId)) {
                final ContactService srvc = new ContactService();
                return srvc.countAllByHubId(hubId);
            }
        } catch (Throwable ignored) {
        }
        return 0;
    }

}