001 /** 002 * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved. 003 * 004 * This library is free software; you can redistribute it and/or modify it under 005 * the terms of the GNU Lesser General Public License as published by the Free 006 * Software Foundation; either version 2.1 of the License, or (at your option) 007 * any later version. 008 * 009 * This library is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 012 * details. 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 subject 041 * of the relation. You can use the following English sentence to find out which 042 * user to use as User1 and which to use as User2: 043 * </p> 044 * 045 * <p> 046 * User1 is <i><relation></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 the 069 * 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 bidirectional 145 * 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 full 227 * 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(userId1, userId2, type); 287 } 288 289 /** 290 * Returns a range of all the relations of the given type where the user is 291 * the subject of the relation. 292 * 293 * <p> 294 * Useful when paginating results. Returns a maximum of <code>end - 295 * start</code> instances. <code>start</code> and <code>end</code> are not 296 * primary keys, they are indexes in the result set. Thus, <code>0</code> 297 * refers to the first result in the set. Setting both <code>start</code> 298 * and <code>end</code> to {@link 299 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 300 * result set. 301 * </p> 302 * 303 * @param userId the primary key of the user 304 * @param type the relation's type 305 * @param start the lower bound of the range of results 306 * @param end the upper bound of the range of results (not inclusive) 307 * @return the range of relations 308 * @throws SystemException if a system exception occurred 309 */ 310 public List<SocialRelation> getRelations( 311 long userId, int type, int start, int end) 312 throws SystemException { 313 314 return socialRelationPersistence.findByU1_T(userId, type, start, end); 315 } 316 317 /** 318 * Returns a range of all the relations between User1 and User2. 319 * 320 * <p> 321 * Useful when paginating results. Returns a maximum of <code>end - 322 * start</code> instances. <code>start</code> and <code>end</code> are not 323 * primary keys, they are indexes in the result set. Thus, <code>0</code> 324 * refers to the first result in the set. Setting both <code>start</code> 325 * and <code>end</code> to {@link 326 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 327 * result set. 328 * </p> 329 * 330 * @param userId1 the user that is the subject of the relation 331 * @param userId2 the user at the other end of the relation 332 * @param start the lower bound of the range of results 333 * @param end the upper bound of the range of results (not inclusive) 334 * @return the range of relations 335 * @throws SystemException if a system exception occurred 336 */ 337 public List<SocialRelation> getRelations( 338 long userId1, long userId2, int start, int end) 339 throws SystemException { 340 341 return socialRelationPersistence.findByU1_U2( 342 userId1, userId2, start, end); 343 } 344 345 /** 346 * Returns the number of relations of the given type where the user is the 347 * subject of the relation. 348 * 349 * @param userId the primary key of the user 350 * @param type the relation's type 351 * @return the number of relations 352 * @throws SystemException if a system exception occurred 353 */ 354 public int getRelationsCount(long userId, int type) throws SystemException { 355 return socialRelationPersistence.countByU1_T(userId, type); 356 } 357 358 /** 359 * Returns the number of relations between User1 and User2. 360 * 361 * @param userId1 the user that is the subject of the relation 362 * @param userId2 the user at the other end of the relation 363 * @return the number of relations 364 * @throws SystemException if a system exception occurred 365 */ 366 public int getRelationsCount(long userId1, long userId2) 367 throws SystemException { 368 369 return socialRelationPersistence.countByU1_U2(userId1, userId2); 370 } 371 372 /** 373 * Returns <code>true</code> if a relation of the given type exists where 374 * the user with primary key <code>userId1</code> is User1 of the relation 375 * and the user with the primary key <code>userId2</code> is User2 of the 376 * relation. 377 * 378 * @param userId1 the user that is the subject of the relation 379 * @param userId2 the user at the other end of the relation 380 * @param type the relation's type 381 * @return <code>true</code> if the relation exists; <code>false</code> 382 * otherwise 383 * @throws SystemException if a system exception occurred 384 */ 385 public boolean hasRelation(long userId1, long userId2, int type) 386 throws SystemException { 387 388 SocialRelation relation = socialRelationPersistence.fetchByU1_U2_T( 389 userId1, userId2, type); 390 391 if (relation == null) { 392 return false; 393 } 394 else { 395 return true; 396 } 397 } 398 399 /** 400 * Returns <code>true</code> if the users can be in a relation of the given 401 * type where the user with primary key <code>userId1</code> is User1 of the 402 * relation and the user with the primary key <code>userId2</code> is User2 403 * of the relation. 404 * 405 * <p> 406 * This method returns <code>false</code> if User1 and User2 are the same, 407 * if either user is the default user, or if a matching relation already 408 * exists. 409 * </p> 410 * 411 * @param userId1 the user that is the subject of the relation 412 * @param userId2 the user at the other end of the relation 413 * @param type the relation's type 414 * @return <code>true</code> if the two users can be in a new relation of 415 * the given type; <code>false</code> otherwise 416 * @throws SystemException if a system exception occurred 417 */ 418 public boolean isRelatable(long userId1, long userId2, int type) 419 throws SystemException { 420 421 if (userId1 == userId2) { 422 return false; 423 } 424 425 User user1 = userPersistence.fetchByPrimaryKey(userId1); 426 427 if ((user1 == null) || user1.isDefaultUser()) { 428 return false; 429 } 430 431 User user2 = userPersistence.fetchByPrimaryKey(userId2); 432 433 if ((user2 == null) || user2.isDefaultUser()) { 434 return false; 435 } 436 437 return !hasRelation(userId1, userId2, type); 438 } 439 440 }