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><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 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 }