RelationshipManagerImpl.java
/*
* Copyright (C) 2003-2007 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero 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 org.exoplatform.social.core.manager;
import org.exoplatform.commons.utils.ListAccess;
import org.exoplatform.container.PortalContainer;
import org.exoplatform.social.core.identity.ConnectionFilterListAccess;
import org.exoplatform.social.core.identity.ConnectionListAccess;
import org.exoplatform.social.core.identity.model.Identity;
import org.exoplatform.social.core.profile.ProfileFilter;
import org.exoplatform.social.core.relationship.RelationshipLifeCycle;
import org.exoplatform.social.core.relationship.RelationshipListener;
import org.exoplatform.social.core.relationship.RelationshipListenerPlugin;
import org.exoplatform.social.core.relationship.model.Relationship;
import org.exoplatform.social.core.relationship.model.Relationship.Type;
import org.exoplatform.social.core.storage.api.IdentityStorage;
import org.exoplatform.social.core.storage.api.RelationshipStorage;
import org.exoplatform.social.core.storage.RelationshipStorageException;
import java.util.*;
/**
* The Class RelationshipManager implements RelationshipManager without caching.
*
* @since Nov 24, 2010
* @version 1.2.0-GA
*/
public class RelationshipManagerImpl implements RelationshipManager {
/** The activityStorage. */
protected RelationshipStorage storage;
protected IdentityStorage identityStorage;
/**
* lifecycle of a relationship.
*/
protected RelationshipLifeCycle lifeCycle = new RelationshipLifeCycle();
private IdentityManager identityManager;
/**
* The default offset when get list identities with connection list access.
*
* @since 1.2.0-Beta3
*/
protected static final int OFFSET = 0;
/**
* The default limit when get list identities with connection list access.
*
* @since 1.2.0-Beta3
*/
protected static final int LIMIT = 200;
/**
* Instantiates a new relationship manager.
*
* @param relationshipStorage
*/
public RelationshipManagerImpl(IdentityStorage identityStorage, RelationshipStorage relationshipStorage) {
this.storage = relationshipStorage;
this.identityStorage = identityStorage;
}
/**
* {@inheritDoc}
*/
public Relationship get(String relationshipId) {
Relationship relationship = null;
try {
relationship = storage.getRelationship(relationshipId);
} catch (Exception e) {
return null;
}
return relationship;
}
/**
* {@inheritDoc}
*/
public Relationship invite(Identity sender, Identity receiver) throws RelationshipStorageException {
return this.inviteToConnect(sender, receiver);
}
/**
* {@inheritDoc}
*/
public void save(Relationship relationship) throws RelationshipStorageException {
this.update(relationship);
}
/**
* {@inheritDoc}
*/
public void confirm(Relationship relationship) throws RelationshipStorageException {
this.confirm(relationship.getReceiver(), relationship.getSender());
}
/**
* {@inheritDoc}
*/
public void deny(Relationship relationship) throws RelationshipStorageException {
this.deny(relationship.getReceiver(), relationship.getSender());
}
/**
* {@inheritDoc}
*/
public void remove(Relationship relationship) throws RelationshipStorageException {
this.delete(relationship);
}
/**
* {@inheritDoc}
*/
public void ignore(Relationship relationship) throws RelationshipStorageException {
this.ignore(relationship.getSender(), relationship.getReceiver());
}
/**
* {@inheritDoc}
*/
public List<Relationship> getPending(Identity sender) throws RelationshipStorageException {
return getSender(sender, Relationship.Type.PENDING, null);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getPending(Identity sender, List<Identity> identities) throws RelationshipStorageException {
return getSender(sender, Relationship.Type.PENDING, identities);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getIncoming(Identity receiver) throws RelationshipStorageException {
return getReceiver(receiver, Relationship.Type.PENDING, null);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getIncoming(Identity receiver, List<Identity> identities) throws RelationshipStorageException {
return getReceiver(receiver, Relationship.Type.PENDING, identities);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getConfirmed(Identity identity) throws RelationshipStorageException {
return getRelationships(identity, Relationship.Type.CONFIRMED, null);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getConfirmed(Identity identity, List<Identity> identities) throws RelationshipStorageException {
return getRelationships(identity, Relationship.Type.CONFIRMED, identities);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getAll(Identity identity) throws RelationshipStorageException {
return getRelationships(identity, null, null);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getAll(Identity identity, List<Identity> identities) throws RelationshipStorageException {
return getRelationships(identity, null, identities);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getAll(Identity identity, Relationship.Type type,
List<Identity> identities) throws RelationshipStorageException {
return getRelationships(identity, type, identities);
}
/**
* {@inheritDoc}
*/
public Relationship get(Identity identity1, Identity identity2) throws RelationshipStorageException {
return storage.getRelationship(identity1, identity2);
}
/**
* {@inheritDoc}
*/
public Relationship.Type getStatus(Identity identity1, Identity identity2) throws RelationshipStorageException {
Relationship relationship = get(identity1, identity2);
return relationship == null ? null : relationship.getStatus();
}
/**
* Registers a RelationshipLister.
*
* @param listener
*/
public void registerListener(RelationshipListener listener) {
lifeCycle.addListener(listener);
}
/**
* Unregisters a RelationshipLister.
*
* @param listener
*/
public void unregisterListener(RelationshipListener listener) {
lifeCycle.removeListener(listener);
}
/**
* Adds a RelationshipListenerPlugin.
*
* @param plugin
*/
public void addListenerPlugin(RelationshipListenerPlugin plugin) {
registerListener(plugin);
}
/**
* Gets the relationship activityStorage.
*
* @return storage
*/
protected RelationshipStorage getStorage() {
return storage;
}
/**
* Sets the relationship activityStorage.
*
* @param storage
*/
protected void setStorage(RelationshipStorage storage) {
this.storage = storage;
}
/**
* Gets the relationship life cycle.
*
* @return lifeCycle
*/
protected RelationshipLifeCycle getLifeCycle() {
return lifeCycle;
}
/**
* Sets thre relationship life cycle.
*
* @param lifeCycle
*/
protected void setLifeCycle(RelationshipLifeCycle lifeCycle) {
this.lifeCycle = lifeCycle;
}
/**
* Get relationships by identity and status from cache or activityStorage
*
* @param identity
* @param identities
* @return list of relationship
* @throws RelationshipStorageException
*/
protected List<Relationship> getRelationships(Identity identity, Relationship.Type type,
List<Identity> identities) throws RelationshipStorageException {
return storage.getRelationships(identity, type, identities);
}
/**
* Get relationships by identity and status and identities from activityStorage
*
* @param sender
* @return list of relationship
* @throws RelationshipStorageException
*/
protected List<Relationship> getSender(Identity sender, Relationship.Type type,
List<Identity> identities) throws RelationshipStorageException {
return storage.getSenderRelationships(sender, type, identities);
}
/**
* Get relationships by identity and status from cache or activityStorage
*
* @param receiver
* @param identities
* @return list of relationship
* @throws RelationshipStorageException
*/
protected List<Relationship> getReceiver(Identity receiver, Relationship.Type type,
List<Identity> identities) throws RelationshipStorageException {
return storage.getReceiverRelationships(receiver, type, identities);
}
/**
* {@inheritDoc}
*/
public Relationship create(Identity sender, Identity receiver) {
return new Relationship(sender, receiver);
}
/**
* {@inheritDoc}
*/
public List<Identity> findRelationships(Identity ownerIdentity, Type relationshipType) throws RelationshipStorageException {
List<Relationship> allRelationships = getAll(ownerIdentity, relationshipType, null);
List<Identity> identities = new ArrayList<Identity>();
if (allRelationships == null || allRelationships.size() == 0) {
return identities;
}
for(Relationship relationship : allRelationships) {
identities.add(relationship.getPartner(ownerIdentity));
}
return identities;
}
/**
* {@inheritDoc}
*/
public List<Relationship> findRoute(Identity sender, Identity receiver) throws RelationshipStorageException {
List<Relationship> route = new ArrayList<Relationship>();
route.add(get(sender,receiver));
return route;
}
/**
* {@inheritDoc}
*/
public Type getConnectionStatus(Identity fromIdentity, Identity toIdentity) throws Exception {
return getStatus(fromIdentity, toIdentity);
}
/**
* {@inheritDoc}
*/
public ListAccess<Identity> getConnections(Identity identity) {
return (new ConnectionListAccess(storage, identity, ConnectionListAccess.Type.CONNECTION));
}
/**
* {@inheritDoc}
*/
public List<Relationship> getContacts(Identity currIdentity, List<Identity> identities) throws RelationshipStorageException {
return getAll(currIdentity, Type.CONFIRMED, identities);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getContacts(Identity identity) throws RelationshipStorageException {
return getAll(identity, Type.CONFIRMED, null);
}
/**
* {@inheritDoc}
*/
public List<Identity> getIdentities(Identity id) throws Exception {
return Arrays.asList(this.getConnections(id).load(OFFSET, LIMIT));
}
/**
* {@inheritDoc}
*/
public List<Relationship> getPendingRelationships(Identity identity) throws RelationshipStorageException {
return getPending(identity);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getPendingRelationships(Identity identity, boolean toConfirm) throws RelationshipStorageException {
return getAll(identity, Type.PENDING, null);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getPendingRelationships(Identity currIdentity, List<Identity> identities,
boolean toConfirm) throws RelationshipStorageException {
return getAll(currIdentity, Type.PENDING, identities);
}
/**
* {@inheritDoc}
*/
public Relationship getRelationship(Identity sender, Identity receiver) throws RelationshipStorageException {
return get(sender, receiver);
}
/**
* {@inheritDoc}
*/
public Relationship getRelationshipById(String id) throws RelationshipStorageException {
return get(id);
}
/**
* {@inheritDoc}
*/
public Type getRelationshipStatus(Relationship rel, Identity id) {
return rel.getStatus();
}
/**
* {@inheritDoc}
*/
public List<Relationship> getRelationshipsByIdentityId(String id) throws RelationshipStorageException {
return getAll(getIdentityManager().getIdentity(id));
}
private IdentityManager getIdentityManager() {
if (identityManager == null) {
identityManager = (IdentityManager) PortalContainer.getInstance().getComponentInstanceOfType(IdentityManager.class);
}
return identityManager;
}
/**
* {@inheritDoc}
*/
public void saveRelationship(Relationship relationship) throws RelationshipStorageException {
save(relationship);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getAllRelationships(Identity identity) throws RelationshipStorageException {
return getAll(identity);
}
/**
* {@inheritDoc}
*/
public void confirm(Identity invitedIdentity, Identity invitingIdentity) {
Relationship relationship = get(invitedIdentity, invitingIdentity);
if (relationship != null && relationship.getStatus() == Relationship.Type.PENDING) {
relationship.setStatus(Relationship.Type.CONFIRMED);
this.update(relationship);
lifeCycle.relationshipConfirmed(this, relationship);
}
}
/**
* {@inheritDoc}
*/
public void delete(Relationship existingRelationship) {
storage.removeRelationship(existingRelationship);
lifeCycle.relationshipRemoved(this, existingRelationship);
}
/**
* {@inheritDoc}
*/
public void deny(Identity invitedIdentity, Identity invitingIdentity) {
Relationship relationship = this.get(invitedIdentity, invitingIdentity);
if (relationship != null) {
// relationship.setStatus(Relationship.Type.IGNORED);
// save(relationship);
// TODO: now just remove, implement later
storage.removeRelationship(relationship);
lifeCycle.relationshipDenied(this, relationship);
}
}
/**
* {@inheritDoc}
*/
public ListAccess<Identity> getAllWithListAccess(Identity existingIdentity) {
return new ConnectionListAccess(this.storage, existingIdentity, ConnectionListAccess.Type.ALL);
}
/**
* {@inheritDoc}
*/
public ListAccess<Identity> getIncomingWithListAccess(Identity existingIdentity) {
return new ConnectionListAccess(this.storage, existingIdentity, ConnectionListAccess.Type.INCOMING);
}
/**
* {@inheritDoc}
*/
public ListAccess<Identity> getOutgoing(Identity existingIdentity) {
return new ConnectionListAccess(this.storage, existingIdentity, ConnectionListAccess.Type.OUTGOING);
}
/**
* {@inheritDoc}
*/
public void ignore(Identity sender, Identity receiver) {
Relationship relationship = this.get(sender, receiver);
if (relationship == null || !Type.IGNORED.equals(relationship.getStatus())) {
relationship = new Relationship(sender, receiver);
relationship.setStatus(Type.IGNORED);
save(relationship);
lifeCycle.relationshipIgnored(this, relationship);
}
}
/**
* {@inheritDoc}
*/
public Relationship inviteToConnect(Identity invitingIdentity, Identity invitedIdentity) {
Relationship relationship = get(invitingIdentity, invitedIdentity);
if (relationship == null || Type.IGNORED.equals(relationship.getStatus())) {
relationship = new Relationship(invitingIdentity, invitedIdentity);
relationship.setStatus(Type.PENDING);
this.update(relationship);
lifeCycle.relationshipRequested(this, relationship);
}
return relationship;
}
/**
* {@inheritDoc}
*/
public void update(Relationship existingRelationship) {
String senderId = existingRelationship.getSender().getId();
String receiverId = existingRelationship.getReceiver().getId();
if (senderId.equals(receiverId)) {
throw new RelationshipStorageException(RelationshipStorageException.Type.FAILED_TO_SAVE_RELATIONSHIP,
"the two identity are the same");
}
storage.saveRelationship(existingRelationship);
}
public ListAccess<Identity> getConnectionsByFilter(Identity existingIdentity, ProfileFilter profileFilter) {
return new ConnectionFilterListAccess(identityStorage, this.storage, existingIdentity, profileFilter,
ConnectionFilterListAccess.Type.PROFILE_FILTER_CONNECTION);
}
public ListAccess<Identity> getIncomingByFilter(Identity existingIdentity, ProfileFilter profileFilter) {
return new ConnectionFilterListAccess(identityStorage, this.storage, existingIdentity, profileFilter,
ConnectionFilterListAccess.Type.PROFILE_FILTER_INCOMMING);
}
public ListAccess<Identity> getOutgoingByFilter(Identity existingIdentity, ProfileFilter profileFilter) {
return new ConnectionFilterListAccess(identityStorage, this.storage, existingIdentity, profileFilter,
ConnectionFilterListAccess.Type.PROFILE_FILTER_OUTGOING);
}
public Map<Identity, Integer> getSuggestions(Identity identity, int maxConnections,
int maxConnectionsToLoad, int maxSuggestions) {
return storage.getSuggestions(identity, maxConnections, maxConnectionsToLoad,
maxSuggestions);
}
public Map<Identity, Integer> getSuggestions(Identity identity, int offset, int limit) {
Map<Identity, Integer> result = storage.getSuggestions(identity, -1, -1, offset + limit);
if (result != null && !result.isEmpty()) {
if (offset > 0) {
result = new LinkedHashMap<Identity, Integer>(result);
int o = 0;
for (Iterator<Map.Entry<Identity, Integer>> it = result.entrySet().iterator(); it.hasNext() && o < offset; o++) {
it.next();
it.remove();
}
}
if (result.size() > limit) {
result = new LinkedHashMap<Identity, Integer>(result);
int i = 0;
for (Iterator<Map.Entry<Identity, Integer>> it = result.entrySet().iterator(); it.hasNext(); i++) {
it.next();
if (i >= limit)
it.remove();
}
}
}
return result;
}
@Override
public List<Identity> getLastConnections(Identity identity, int limit) {
return storage.getLastConnections(identity, limit);
}
/**
* {@inheritDoc}
*/
public List<Relationship> getRelationshipsByStatus(Identity identity, Relationship.Type type, int offset, int limit) {
return storage.getRelationshipsByStatus(identity, type, offset, limit);
}
/**
* {@inheritDoc}
*/
public int getRelationshipsCountByStatus(Identity identity, Relationship.Type type) {
return storage.getRelationshipsCountByStatus(identity, type);
}
}