001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.social.service.impl;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.model.User;
020    import com.liferay.portlet.social.RelationUserIdException;
021    import com.liferay.portlet.social.model.SocialRelation;
022    import com.liferay.portlet.social.model.SocialRelationConstants;
023    import com.liferay.portlet.social.service.base.SocialRelationLocalServiceBaseImpl;
024    
025    import java.util.List;
026    
027    /**
028     * The social relation local service. This service provides methods to handle
029     * unidirectional or bidirectional relations between users.
030     *
031     * <p>
032     * Relations between users can be unidirectional or bidirectional. The type of
033     * relation is determined by an integer constant. Some example relations are
034     * <i>co-worker, friend, romantic partner, sibling, spouse, child, enemy,
035     * follower, parent, subordinate, supervisor</i>.
036     * </p>
037     *
038     * <p>
039     * The two users participating in the relation are designated as User1 and
040     * User2. In case of unidirectional relations User1 should always be the
041     * subject of the relation. You can use the following English sentence to find
042     * out which user to use as User1 and which to use as User2:
043     * </p>
044     *
045     * <p>
046     * User1 is <i>&lt;relation&gt;</i> of User2 (e.g. User1 is parent of User2;
047     * User1 is supervisor of User2)
048     * </p>
049     *
050     * <p>
051     * For bidirectional relations, the service automatically generates the inverse
052     * relation.
053     * </p>
054     *
055     * @author Brian Wing Shun Chan
056     */
057    public class SocialRelationLocalServiceImpl
058            extends SocialRelationLocalServiceBaseImpl {
059    
060            /**
061             * Adds a social relation between the two users to the database.
062             *
063             * @param  userId1 the user that is the subject of the relation
064             * @param  userId2 the user at the other end of the relation
065             * @param  type the type of the relation
066             * @return the social relation
067             * @throws PortalException if the users could not be found, if the users
068             *         were not from the same company, or if either of the users was
069             *         the default user
070             * @throws SystemException if a system exception occurred
071             */
072            public SocialRelation addRelation(long userId1, long userId2, int type)
073                    throws PortalException, SystemException {
074    
075                    if (userId1 == userId2) {
076                            throw new RelationUserIdException();
077                    }
078    
079                    User user1 = userPersistence.findByPrimaryKey(userId1);
080                    User user2 = userPersistence.findByPrimaryKey(userId2);
081    
082                    if (user1.getCompanyId() != user2.getCompanyId()) {
083                            throw new RelationUserIdException();
084                    }
085    
086                    SocialRelation relation = socialRelationPersistence.fetchByU1_U2_T(
087                            userId1, userId2, type);
088    
089                    if (relation == null) {
090                            long relationId = counterLocalService.increment();
091    
092                            relation = socialRelationPersistence.create(relationId);
093    
094                            relation.setCompanyId(user1.getCompanyId());
095                            relation.setCreateDate(System.currentTimeMillis());
096                            relation.setUserId1(userId1);
097                            relation.setUserId2(userId2);
098                            relation.setType(type);
099    
100                            socialRelationPersistence.update(relation, false);
101                    }
102    
103                    if (SocialRelationConstants.isTypeBi(type)) {
104                            SocialRelation biRelation =
105                                    socialRelationPersistence.fetchByU1_U2_T(
106                                            userId2, userId1, type);
107    
108                            if (biRelation == null) {
109                                    long biRelationId = counterLocalService.increment();
110    
111                                    biRelation = socialRelationPersistence.create(biRelationId);
112    
113                                    biRelation.setCompanyId(user1.getCompanyId());
114                                    biRelation.setCreateDate(System.currentTimeMillis());
115                                    biRelation.setUserId1(userId2);
116                                    biRelation.setUserId2(userId1);
117                                    biRelation.setType(type);
118    
119                                    socialRelationPersistence.update(biRelation, false);
120                            }
121                    }
122    
123                    return relation;
124            }
125    
126            /**
127             * Removes the relation (and its inverse in case of a bidirectional
128             * relation) from the database.
129             *
130             * @param  relationId the primary key of the relation
131             * @throws PortalException if the relation could not be found
132             * @throws SystemException if a system exception occurred
133             */
134            public void deleteRelation(long relationId)
135                    throws PortalException, SystemException {
136    
137                    SocialRelation relation = socialRelationPersistence.findByPrimaryKey(
138                            relationId);
139    
140                    deleteRelation(relation);
141            }
142    
143            /**
144             * Removes the matching relation (and its inverse in case of a
145             * bidirectional relation) from the database.
146             *
147             * @param  userId1 the user that is the subject of the relation
148             * @param  userId2 the user at the other end of the relation
149             * @param  type the relation's type
150             * @throws PortalException if the relation or its inverse relation (if
151             *         applicable) could not be found
152             * @throws SystemException if a system exception occurred
153             */
154            public void deleteRelation(long userId1, long userId2, int type)
155                    throws PortalException, SystemException {
156    
157                    SocialRelation relation = socialRelationPersistence.findByU1_U2_T(
158                            userId1, userId2, type);
159    
160                    deleteRelation(relation);
161            }
162    
163            /**
164             * Removes the relation (and its inverse in case of a bidirectional
165             * relation) from the database.
166             *
167             * @param  relation the relation to be removed
168             * @throws PortalException if the relation is bidirectional and its inverse
169             *         relation could not be found
170             * @throws SystemException if a system exception occurred
171             */
172            public void deleteRelation(SocialRelation relation)
173                    throws PortalException, SystemException {
174    
175                    socialRelationPersistence.remove(relation);
176    
177                    if (SocialRelationConstants.isTypeBi(relation.getType())) {
178                            SocialRelation biRelation = socialRelationPersistence.findByU1_U2_T(
179                                    relation.getUserId2(), relation.getUserId1(),
180                                    relation.getType());
181    
182                            socialRelationPersistence.remove(biRelation);
183                    }
184            }
185    
186            /**
187             * Removes all relations involving the user from the database.
188             *
189             * @param  userId the primary key of the user
190             * @throws SystemException if a system exception occurred
191             */
192            public void deleteRelations(long userId) throws SystemException {
193                    socialRelationPersistence.removeByUserId1(userId);
194                    socialRelationPersistence.removeByUserId2(userId);
195            }
196    
197            /**
198             * Removes all relations between User1 and User2.
199             *
200             * @param  userId1 the user that is the subject of the relation
201             * @param  userId2 the user at the other end of the relation
202             * @throws PortalException if the inverse relation could not be found
203             * @throws SystemException if a system exception occurred
204             */
205            public void deleteRelations(long userId1, long userId2)
206                    throws PortalException, SystemException {
207    
208                    List<SocialRelation> relations = socialRelationPersistence.findByU1_U2(
209                            userId1, userId2);
210    
211                    for (SocialRelation relation : relations) {
212                            deleteRelation(relation);
213                    }
214            }
215    
216            /**
217             * Returns a range of all the inverse relations of the given type for which
218             * the user is User2 of the relation.
219             *
220             * <p>
221             * Useful when paginating results. Returns a maximum of <code>end -
222             * start</code> instances. <code>start</code> and <code>end</code> are not
223             * primary keys, they are indexes in the result set. Thus, <code>0</code>
224             * refers to the first result in the set. Setting both <code>start</code>
225             * and <code>end</code> to {@link
226             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the
227             * full result set.
228             * </p>
229             *
230             * @param  userId the primary key of the user
231             * @param  type the relation's type
232             * @param  start the lower bound of the range of results
233             * @param  end the upper bound of the range of results (not inclusive)
234             * @return the range of matching relations
235             * @throws SystemException if a system exception occurred
236             */
237            public List<SocialRelation> getInverseRelations(
238                            long userId, int type, int start, int end)
239                    throws SystemException {
240    
241                    return socialRelationPersistence.findByU2_T(userId, type, start, end);
242            }
243    
244            /**
245             * Returns the number of inverse relations of the given type for which the
246             * user is User2 of the relation.
247             *
248             * @param  userId the primary key of the user
249             * @param  type the relation's type
250             * @return the number of matching relations
251             * @throws SystemException if a system exception occurred
252             */
253            public int getInverseRelationsCount(long userId, int type)
254                    throws SystemException {
255    
256                    return socialRelationPersistence.countByU2_T(userId, type);
257            }
258    
259            /**
260             * Returns the relation identified by its primary key.
261             *
262             * @param  relationId the primary key of the relation
263             * @return Returns the relation
264             * @throws PortalException if the relation could not be found
265             * @throws SystemException if a system exception occurred
266             */
267            public SocialRelation getRelation(long relationId)
268                    throws PortalException, SystemException {
269    
270                    return socialRelationPersistence.findByPrimaryKey(relationId);
271            }
272    
273            /**
274             * Returns the relation of the given type between User1 and User2.
275             *
276             * @param  userId1 the user that is the subject of the relation
277             * @param  userId2 the user at the other end of the relation
278             * @param  type the relation's type
279             * @return Returns the relation
280             * @throws PortalException if the relation could not be found
281             * @throws SystemException if a system exception occurred
282             */
283            public SocialRelation getRelation(long userId1, long userId2, int type)
284                    throws PortalException, SystemException {
285    
286                    return socialRelationPersistence.findByU1_U2_T(
287                            userId1, userId2, type);
288            }
289    
290            /**
291             * Returns a range of all the relations of the given type where the user is
292             * the subject of the relation.
293             *
294             * <p>
295             * Useful when paginating results. Returns a maximum of <code>end -
296             * start</code> instances. <code>start</code> and <code>end</code> are not
297             * primary keys, they are indexes in the result set. Thus, <code>0</code>
298             * refers to the first result in the set. Setting both <code>start</code>
299             * and <code>end</code> to {@link
300             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the
301             * full result set.
302             * </p>
303             *
304             * @param  userId the primary key of the user
305             * @param  type the relation's type
306             * @param  start the lower bound of the range of results
307             * @param  end the upper bound of the range of results (not inclusive)
308             * @return the range of relations
309             * @throws SystemException if a system exception occurred
310             */
311            public List<SocialRelation> getRelations(
312                            long userId, int type, int start, int end)
313                    throws SystemException {
314    
315                    return socialRelationPersistence.findByU1_T(userId, type, start, end);
316            }
317    
318            /**
319             * Returns a range of all the relations between User1 and User2.
320             *
321             * <p>
322             * Useful when paginating results. Returns a maximum of <code>end -
323             * start</code> instances. <code>start</code> and <code>end</code> are not
324             * primary keys, they are indexes in the result set. Thus, <code>0</code>
325             * refers to the first result in the set. Setting both <code>start</code>
326             * and <code>end</code> to {@link
327             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the
328             * full result set.
329             * </p>
330             *
331             * @param  userId1 the user that is the subject of the relation
332             * @param  userId2 the user at the other end of the relation
333             * @param  start the lower bound of the range of results
334             * @param  end the upper bound of the range of results (not inclusive)
335             * @return the range of relations
336             * @throws SystemException if a system exception occurred
337             */
338            public List<SocialRelation> getRelations(
339                            long userId1, long userId2, int start, int end)
340                    throws SystemException {
341    
342                    return socialRelationPersistence.findByU1_U2(
343                            userId1, userId2, start, end);
344            }
345    
346            /**
347             * Returns the number of relations of the given type where the user is the
348             * subject of the relation.
349             *
350             * @param  userId the primary key of the user
351             * @param  type the relation's type
352             * @return the number of relations
353             * @throws SystemException if a system exception occurred
354             */
355            public int getRelationsCount(long userId, int type) throws SystemException {
356                    return socialRelationPersistence.countByU1_T(userId, type);
357            }
358    
359            /**
360             * Returns the number of relations between User1 and User2.
361             *
362             * @param  userId1 the user that is the subject of the relation
363             * @param  userId2 the user at the other end of the relation
364             * @return the number of relations
365             * @throws SystemException if a system exception occurred
366             */
367            public int getRelationsCount(long userId1, long userId2)
368                    throws SystemException {
369    
370                    return socialRelationPersistence.countByU1_U2(userId1, userId2);
371            }
372    
373            /**
374             * Returns <code>true</code> if a relation of the given type exists where
375             * the user with primary key <code>userId1</code> is User1 of the relation
376             * and the user with the primary key <code>userId2</code> is User2 of the
377             * relation.
378             *
379             * @param  userId1 the user that is the subject of the relation
380             * @param  userId2 the user at the other end of the relation
381             * @param  type the relation's type
382             * @return <code>true</code> if the relation exists; <code>false</code>
383             *         otherwise
384             * @throws SystemException if a system exception occurred
385             */
386            public boolean hasRelation(long userId1, long userId2, int type)
387                    throws SystemException {
388    
389                    SocialRelation relation = socialRelationPersistence.fetchByU1_U2_T(
390                            userId1, userId2, type);
391    
392                    if (relation == null) {
393                            return false;
394                    }
395                    else {
396                            return true;
397                    }
398            }
399    
400            /**
401             * Returns <code>true</code> if the users can be in a relation of the given
402             * type where the user with primary key <code>userId1</code> is User1 of
403             * the relation and the user with the primary key <code>userId2</code> is
404             * User2 of the relation.
405             *
406             * <p>
407             * This method returns <code>false</code> if User1 and User2 are the same,
408             * if either user is the default user, or if a matching relation already
409             * exists.
410             * </p>
411             *
412             * @param  userId1 the user that is the subject of the relation
413             * @param  userId2 the user at the other end of the relation
414             * @param  type the relation's type
415             * @return <code>true</code> if the two users can be in a new relation of
416             *         the given type; <code>false</code> otherwise
417             * @throws SystemException if a system exception occurred
418             */
419            public boolean isRelatable(long userId1, long userId2, int type)
420                    throws SystemException {
421    
422                    if (userId1 == userId2) {
423                            return false;
424                    }
425    
426                    User user1 = userPersistence.fetchByPrimaryKey(userId1);
427    
428                    if ((user1 == null) || user1.isDefaultUser()) {
429                            return false;
430                    }
431    
432                    User user2 = userPersistence.fetchByPrimaryKey(userId2);
433    
434                    if ((user2 == null) || user2.isDefaultUser()) {
435                            return false;
436                    }
437    
438                    return !hasRelation(userId1, userId2, type);
439            }
440    
441    }