001 /** 002 * Copyright (c) 2000-2013 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 @Override 073 public SocialRelation addRelation(long userId1, long userId2, int type) 074 throws PortalException, SystemException { 075 076 if (userId1 == userId2) { 077 throw new RelationUserIdException(); 078 } 079 080 User user1 = userPersistence.findByPrimaryKey(userId1); 081 User user2 = userPersistence.findByPrimaryKey(userId2); 082 083 if (user1.getCompanyId() != user2.getCompanyId()) { 084 throw new RelationUserIdException(); 085 } 086 087 SocialRelation relation = socialRelationPersistence.fetchByU1_U2_T( 088 userId1, userId2, type); 089 090 if (relation == null) { 091 long relationId = counterLocalService.increment(); 092 093 relation = socialRelationPersistence.create(relationId); 094 095 relation.setCompanyId(user1.getCompanyId()); 096 relation.setCreateDate(System.currentTimeMillis()); 097 relation.setUserId1(userId1); 098 relation.setUserId2(userId2); 099 relation.setType(type); 100 101 socialRelationPersistence.update(relation, false); 102 } 103 104 if (SocialRelationConstants.isTypeBi(type)) { 105 SocialRelation biRelation = 106 socialRelationPersistence.fetchByU1_U2_T( 107 userId2, userId1, type); 108 109 if (biRelation == null) { 110 long biRelationId = counterLocalService.increment(); 111 112 biRelation = socialRelationPersistence.create(biRelationId); 113 114 biRelation.setCompanyId(user1.getCompanyId()); 115 biRelation.setCreateDate(System.currentTimeMillis()); 116 biRelation.setUserId1(userId2); 117 biRelation.setUserId2(userId1); 118 biRelation.setType(type); 119 120 socialRelationPersistence.update(biRelation, false); 121 } 122 } 123 124 return relation; 125 } 126 127 /** 128 * Removes the relation (and its inverse in case of a bidirectional 129 * relation) from the database. 130 * 131 * @param relationId the primary key of the relation 132 * @throws PortalException if the relation could not be found 133 * @throws SystemException if a system exception occurred 134 */ 135 @Override 136 public void deleteRelation(long relationId) 137 throws PortalException, SystemException { 138 139 SocialRelation relation = socialRelationPersistence.findByPrimaryKey( 140 relationId); 141 142 deleteRelation(relation); 143 } 144 145 /** 146 * Removes the matching relation (and its inverse in case of a bidirectional 147 * relation) from the database. 148 * 149 * @param userId1 the user that is the subject of the relation 150 * @param userId2 the user at the other end of the relation 151 * @param type the relation's type 152 * @throws PortalException if the relation or its inverse relation (if 153 * applicable) could not be found 154 * @throws SystemException if a system exception occurred 155 */ 156 @Override 157 public void deleteRelation(long userId1, long userId2, int type) 158 throws PortalException, SystemException { 159 160 SocialRelation relation = socialRelationPersistence.findByU1_U2_T( 161 userId1, userId2, type); 162 163 deleteRelation(relation); 164 } 165 166 /** 167 * Removes the relation (and its inverse in case of a bidirectional 168 * relation) from the database. 169 * 170 * @param relation the relation to be removed 171 * @throws PortalException if the relation is bidirectional and its inverse 172 * relation could not be found 173 * @throws SystemException if a system exception occurred 174 */ 175 @Override 176 public void deleteRelation(SocialRelation relation) 177 throws PortalException, SystemException { 178 179 socialRelationPersistence.remove(relation); 180 181 if (SocialRelationConstants.isTypeBi(relation.getType())) { 182 SocialRelation biRelation = socialRelationPersistence.findByU1_U2_T( 183 relation.getUserId2(), relation.getUserId1(), 184 relation.getType()); 185 186 socialRelationPersistence.remove(biRelation); 187 } 188 } 189 190 /** 191 * Removes all relations involving the user from the database. 192 * 193 * @param userId the primary key of the user 194 * @throws SystemException if a system exception occurred 195 */ 196 @Override 197 public void deleteRelations(long userId) throws SystemException { 198 socialRelationPersistence.removeByUserId1(userId); 199 socialRelationPersistence.removeByUserId2(userId); 200 } 201 202 /** 203 * Removes all relations between User1 and User2. 204 * 205 * @param userId1 the user that is the subject of the relation 206 * @param userId2 the user at the other end of the relation 207 * @throws PortalException if the inverse relation could not be found 208 * @throws SystemException if a system exception occurred 209 */ 210 @Override 211 public void deleteRelations(long userId1, long userId2) 212 throws PortalException, SystemException { 213 214 List<SocialRelation> relations = socialRelationPersistence.findByU1_U2( 215 userId1, userId2); 216 217 for (SocialRelation relation : relations) { 218 deleteRelation(relation); 219 } 220 } 221 222 /** 223 * Returns a range of all the inverse relations of the given type for which 224 * the user is User2 of the relation. 225 * 226 * <p> 227 * Useful when paginating results. Returns a maximum of <code>end - 228 * start</code> instances. <code>start</code> and <code>end</code> are not 229 * primary keys, they are indexes in the result set. Thus, <code>0</code> 230 * refers to the first result in the set. Setting both <code>start</code> 231 * and <code>end</code> to {@link 232 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 233 * result set. 234 * </p> 235 * 236 * @param userId the primary key of the user 237 * @param type the relation's type 238 * @param start the lower bound of the range of results 239 * @param end the upper bound of the range of results (not inclusive) 240 * @return the range of matching relations 241 * @throws SystemException if a system exception occurred 242 */ 243 @Override 244 public List<SocialRelation> getInverseRelations( 245 long userId, int type, int start, int end) 246 throws SystemException { 247 248 return socialRelationPersistence.findByU2_T(userId, type, start, end); 249 } 250 251 /** 252 * Returns the number of inverse relations of the given type for which the 253 * user is User2 of the relation. 254 * 255 * @param userId the primary key of the user 256 * @param type the relation's type 257 * @return the number of matching relations 258 * @throws SystemException if a system exception occurred 259 */ 260 @Override 261 public int getInverseRelationsCount(long userId, int type) 262 throws SystemException { 263 264 return socialRelationPersistence.countByU2_T(userId, type); 265 } 266 267 /** 268 * Returns the relation identified by its primary key. 269 * 270 * @param relationId the primary key of the relation 271 * @return Returns the relation 272 * @throws PortalException if the relation could not be found 273 * @throws SystemException if a system exception occurred 274 */ 275 @Override 276 public SocialRelation getRelation(long relationId) 277 throws PortalException, SystemException { 278 279 return socialRelationPersistence.findByPrimaryKey(relationId); 280 } 281 282 /** 283 * Returns the relation of the given type between User1 and User2. 284 * 285 * @param userId1 the user that is the subject of the relation 286 * @param userId2 the user at the other end of the relation 287 * @param type the relation's type 288 * @return Returns the relation 289 * @throws PortalException if the relation could not be found 290 * @throws SystemException if a system exception occurred 291 */ 292 @Override 293 public SocialRelation getRelation(long userId1, long userId2, int type) 294 throws PortalException, SystemException { 295 296 return socialRelationPersistence.findByU1_U2_T(userId1, userId2, type); 297 } 298 299 /** 300 * Returns a range of all the relations of the given type where the user is 301 * the subject of the relation. 302 * 303 * <p> 304 * Useful when paginating results. Returns a maximum of <code>end - 305 * start</code> instances. <code>start</code> and <code>end</code> are not 306 * primary keys, they are indexes in the result set. Thus, <code>0</code> 307 * refers to the first result in the set. Setting both <code>start</code> 308 * and <code>end</code> to {@link 309 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 310 * result set. 311 * </p> 312 * 313 * @param userId the primary key of the user 314 * @param type the relation's type 315 * @param start the lower bound of the range of results 316 * @param end the upper bound of the range of results (not inclusive) 317 * @return the range of relations 318 * @throws SystemException if a system exception occurred 319 */ 320 @Override 321 public List<SocialRelation> getRelations( 322 long userId, int type, int start, int end) 323 throws SystemException { 324 325 return socialRelationPersistence.findByU1_T(userId, type, start, end); 326 } 327 328 /** 329 * Returns a range of all the relations between User1 and User2. 330 * 331 * <p> 332 * Useful when paginating results. Returns a maximum of <code>end - 333 * start</code> instances. <code>start</code> and <code>end</code> are not 334 * primary keys, they are indexes in the result set. Thus, <code>0</code> 335 * refers to the first result in the set. Setting both <code>start</code> 336 * and <code>end</code> to {@link 337 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 338 * result set. 339 * </p> 340 * 341 * @param userId1 the user that is the subject of the relation 342 * @param userId2 the user at the other end of the relation 343 * @param start the lower bound of the range of results 344 * @param end the upper bound of the range of results (not inclusive) 345 * @return the range of relations 346 * @throws SystemException if a system exception occurred 347 */ 348 @Override 349 public List<SocialRelation> getRelations( 350 long userId1, long userId2, int start, int end) 351 throws SystemException { 352 353 return socialRelationPersistence.findByU1_U2( 354 userId1, userId2, start, end); 355 } 356 357 /** 358 * Returns the number of relations of the given type where the user is the 359 * subject of the relation. 360 * 361 * @param userId the primary key of the user 362 * @param type the relation's type 363 * @return the number of relations 364 * @throws SystemException if a system exception occurred 365 */ 366 @Override 367 public int getRelationsCount(long userId, int type) throws SystemException { 368 return socialRelationPersistence.countByU1_T(userId, type); 369 } 370 371 /** 372 * Returns the number of relations between User1 and User2. 373 * 374 * @param userId1 the user that is the subject of the relation 375 * @param userId2 the user at the other end of the relation 376 * @return the number of relations 377 * @throws SystemException if a system exception occurred 378 */ 379 @Override 380 public int getRelationsCount(long userId1, long userId2) 381 throws SystemException { 382 383 return socialRelationPersistence.countByU1_U2(userId1, userId2); 384 } 385 386 /** 387 * Returns <code>true</code> if a relation of the given type exists where 388 * the user with primary key <code>userId1</code> is User1 of the relation 389 * and the user with the primary key <code>userId2</code> is User2 of the 390 * relation. 391 * 392 * @param userId1 the user that is the subject of the relation 393 * @param userId2 the user at the other end of the relation 394 * @param type the relation's type 395 * @return <code>true</code> if the relation exists; <code>false</code> 396 * otherwise 397 * @throws SystemException if a system exception occurred 398 */ 399 @Override 400 public boolean hasRelation(long userId1, long userId2, int type) 401 throws SystemException { 402 403 SocialRelation relation = socialRelationPersistence.fetchByU1_U2_T( 404 userId1, userId2, type); 405 406 if (relation == null) { 407 return false; 408 } 409 else { 410 return true; 411 } 412 } 413 414 /** 415 * Returns <code>true</code> if the users can be in a relation of the given 416 * type where the user with primary key <code>userId1</code> is User1 of the 417 * relation and the user with the primary key <code>userId2</code> is User2 418 * of the relation. 419 * 420 * <p> 421 * This method returns <code>false</code> if User1 and User2 are the same, 422 * if either user is the default user, or if a matching relation already 423 * exists. 424 * </p> 425 * 426 * @param userId1 the user that is the subject of the relation 427 * @param userId2 the user at the other end of the relation 428 * @param type the relation's type 429 * @return <code>true</code> if the two users can be in a new relation of 430 * the given type; <code>false</code> otherwise 431 * @throws SystemException if a system exception occurred 432 */ 433 @Override 434 public boolean isRelatable(long userId1, long userId2, int type) 435 throws SystemException { 436 437 if (userId1 == userId2) { 438 return false; 439 } 440 441 User user1 = userPersistence.fetchByPrimaryKey(userId1); 442 443 if ((user1 == null) || user1.isDefaultUser()) { 444 return false; 445 } 446 447 User user2 = userPersistence.fetchByPrimaryKey(userId2); 448 449 if ((user2 == null) || user2.isDefaultUser()) { 450 return false; 451 } 452 453 return !hasRelation(userId1, userId2, type); 454 } 455 456 }