/* * Copyright 2012 Nodeable Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.streamreduce.core.dao; import com.google.code.morphia.AdvancedDatastore; import com.google.code.morphia.query.Criteria; import com.google.code.morphia.query.Query; import com.streamreduce.Constants; import com.streamreduce.core.model.Account; import com.streamreduce.core.model.SobaObject; import com.streamreduce.core.model.User; import com.streamreduce.core.model.messages.MessageComment; import com.streamreduce.core.model.messages.MessageType; import com.streamreduce.core.model.messages.SobaMessage; import com.streamreduce.util.ConnectionUtils; import com.streamreduce.util.MessageUtils; import org.apache.commons.lang.StringUtils; import org.bson.types.ObjectId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Repository; import java.util.ArrayList; import java.util.Date; import java.util.List; @Repository("sobaMessageDAO") public class SobaMessageDAO extends ValidatingDAO<SobaMessage> { protected transient Logger logger = LoggerFactory.getLogger(getClass()); @Autowired protected SobaMessageDAO(@Qualifier(value = "messageDBDatastore") AdvancedDatastore datastore) { super(datastore); } /* * Get all messages for an account */ public List<SobaMessage> getMessagesFromInbox(User user, Long after, Long before, int limit, boolean ascending, String search, List<String> hashtags, String sender, boolean excludeNodebellies) { Query<SobaMessage> query = ((AdvancedDatastore) getDatastore()).find(MessageUtils.getInboxPath(user), entityClazz); query.and( query.or( query.and( // self and you are that person query.criteria("ownerId").hasThisOne(user.getId()), query.criteria("visibility").equal(SobaObject.Visibility.SELF) ) , query.and( // you always get these, these also include User sent messages as they are account scoped now query.criteria("visibility").equal(SobaObject.Visibility.ACCOUNT) ) , query.and( // this is your copy of a public message query.criteria("visibility").equal(SobaObject.Visibility.PUBLIC) ))); if (!StringUtils.isBlank(search)) { query.and( query.or( query.criteria("senderName").containsIgnoreCase(search), query.criteria("transformedMessage").containsIgnoreCase(search), query.criteria("comments").hasThisElement(new MessageComment(search)) ) ); } //OR filter over hashtag and sender fields List<Criteria> hashTagAndSenderCriteria = new ArrayList<>(); if (hashtags != null && hashtags.contains("#conversation")) { hashTagAndSenderCriteria.add(query.criteria("hashtags").hasAnyOf(hashtags)); } else if (hashtags != null && hashtags.size() > 0) { hashTagAndSenderCriteria.add(query.criteria("hashtags").hasAllOf(hashtags)); } if (sender != null) { try { ObjectId senderId = new ObjectId(sender); hashTagAndSenderCriteria.add( query.or( query.criteria("senderId").equal(senderId), query.criteria("senderName").equal(sender) )); } catch (IllegalArgumentException e) { // only look at senderName if sender can't be parsed into an ObjectId hashTagAndSenderCriteria.add(query.criteria("senderName").equal(sender)); } } if (!hashTagAndSenderCriteria.isEmpty()) { query.or(hashTagAndSenderCriteria.toArray(new Criteria[hashTagAndSenderCriteria.size()])); } if (after != null) { query.field("modified").greaterThan(after); } if (before != null) { query.field("modified").lessThan(before); } if (limit == 0) { limit = Constants.DEFAULT_MAX_MESSAGES; } if (limit > 0) { query.limit(limit); } if (excludeNodebellies) { query.criteria("type").notEqual(MessageType.NODEBELLY); } String order = "modified"; if (!ascending) { order = "-" + order; } query.order(order); return query.asList(); } public void saveToInbox(Account account, SobaMessage message) { logger.debug("[SOBA MESSAGE DAO] saving new message: " + message.getTransformedMessage()); ((AdvancedDatastore) getDatastore()).save(MessageUtils.getMessageInboxPath(account), message); } public void saveToInboxes(List<Account> accounts, SobaMessage message) { for (Account account : accounts) { // save if it hasn't been blacklisted (this should be for stream and insight messages if (!ConnectionUtils.isBlacklisted(account, message.getConnectionId())) { saveToInbox(account, message); } } } // TODD: limit by date? public List<SobaMessage> getPublicArchivedMessages() { Query<SobaMessage> query = ds.find(entityClazz); query.criteria("visibility").equal(SobaObject.Visibility.PUBLIC); query.criteria("created").greaterThan(new Date().getTime() - Constants.BOOTSTRAP_MESSAGE_ARCHIVE_DURATION); // Now() - 1 week return query.asList(); } public SobaMessage getFromInbox(Account account, ObjectId messageId) { return ((AdvancedDatastore) getDatastore()).get(MessageUtils.getMessageInboxPath(account), entityClazz, messageId); } // just for testing... i don't see a need for this really. // well, i guess we can always retract a sent messages with this method. public void deleteFromInbox(Account account, ObjectId messageId) { ((AdvancedDatastore) getDatastore()).delete(MessageUtils.getMessageInboxPath(account), messageId); } public void removeInbox(Account account) { getDatastore().delete(MessageUtils.getMessageInboxPath(account)); } public void removeMessagesFromConnection(Account account, ObjectId connectionId) { // What is the syntax to do this with .delete()????? Query<SobaMessage> query = ((AdvancedDatastore) getDatastore()).find(MessageUtils.getMessageInboxPath(account), entityClazz); query.criteria("connectionId").equal(connectionId); List<SobaMessage> sobaMessages = query.asList(); for (SobaMessage sobaMessage : sobaMessages) { deleteFromInbox(account, sobaMessage.getId()); } } }