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