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.portal.service.impl; 016 017 import com.liferay.portal.DuplicateOrganizationException; 018 import com.liferay.portal.OrganizationNameException; 019 import com.liferay.portal.OrganizationParentException; 020 import com.liferay.portal.OrganizationTypeException; 021 import com.liferay.portal.RequiredOrganizationException; 022 import com.liferay.portal.kernel.cache.ThreadLocalCachable; 023 import com.liferay.portal.kernel.configuration.Filter; 024 import com.liferay.portal.kernel.dao.orm.QueryUtil; 025 import com.liferay.portal.kernel.exception.PortalException; 026 import com.liferay.portal.kernel.exception.SystemException; 027 import com.liferay.portal.kernel.search.Hits; 028 import com.liferay.portal.kernel.search.Indexer; 029 import com.liferay.portal.kernel.search.IndexerRegistryUtil; 030 import com.liferay.portal.kernel.search.QueryConfig; 031 import com.liferay.portal.kernel.search.SearchContext; 032 import com.liferay.portal.kernel.search.Sort; 033 import com.liferay.portal.kernel.util.ArrayUtil; 034 import com.liferay.portal.kernel.util.GetterUtil; 035 import com.liferay.portal.kernel.util.OrderByComparator; 036 import com.liferay.portal.kernel.util.PropsKeys; 037 import com.liferay.portal.kernel.util.StringPool; 038 import com.liferay.portal.kernel.util.Validator; 039 import com.liferay.portal.kernel.workflow.WorkflowConstants; 040 import com.liferay.portal.model.Company; 041 import com.liferay.portal.model.Group; 042 import com.liferay.portal.model.GroupConstants; 043 import com.liferay.portal.model.LayoutSet; 044 import com.liferay.portal.model.ListTypeConstants; 045 import com.liferay.portal.model.Organization; 046 import com.liferay.portal.model.OrganizationConstants; 047 import com.liferay.portal.model.ResourceConstants; 048 import com.liferay.portal.model.Role; 049 import com.liferay.portal.model.RoleConstants; 050 import com.liferay.portal.model.User; 051 import com.liferay.portal.model.impl.OrganizationImpl; 052 import com.liferay.portal.security.permission.PermissionCacheUtil; 053 import com.liferay.portal.service.ServiceContext; 054 import com.liferay.portal.service.base.OrganizationLocalServiceBaseImpl; 055 import com.liferay.portal.util.PropsUtil; 056 import com.liferay.portal.util.PropsValues; 057 import com.liferay.portal.util.comparator.OrganizationNameComparator; 058 import com.liferay.portlet.expando.model.ExpandoBridge; 059 060 import java.io.Serializable; 061 062 import java.util.ArrayList; 063 import java.util.HashMap; 064 import java.util.Iterator; 065 import java.util.LinkedHashMap; 066 import java.util.List; 067 import java.util.Map; 068 069 /** 070 * The implementation of the organization local service. 071 * 072 * @author Brian Wing Shun Chan 073 * @author Jorge Ferrer 074 * @author Julio Camarero 075 * @author Hugo Huijser 076 * @author Juan Fernández 077 */ 078 public class OrganizationLocalServiceImpl 079 extends OrganizationLocalServiceBaseImpl { 080 081 /** 082 * Adds the organizations to the group. 083 * 084 * @param groupId the primary key of the group 085 * @param organizationIds the primary keys of the organizations 086 * @throws PortalException if a group or organization with the primary key 087 * could not be found 088 * @throws SystemException if a system exception occurred 089 */ 090 public void addGroupOrganizations(long groupId, long[] organizationIds) 091 throws PortalException, SystemException { 092 093 groupPersistence.addOrganizations(groupId, organizationIds); 094 095 Indexer indexer = IndexerRegistryUtil.getIndexer(Organization.class); 096 097 indexer.reindex(organizationIds); 098 099 PermissionCacheUtil.clearCache(); 100 } 101 102 /** 103 * Adds an organization. 104 * 105 * <p> 106 * This method handles the creation and bookkeeping of the organization 107 * including its resources, metadata, and internal data structures. It is 108 * not necessary to make a subsequent call to {@link 109 * #addOrganizationResources(long, Organization)}. 110 * </p> 111 * 112 * @param userId the primary key of the creator/owner of the organization 113 * @param parentOrganizationId the primary key of the organization's parent 114 * organization 115 * @param name the organization's name 116 * @param type the organization's type 117 * @param recursable whether the permissions of the organization are to be 118 * inherited by its sub-organizations 119 * @param regionId the primary key of the organization's region 120 * @param countryId the primary key of the organization's country 121 * @param statusId the organization's workflow status 122 * @param comments the comments about the organization 123 * @param site whether the organization is to be associated with a main 124 * site 125 * @param serviceContext the organization's service context (optionally 126 * <code>null</code>). Can set asset category IDs, asset tag names, 127 * and expando bridge attributes for the organization. 128 * @return the organization 129 * @throws PortalException if a creator or parent organization with the 130 * primary key could not be found or if the organization's 131 * information was invalid 132 * @throws SystemException if a system exception occurred 133 */ 134 public Organization addOrganization( 135 long userId, long parentOrganizationId, String name, String type, 136 boolean recursable, long regionId, long countryId, int statusId, 137 String comments, boolean site, ServiceContext serviceContext) 138 throws PortalException, SystemException { 139 140 // Organization 141 142 User user = userPersistence.findByPrimaryKey(userId); 143 parentOrganizationId = getParentOrganizationId( 144 user.getCompanyId(), parentOrganizationId); 145 recursable = true; 146 147 validate( 148 user.getCompanyId(), parentOrganizationId, name, type, countryId, 149 statusId); 150 151 long organizationId = counterLocalService.increment(); 152 153 Organization organization = organizationPersistence.create( 154 organizationId); 155 156 organization.setCompanyId(user.getCompanyId()); 157 organization.setParentOrganizationId(parentOrganizationId); 158 159 String treePath = organization.buildTreePath(); 160 161 organization.setTreePath(treePath); 162 163 organization.setName(name); 164 organization.setType(type); 165 organization.setRecursable(recursable); 166 organization.setRegionId(regionId); 167 organization.setCountryId(countryId); 168 organization.setStatusId(statusId); 169 organization.setComments(comments); 170 171 organizationPersistence.update(organization, false); 172 173 // Group 174 175 Group group = groupLocalService.addGroup( 176 userId, Organization.class.getName(), organizationId, name, null, 177 GroupConstants.TYPE_SITE_PRIVATE, null, site, true, null); 178 179 if (PropsValues.ORGANIZATIONS_ASSIGNMENT_AUTO) { 180 181 // Role 182 183 Role role = roleLocalService.getRole( 184 organization.getCompanyId(), RoleConstants.ORGANIZATION_OWNER); 185 186 userGroupRoleLocalService.addUserGroupRoles( 187 userId, group.getGroupId(), new long[] {role.getRoleId()}); 188 189 // User 190 191 userPersistence.addOrganization(userId, organizationId); 192 } 193 194 // Resources 195 196 addOrganizationResources(userId, organization); 197 198 // Asset 199 200 if (serviceContext != null) { 201 updateAsset( 202 userId, organization, serviceContext.getAssetCategoryIds(), 203 serviceContext.getAssetTagNames()); 204 } 205 206 // Expando 207 208 if (serviceContext != null) { 209 ExpandoBridge expandoBridge = organization.getExpandoBridge(); 210 211 expandoBridge.setAttributes(serviceContext); 212 } 213 214 // Indexer 215 216 if ((serviceContext == null) || serviceContext.isIndexingEnabled()) { 217 Indexer indexer = IndexerRegistryUtil.getIndexer( 218 Organization.class); 219 220 indexer.reindex(organization); 221 } 222 223 return organization; 224 } 225 226 /** 227 * Adds a resource for each type of permission available on the 228 * organization. 229 * 230 * @param userId the primary key of the creator/owner of the organization 231 * @param organization the organization 232 * @throws PortalException if a portal exception occurred 233 * @throws SystemException if a system exception occurred 234 */ 235 public void addOrganizationResources(long userId, Organization organization) 236 throws PortalException, SystemException { 237 238 String name = Organization.class.getName(); 239 240 resourceLocalService.addResources( 241 organization.getCompanyId(), 0, userId, name, 242 organization.getOrganizationId(), false, false, false); 243 } 244 245 /** 246 * Assigns the password policy to the organizations, removing any other 247 * currently assigned password policies. 248 * 249 * @param passwordPolicyId the primary key of the password policy 250 * @param organizationIds the primary keys of the organizations 251 * @throws SystemException if a system exception occurred 252 */ 253 public void addPasswordPolicyOrganizations( 254 long passwordPolicyId, long[] organizationIds) 255 throws SystemException { 256 257 passwordPolicyRelLocalService.addPasswordPolicyRels( 258 passwordPolicyId, Organization.class.getName(), organizationIds); 259 } 260 261 /** 262 * Deletes the logo of the organization. 263 * 264 * @param organizationId the primary key of the organization 265 * @throws PortalException if an organization or parent organization with 266 * the primary key could not be found or if the organization's logo 267 * could not be found 268 * @throws SystemException if a system exception occurred 269 */ 270 public void deleteLogo(long organizationId) 271 throws PortalException, SystemException { 272 273 Organization organization = getOrganization(organizationId); 274 275 Group group = organization.getGroup(); 276 277 LayoutSet publicLayoutSet = layoutSetLocalService.getLayoutSet( 278 group.getGroupId(), false); 279 280 if (publicLayoutSet.isLogo()) { 281 long logoId = publicLayoutSet.getLogoId(); 282 283 publicLayoutSet.setLogo(false); 284 publicLayoutSet.setLogoId(0); 285 286 layoutSetPersistence.update(publicLayoutSet, false); 287 288 imageLocalService.deleteImage(logoId); 289 } 290 291 LayoutSet privateLayoutSet = layoutSetLocalService.getLayoutSet( 292 group.getGroupId(), true); 293 294 if (privateLayoutSet.isLogo()) { 295 long logoId = privateLayoutSet.getLogoId(); 296 297 privateLayoutSet.setLogo(false); 298 privateLayoutSet.setLogoId(0); 299 300 layoutSetPersistence.update(privateLayoutSet, false); 301 302 if (imageLocalService.getImage(logoId) != null) { 303 imageLocalService.deleteImage(logoId); 304 } 305 } 306 } 307 308 /** 309 * Deletes the organization. The organization's associated resources and 310 * assets are also deleted. 311 * 312 * @param organizationId the primary key of the organization 313 * @throws PortalException if an organization with the primary key could not 314 * be found, if the organization had a workflow in approved status, 315 * or if the organization was a parent organization 316 * @throws SystemException if a system exception occurred 317 */ 318 @Override 319 public void deleteOrganization(long organizationId) 320 throws PortalException, SystemException { 321 322 Organization organization = organizationPersistence.findByPrimaryKey( 323 organizationId); 324 325 deleteOrganization(organization); 326 } 327 328 /** 329 * Deletes the organization. The organization's associated resources and 330 * assets are also deleted. 331 * 332 * @param organization the organization 333 * @throws PortalException if the organization had a workflow in approved 334 * status or if the organization was a parent organization 335 * @throws SystemException if a system exception occurred 336 */ 337 @Override 338 public void deleteOrganization(Organization organization) 339 throws PortalException, SystemException { 340 341 if ((userLocalService.getOrganizationUsersCount( 342 organization.getOrganizationId(), 343 WorkflowConstants.STATUS_APPROVED) > 0) || 344 (organizationPersistence.countByC_P( 345 organization.getCompanyId(), 346 organization.getOrganizationId()) > 0)) { 347 348 throw new RequiredOrganizationException(); 349 } 350 351 // Asset 352 353 assetEntryLocalService.deleteEntry( 354 Organization.class.getName(), organization.getOrganizationId()); 355 356 // Addresses 357 358 addressLocalService.deleteAddresses( 359 organization.getCompanyId(), Organization.class.getName(), 360 organization.getOrganizationId()); 361 362 // Email addresses 363 364 emailAddressLocalService.deleteEmailAddresses( 365 organization.getCompanyId(), Organization.class.getName(), 366 organization.getOrganizationId()); 367 368 // Expando 369 370 expandoValueLocalService.deleteValues( 371 Organization.class.getName(), organization.getOrganizationId()); 372 373 // Password policy relation 374 375 passwordPolicyRelLocalService.deletePasswordPolicyRel( 376 Organization.class.getName(), organization.getOrganizationId()); 377 378 // Phone 379 380 phoneLocalService.deletePhones( 381 organization.getCompanyId(), Organization.class.getName(), 382 organization.getOrganizationId()); 383 384 // Website 385 386 websiteLocalService.deleteWebsites( 387 organization.getCompanyId(), Organization.class.getName(), 388 organization.getOrganizationId()); 389 390 // Group 391 392 Group group = organization.getGroup(); 393 394 if (group.isSite()) { 395 group.setSite(false); 396 397 groupPersistence.update(group, false); 398 } 399 400 groupLocalService.deleteGroup(group); 401 402 // Resources 403 404 String name = Organization.class.getName(); 405 406 resourceLocalService.deleteResource( 407 organization.getCompanyId(), name, 408 ResourceConstants.SCOPE_INDIVIDUAL, 409 organization.getOrganizationId()); 410 411 // Organization 412 413 organizationPersistence.remove(organization); 414 415 // Permission cache 416 417 PermissionCacheUtil.clearCache(); 418 419 // Indexer 420 421 Indexer indexer = IndexerRegistryUtil.getIndexer(Organization.class); 422 423 indexer.delete(organization); 424 } 425 426 /** 427 * Returns all the organizations belonging to the group. 428 * 429 * @param groupId the primary key of the group 430 * @return the organizations belonging to the group 431 * @throws SystemException if a system exception occurred 432 */ 433 public List<Organization> getGroupOrganizations(long groupId) 434 throws SystemException { 435 436 return groupPersistence.getOrganizations(groupId); 437 } 438 439 /** 440 * Returns the organization with the primary key. 441 * 442 * @param organizationId the primary key of the organization 443 * @return the organization with the primary key 444 * @throws PortalException if an organization with the primary key could not 445 * be found 446 * @throws SystemException if a system exception occurred 447 */ 448 @Override 449 public Organization getOrganization(long organizationId) 450 throws PortalException, SystemException { 451 452 return organizationPersistence.findByPrimaryKey(organizationId); 453 } 454 455 /** 456 * Returns the organization with the name. 457 * 458 * @param companyId the primary key of the organization's company 459 * @param name the organization's name 460 * @return the organization with the name 461 * @throws PortalException if the organization with the name could not be 462 * found 463 * @throws SystemException if a system exception occurred 464 */ 465 public Organization getOrganization(long companyId, String name) 466 throws PortalException, SystemException { 467 468 return organizationPersistence.findByC_N(companyId, name); 469 } 470 471 /** 472 * Returns the primary key of the organization with the name. 473 * 474 * @param companyId the primary key of the organization's company 475 * @param name the organization's name 476 * @return the primary key of the organization with the name, or 477 * <code>0</code> if the organization could not be found 478 * @throws SystemException if a system exception occurred 479 */ 480 public long getOrganizationId(long companyId, String name) 481 throws SystemException { 482 483 Organization organization = organizationPersistence.fetchByC_N( 484 companyId, name); 485 486 if (organization != null) { 487 return organization.getOrganizationId(); 488 } 489 else { 490 return 0; 491 } 492 } 493 494 /** 495 * Returns all the organizations belonging to the parent organization. 496 * 497 * @param companyId the primary key of the organization's company 498 * @param parentOrganizationId the primary key of the organization's parent 499 * organization 500 * @return the organizations belonging to the parent organization 501 * @throws SystemException if a system exception occurred 502 */ 503 public List<Organization> getOrganizations( 504 long companyId, long parentOrganizationId) 505 throws SystemException { 506 507 return getOrganizations( 508 companyId, parentOrganizationId, QueryUtil.ALL_POS, 509 QueryUtil.ALL_POS); 510 } 511 512 /** 513 * Returns a range of all the organizations belonging to the parent 514 * organization. 515 * 516 * <p> 517 * Useful when paginating results. Returns a maximum of <code>end - 518 * start</code> instances. <code>start</code> and <code>end</code> are not 519 * primary keys, they are indexes in the result set. Thus, <code>0</code> 520 * refers to the first result in the set. Setting both <code>start</code> 521 * and <code>end</code> to {@link 522 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 523 * result set. 524 * </p> 525 * 526 * @param companyId the primary key of the organization's company 527 * @param parentOrganizationId the primary key of the organization's parent 528 * organization 529 * @param start the lower bound of the range of organizations to return 530 * @param end the upper bound of the range of organizations to return (not 531 * inclusive) 532 * @return the range of organizations belonging to the parent organization 533 * @throws SystemException if a system exception occurred 534 * @see com.liferay.portal.service.persistence.OrganizationPersistence#findByC_P( 535 * long, long, int, int) 536 */ 537 public List<Organization> getOrganizations( 538 long companyId, long parentOrganizationId, int start, int end) 539 throws SystemException { 540 541 if (parentOrganizationId == 542 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { 543 544 return organizationPersistence.findByCompanyId( 545 companyId, start, end); 546 } 547 else { 548 return organizationPersistence.findByC_P( 549 companyId, parentOrganizationId, start, end); 550 } 551 } 552 553 /** 554 * Returns the organizations with the primary keys. 555 * 556 * @param organizationIds the primary keys of the organizations 557 * @return the organizations with the primary keys 558 * @throws PortalException if any one of the organizations could not be 559 * found 560 * @throws SystemException if a system exception occurred 561 */ 562 public List<Organization> getOrganizations(long[] organizationIds) 563 throws PortalException, SystemException { 564 565 List<Organization> organizations = new ArrayList<Organization>( 566 organizationIds.length); 567 568 for (long organizationId : organizationIds) { 569 Organization organization = getOrganization(organizationId); 570 571 organizations.add(organization); 572 } 573 574 return organizations; 575 } 576 577 /** 578 * Returns the number of organizations belonging to the parent organization. 579 * 580 * @param companyId the primary key of the organization's company 581 * @param parentOrganizationId the primary key of the organization's parent 582 * organization 583 * @return the number of organizations belonging to the parent organization 584 * @throws SystemException if a system exception occurred 585 */ 586 public int getOrganizationsCount(long companyId, long parentOrganizationId) 587 throws SystemException { 588 589 if (parentOrganizationId == 590 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { 591 592 return organizationPersistence.countByCompanyId(companyId); 593 } 594 else { 595 return organizationPersistence.countByC_P( 596 companyId, parentOrganizationId); 597 } 598 } 599 600 /** 601 * Returns the parent organizations in order by closest ancestor. The list 602 * starts with the organization itself. 603 * 604 * @param organizationId the primary key of the organization 605 * @return the parent organizations in order by closest ancestor 606 * @throws PortalException if an organization with the primary key could not 607 * be found 608 * @throws SystemException if a system exception occurred 609 */ 610 public List<Organization> getParentOrganizations(long organizationId) 611 throws PortalException, SystemException { 612 613 if (organizationId == 614 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { 615 616 return new ArrayList<Organization>(); 617 } 618 619 Organization organization = organizationPersistence.findByPrimaryKey( 620 organizationId); 621 622 return getParentOrganizations(organization, true); 623 } 624 625 /** 626 * Returns the sub-organizations of the organizations. 627 * 628 * @param organizations the organizations from which to get 629 * sub-organizations 630 * @return the sub-organizations of the organizations 631 * @throws SystemException if a system exception occurred 632 */ 633 public List<Organization> getSuborganizations( 634 List<Organization> organizations) 635 throws SystemException { 636 637 List<Organization> allSuborganizations = new ArrayList<Organization>(); 638 639 for (int i = 0; i < organizations.size(); i++) { 640 Organization organization = organizations.get(i); 641 642 List<Organization> suborganizations = 643 organizationPersistence.findByC_P( 644 organization.getCompanyId(), 645 organization.getOrganizationId()); 646 647 addSuborganizations(allSuborganizations, suborganizations); 648 } 649 650 return allSuborganizations; 651 } 652 653 /** 654 * Returns the intersection of <code>allOrganizations</code> and 655 * <code>availableOrganizations</code>. 656 * 657 * @param allOrganizations the organizations to check for availability 658 * @param availableOrganizations the available organizations 659 * @return the intersection of <code>allOrganizations</code> and 660 * <code>availableOrganizations</code> 661 */ 662 public List<Organization> getSubsetOrganizations( 663 List<Organization> allOrganizations, 664 List<Organization> availableOrganizations) { 665 666 List<Organization> subsetOrganizations = new ArrayList<Organization>(); 667 668 Iterator<Organization> itr = allOrganizations.iterator(); 669 670 while (itr.hasNext()) { 671 Organization organization = itr.next(); 672 673 if (availableOrganizations.contains(organization)) { 674 subsetOrganizations.add(organization); 675 } 676 } 677 678 return subsetOrganizations; 679 } 680 681 /** 682 * Returns all the organizations associated with the user. 683 * 684 * @param userId the primary key of the user 685 * @return the organizations associated with the user 686 * @throws PortalException if a user with the primary key could not be found 687 * @throws SystemException if a system exception occurred 688 */ 689 public List<Organization> getUserOrganizations(long userId) 690 throws PortalException, SystemException { 691 692 return getUserOrganizations( 693 userId, QueryUtil.ALL_POS, QueryUtil.ALL_POS); 694 } 695 696 /** 697 * Returns a range of all the organizations associated with the user. 698 * 699 * <p> 700 * Useful when paginating results. Returns a maximum of <code>end - 701 * start</code> instances. <code>start</code> and <code>end</code> are not 702 * primary keys, they are indexes in the result set. Thus, <code>0</code> 703 * refers to the first result in the set. Setting both <code>start</code> 704 * and <code>end</code> to {@link 705 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 706 * result set. 707 * </p> 708 * 709 * @param userId the primary key of the user 710 * @param start the lower bound of the range of organizations to return 711 * @param end the upper bound of the range of organizations to return (not 712 * inclusive) 713 * @return the range organizations associated with the user 714 * @throws PortalException if a user with the primary key could not be found 715 * @throws SystemException if a system exception occurred 716 */ 717 public List<Organization> getUserOrganizations( 718 long userId, int start, int end) 719 throws PortalException, SystemException { 720 721 return userPersistence.getOrganizations(userId, start, end); 722 } 723 724 /** 725 * Returns the number of organizations associated with the user. 726 * 727 * @param userId the primary key of the user 728 * @return the number of organizations associated with the user 729 * @throws SystemException if a system exception occurred 730 */ 731 @ThreadLocalCachable 732 public int getUserOrganizationsCount(long userId) throws SystemException { 733 return userPersistence.getOrganizationsSize(userId); 734 } 735 736 /** 737 * Returns <code>true</code> if the organization belongs to the group. 738 * 739 * @param groupId the primary key of the group 740 * @param organizationId the primary key of the organization 741 * @return <code>true</code> if the organization belongs to the group; 742 * <code>false</code> otherwise 743 * @throws SystemException if a system exception occurred 744 */ 745 public boolean hasGroupOrganization(long groupId, long organizationId) 746 throws SystemException { 747 748 return groupPersistence.containsOrganization(groupId, organizationId); 749 } 750 751 /** 752 * Returns <code>true</code> if the password policy has been assigned to the 753 * organization. 754 * 755 * @param passwordPolicyId the primary key of the password policy 756 * @param organizationId the primary key of the organization 757 * @return <code>true</code> if the password policy has been assigned to the 758 * organization; <code>false</code> otherwise 759 * @throws SystemException if a system exception occurred 760 */ 761 public boolean hasPasswordPolicyOrganization( 762 long passwordPolicyId, long organizationId) 763 throws SystemException { 764 765 return passwordPolicyRelLocalService.hasPasswordPolicyRel( 766 passwordPolicyId, Organization.class.getName(), organizationId); 767 } 768 769 /** 770 * Returns <code>true</code> if the user is a member of the organization. 771 * This method is usually called to determine if the user has view access to 772 * a resource belonging to the organization. 773 * 774 * @param userId the primary key of the user 775 * @param organizationId the primary key of the organization 776 * @return <code>true</code> if the user has access to the organization; 777 * <code>false</code> otherwise 778 * @throws SystemException if a system exception occurred 779 */ 780 public boolean hasUserOrganization(long userId, long organizationId) 781 throws SystemException { 782 783 return userPersistence.containsOrganization(userId, organizationId); 784 } 785 786 /** 787 * Returns <code>true</code> if the user is a member of the organization, 788 * optionally focusing on sub-organizations or the specified organization. 789 * This method is usually called to determine if the user has view access to 790 * a resource belonging to the organization. 791 * 792 * <p> 793 * 794 * <ol> 795 * <li> 796 * If <code>inheritSuborganizations=<code>false</code></code>: 797 * the method checks whether the user belongs to the organization specified 798 * by <code>organizationId</code>. The parameter 799 * <code>includeSpecifiedOrganization</code> is ignored. 800 * </li> 801 * <li> 802 * The parameter <code>includeSpecifiedOrganization</code> is 803 * ignored unless <code>inheritSuborganizations</code> is also 804 * <code>true</code>. 805 * </li> 806 * <li> 807 * If <code>inheritSuborganizations=<code>true</code></code> and 808 * <code>includeSpecifiedOrganization=<code>false</code></code>: the method 809 * checks 810 * whether the user belongs to one of the child organizations of the one 811 * specified by <code>organizationId</code>. 812 * </li> 813 * <li> 814 * If <code>inheritSuborganizations=<code>true</code></code> and 815 * <code>includeSpecifiedOrganization=<code>true</code></code>: the method 816 * checks whether 817 * the user belongs to the organization specified by 818 * <code>organizationId</code> or any of 819 * its child organizations. 820 * </li> 821 * </ol> 822 * 823 * <p> 824 * 825 * @param userId the primary key of the organization's user 826 * @param organizationId the primary key of the organization 827 * @param inheritSuborganizations if <code>true</code> sub-organizations 828 * are considered in the determination 829 * @param includeSpecifiedOrganization if <code>true</code> the 830 * organization specified by <code>organizationId</code> is 831 * considered in the determination 832 * @return <code>true</code> if the user has access to the organization; 833 * <code>false</code> otherwise 834 * @throws PortalException if an organization with the primary key could not 835 * be found 836 * @throws SystemException if a system exception occurred 837 * @see com.liferay.portal.service.persistence.OrganizationFinder 838 */ 839 public boolean hasUserOrganization( 840 long userId, long organizationId, boolean inheritSuborganizations, 841 boolean includeSpecifiedOrganization) 842 throws PortalException, SystemException { 843 844 if (!inheritSuborganizations) { 845 return userPersistence.containsOrganization(userId, organizationId); 846 } 847 848 LinkedHashMap<String, Object> params = 849 new LinkedHashMap<String, Object>(); 850 851 List<Organization> organizationsTree = new ArrayList<Organization>(); 852 853 Organization organization = organizationPersistence.findByPrimaryKey( 854 organizationId); 855 856 if (!includeSpecifiedOrganization) { 857 organizationsTree.add(organization); 858 } 859 else { 860 organizationsTree.add(organization.getParentOrganization()); 861 } 862 863 params.put("usersOrgsTree", organizationsTree); 864 865 if (userFinder.countByUser(userId, params) > 0) { 866 return true; 867 } 868 869 return false; 870 } 871 872 /** 873 * Rebuilds the organizations tree. 874 * 875 * <p> 876 * Only call this method if the tree has become stale through operations 877 * other than normal CRUD. Under normal circumstances the tree is 878 * automatically rebuilt whenever necessary. 879 * </p> 880 * 881 * @param companyId the primary key of the organization's company 882 * @throws PortalException if an organization with the primary key could not 883 * be found 884 * @throws SystemException if a system exception occurred 885 * @see com.liferay.portal.service.persistence.OrganizationPersistence#rebuildTree( 886 * long, boolean) 887 */ 888 public void rebuildTree(long companyId) 889 throws PortalException, SystemException { 890 891 List<Organization> organizations = 892 organizationPersistence.findByCompanyId(companyId); 893 894 for (Organization organization : organizations) { 895 String treePath = organization.buildTreePath(); 896 897 organization.setTreePath(treePath); 898 899 organizationPersistence.update(organization, false); 900 } 901 } 902 903 /** 904 * Returns a range of all the organizations of the company. 905 * 906 * <p> 907 * Useful when paginating results. Returns a maximum of <code>end - 908 * start</code> instances. <code>start</code> and <code>end</code> are not 909 * primary keys, they are indexes in the result set. Thus, <code>0</code> 910 * refers to the first result in the set. Setting both <code>start</code> 911 * and <code>end</code> to {@link 912 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 913 * result set. 914 * </p> 915 * 916 * @param companyId the primary key of the company 917 * @param params the finder parameters (optionally <code>null</code>). For 918 * more information see {@link 919 * com.liferay.portlet.enterpriseadmin.util.OrganizationIndexer} 920 * @param start the lower bound of the range of organizations to return 921 * @param end the upper bound of the range of organizations to return (not 922 * inclusive) 923 * @return the range of all the organizations of the company 924 * @throws SystemException if a system exception occurred 925 */ 926 public List<Organization> search( 927 long companyId, LinkedHashMap<String, Object> params, int start, 928 int end) 929 throws SystemException { 930 931 return organizationFinder.findByCompanyId( 932 companyId, params, start, end, 933 new OrganizationNameComparator(true)); 934 } 935 936 /** 937 * Returns an ordered range of all the organizations that match the 938 * keywords, using the indexer. It is preferable to use this method instead 939 * of the non-indexed version whenever possible for performance reasons. 940 * 941 * <p> 942 * Useful when paginating results. Returns a maximum of <code>end - 943 * start</code> instances. <code>start</code> and <code>end</code> are not 944 * primary keys, they are indexes in the result set. Thus, <code>0</code> 945 * refers to the first result in the set. Setting both <code>start</code> 946 * and <code>end</code> to {@link 947 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 948 * result set. 949 * </p> 950 * 951 * @param companyId the primary key of the organization's company 952 * @param parentOrganizationId the primary key of the organization's parent 953 * organization 954 * @param keywords the keywords (space separated), which may occur in the 955 * organization's name, street, city, zipcode, type, region or 956 * country (optionally <code>null</code>) 957 * @param params the finder parameters (optionally <code>null</code>). For 958 * more information see {@link 959 * com.liferay.portlet.enterpriseadmin.util.OrganizationIndexer} 960 * @param start the lower bound of the range of organizations to return 961 * @param end the upper bound of the range of organizations to return (not 962 * inclusive) 963 * @param sort the field and direction by which to sort (optionally 964 * <code>null</code>) 965 * @return the matching organizations ordered by name 966 * @throws SystemException if a system exception occurred 967 * @see com.liferay.portlet.enterpriseadmin.util.OrganizationIndexer 968 */ 969 public Hits search( 970 long companyId, long parentOrganizationId, String keywords, 971 LinkedHashMap<String, Object> params, int start, int end, Sort sort) 972 throws SystemException { 973 974 String name = null; 975 String type = null; 976 String street = null; 977 String city = null; 978 String zip = null; 979 String region = null; 980 String country = null; 981 boolean andOperator = false; 982 983 if (Validator.isNotNull(keywords)) { 984 name = keywords; 985 type = keywords; 986 street = keywords; 987 city = keywords; 988 zip = keywords; 989 region = keywords; 990 country = keywords; 991 } 992 else { 993 andOperator = true; 994 } 995 996 if (params != null) { 997 params.put("keywords", keywords); 998 } 999 1000 return search( 1001 companyId, parentOrganizationId, name, type, street, city, zip, 1002 region, country, params, andOperator, start, end, sort); 1003 } 1004 1005 /** 1006 * Returns a name ordered range of all the organizations that match the 1007 * keywords, type, region, and country, without using the indexer. It is 1008 * preferable to use the indexed version {@link #search(long, long, String, 1009 * LinkedHashMap, int, int, Sort)} instead of this method wherever possible 1010 * for performance reasons. 1011 * 1012 * <p> 1013 * Useful when paginating results. Returns a maximum of <code>end - 1014 * start</code> instances. <code>start</code> and <code>end</code> are not 1015 * primary keys, they are indexes in the result set. Thus, <code>0</code> 1016 * refers to the first result in the set. Setting both <code>start</code> 1017 * and <code>end</code> to {@link 1018 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 1019 * result set. 1020 * </p> 1021 * 1022 * @param companyId the primary key of the organization's company 1023 * @param parentOrganizationId the primary key of the organization's parent 1024 * organization 1025 * @param keywords the keywords (space separated), which may occur in the 1026 * organization's name, street, city, or zipcode (optionally 1027 * <code>null</code>) 1028 * @param type the organization's type (optionally <code>null</code>) 1029 * @param regionId the primary key of the organization's region (optionally 1030 * <code>null</code>) 1031 * @param countryId the primary key of the organization's country 1032 * (optionally <code>null</code>) 1033 * @param params the finder params. For more information see {@link 1034 * com.liferay.portal.service.persistence.OrganizationFinder} 1035 * @param start the lower bound of the range of organizations to return 1036 * @param end the upper bound of the range of organizations to return (not 1037 * inclusive) 1038 * @return the matching organizations ordered by name 1039 * @throws SystemException if a system exception occurred 1040 * @see com.liferay.portal.service.persistence.OrganizationFinder 1041 */ 1042 public List<Organization> search( 1043 long companyId, long parentOrganizationId, String keywords, 1044 String type, Long regionId, Long countryId, 1045 LinkedHashMap<String, Object> params, int start, int end) 1046 throws SystemException { 1047 1048 return search( 1049 companyId, parentOrganizationId, keywords, type, regionId, 1050 countryId, params, start, end, 1051 new OrganizationNameComparator(true)); 1052 } 1053 1054 /** 1055 * Returns an ordered range of all the organizations that match the 1056 * keywords, type, region, and country, without using the indexer. It is 1057 * preferable to use the indexed version {@link #search(long, long, String, 1058 * String, String, String, String, String, String, LinkedHashMap, boolean, 1059 * int, int, Sort)} instead of this method wherever possible for performance 1060 * reasons. 1061 * 1062 * <p> 1063 * Useful when paginating results. Returns a maximum of <code>end - 1064 * start</code> instances. <code>start</code> and <code>end</code> are not 1065 * primary keys, they are indexes in the result set. Thus, <code>0</code> 1066 * refers to the first result in the set. Setting both <code>start</code> 1067 * and <code>end</code> to {@link 1068 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 1069 * result set. 1070 * </p> 1071 * 1072 * @param companyId the primary key of the organization's company 1073 * @param parentOrganizationId the primary key of the organization's parent 1074 * organization 1075 * @param keywords the keywords (space separated), which may occur in the 1076 * organization's name, street, city, or zipcode (optionally 1077 * <code>null</code>) 1078 * @param type the organization's type (optionally <code>null</code>) 1079 * @param regionId the primary key of the organization's region (optionally 1080 * <code>null</code>) 1081 * @param countryId the primary key of the organization's country 1082 * (optionally <code>null</code>) 1083 * @param params the finder params. For more information see {@link 1084 * com.liferay.portal.service.persistence.OrganizationFinder} 1085 * @param start the lower bound of the range of organizations to return 1086 * @param end the upper bound of the range of organizations to return (not 1087 * inclusive) 1088 * @param obc the comparator to order the organizations (optionally 1089 * <code>null</code>) 1090 * @return the matching organizations ordered by comparator <code>obc</code> 1091 * @throws SystemException if a system exception occurred 1092 * @see com.liferay.portal.service.persistence.OrganizationFinder 1093 */ 1094 public List<Organization> search( 1095 long companyId, long parentOrganizationId, String keywords, 1096 String type, Long regionId, Long countryId, 1097 LinkedHashMap<String, Object> params, int start, int end, 1098 OrderByComparator obc) 1099 throws SystemException { 1100 1101 String parentOrganizationIdComparator = StringPool.EQUAL; 1102 1103 if (parentOrganizationId == 1104 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { 1105 1106 parentOrganizationIdComparator = StringPool.NOT_EQUAL; 1107 } 1108 1109 return organizationFinder.findByKeywords( 1110 companyId, parentOrganizationId, parentOrganizationIdComparator, 1111 keywords, type, regionId, countryId, params, start, end, obc); 1112 } 1113 1114 /** 1115 * Returns a name ordered range of all the organizations with the type, 1116 * region, and country, and whose name, street, city, and zipcode match the 1117 * keywords specified for them, without using the indexer. It is preferable 1118 * to use the indexed version {@link #search(long, long, String, String, 1119 * String, String, String, String, String, LinkedHashMap, boolean, int, int, 1120 * Sort)} instead of this method wherever possible for performance reasons. 1121 * 1122 * <p> 1123 * Useful when paginating results. Returns a maximum of <code>end - 1124 * start</code> instances. <code>start</code> and <code>end</code> are not 1125 * primary keys, they are indexes in the result set. Thus, <code>0</code> 1126 * refers to the first result in the set. Setting both <code>start</code> 1127 * and <code>end</code> to {@link 1128 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 1129 * result set. 1130 * </p> 1131 * 1132 * @param companyId the primary key of the organization's company 1133 * @param parentOrganizationId the primary key of the organization's parent 1134 * @param name the name keywords (space separated, optionally 1135 * <code>null</code>) 1136 * @param type the organization's type (optionally <code>null</code>) 1137 * @param street the street keywords (optionally <code>null</code>) 1138 * @param city the city keywords (optionally <code>null</code>) 1139 * @param zip the zipcode keywords (optionally <code>null</code>) 1140 * @param regionId the primary key of the organization's region (optionally 1141 * <code>null</code>) 1142 * @param countryId the primary key of the organization's country 1143 * (optionally <code>null</code>) 1144 * @param params the finder parameters (optionally <code>null</code>). For 1145 * more information see {@link 1146 * com.liferay.portal.service.persistence.OrganizationFinder} 1147 * @param andOperator whether every field must match its keywords, or just 1148 * one field. For example, "organizations with the name 1149 * 'Employees' and city 'Chicago'" vs "organizations with 1150 * the name 'Employees' or the city 'Chicago'". 1151 * @param start the lower bound of the range of organizations to return 1152 * @param end the upper bound of the range of organizations to return (not 1153 * inclusive) 1154 * @return the matching organizations ordered by name 1155 * @throws SystemException if a system exception occurred 1156 * @see com.liferay.portal.service.persistence.OrganizationFinder 1157 */ 1158 public List<Organization> search( 1159 long companyId, long parentOrganizationId, String name, String type, 1160 String street, String city, String zip, Long regionId, 1161 Long countryId, 1162 LinkedHashMap<String, Object> params, boolean andOperator, 1163 int start, int end) 1164 throws SystemException { 1165 1166 return search( 1167 companyId, parentOrganizationId, name, type, street, city, zip, 1168 regionId, countryId, params, andOperator, start, end, 1169 new OrganizationNameComparator(true)); 1170 } 1171 1172 /** 1173 * Returns an ordered range of all the organizations with the type, region, 1174 * and country, and whose name, street, city, and zipcode match the keywords 1175 * specified for them, without using the indexer. It is preferable to use 1176 * the indexed version {@link #search(long, long, String, String, String, 1177 * String, String, String, String, LinkedHashMap, boolean, int, int, Sort)} 1178 * instead of this method wherever possible for performance reasons. 1179 * 1180 * <p> 1181 * Useful when paginating results. Returns a maximum of <code>end - 1182 * start</code> instances. <code>start</code> and <code>end</code> are not 1183 * primary keys, they are indexes in the result set. Thus, <code>0</code> 1184 * refers to the first result in the set. Setting both <code>start</code> 1185 * and <code>end</code> to {@link 1186 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 1187 * result set. 1188 * </p> 1189 * 1190 * @param companyId the primary key of the organization's company 1191 * @param parentOrganizationId the primary key of the organization's parent 1192 * organization 1193 * @param name the name keywords (space separated, optionally 1194 * <code>null</code>) 1195 * @param type the organization's type (optionally <code>null</code>) 1196 * @param street the street keywords (optionally <code>null</code>) 1197 * @param city the city keywords (optionally <code>null</code>) 1198 * @param zip the zipcode keywords (optionally <code>null</code>) 1199 * @param regionId the primary key of the organization's region (optionally 1200 * <code>null</code>) 1201 * @param countryId the primary key of the organization's country 1202 * (optionally <code>null</code>) 1203 * @param params the finder parameters (optionally <code>null</code>). For 1204 * more information see {@link 1205 * com.liferay.portal.service.persistence.OrganizationFinder} 1206 * @param andOperator whether every field must match its keywords, or just 1207 * one field. For example, "organizations with the name 1208 * 'Employees' and city 'Chicago'" vs "organizations with 1209 * the name 'Employees' or the city 'Chicago'". 1210 * @param start the lower bound of the range of organizations to return 1211 * @param end the upper bound of the range of organizations to return (not 1212 * inclusive) 1213 * @param obc the comparator to order the organizations (optionally 1214 * <code>null</code>) 1215 * @return the matching organizations ordered by comparator <code>obc</code> 1216 * @throws SystemException if a system exception occurred 1217 * @see com.liferay.portal.service.persistence.OrganizationFinder 1218 */ 1219 public List<Organization> search( 1220 long companyId, long parentOrganizationId, String name, String type, 1221 String street, String city, String zip, Long regionId, 1222 Long countryId, LinkedHashMap<String, Object> params, 1223 boolean andOperator, int start, int end, OrderByComparator obc) 1224 throws SystemException { 1225 1226 String parentOrganizationIdComparator = StringPool.EQUAL; 1227 1228 if (parentOrganizationId == 1229 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { 1230 1231 parentOrganizationIdComparator = StringPool.NOT_EQUAL; 1232 } 1233 1234 return organizationFinder.findByC_PO_N_T_S_C_Z_R_C( 1235 companyId, parentOrganizationId, parentOrganizationIdComparator, 1236 name, type, street, city, zip, regionId, countryId, params, 1237 andOperator, start, end, obc); 1238 } 1239 1240 /** 1241 * Returns an ordered range of all the organizations whose name, type, or 1242 * location fields match the keywords specified for them, using the indexer. 1243 * It is preferable to use this method instead of the non-indexed version 1244 * whenever possible for performance reasons. 1245 * 1246 * <p> 1247 * Useful when paginating results. Returns a maximum of <code>end - 1248 * start</code> instances. <code>start</code> and <code>end</code> are not 1249 * primary keys, they are indexes in the result set. Thus, <code>0</code> 1250 * refers to the first result in the set. Setting both <code>start</code> 1251 * and <code>end</code> to {@link 1252 * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full 1253 * result set. 1254 * </p> 1255 * 1256 * @param companyId the primary key of the organization's company 1257 * @param parentOrganizationId the primary key of the organization's parent 1258 * organization 1259 * @param name the name keywords (space separated, optionally 1260 * <code>null</code>) 1261 * @param type the type keywords (optionally <code>null</code>) 1262 * @param street the street keywords (optionally <code>null</code>) 1263 * @param city the city keywords (optionally <code>null</code>) 1264 * @param zip the zipcode keywords (optionally <code>null</code>) 1265 * @param region the region keywords (optionally <code>null</code>) 1266 * @param country the country keywords (optionally <code>null</code>) 1267 * @param params the finder parameters (optionally <code>null</code>). For 1268 * more information see {@link 1269 * com.liferay.portlet.enterpriseadmin.util.OrganizationIndexer}. 1270 * @param andSearch whether every field must match its keywords or just one 1271 * field 1272 * @param start the lower bound of the range of organizations to return 1273 * @param end the upper bound of the range of organizations to return (not 1274 * inclusive) 1275 * @param sort the field and direction by which to sort (optionally 1276 * <code>null</code>) 1277 * @return the matching organizations ordered by <code>sort</code> 1278 * @throws SystemException if a system exception occurred 1279 * @see com.liferay.portlet.enterpriseadmin.util.OrganizationIndexer 1280 */ 1281 public Hits search( 1282 long companyId, long parentOrganizationId, String name, String type, 1283 String street, String city, String zip, String region, 1284 String country, LinkedHashMap<String, Object> params, 1285 boolean andSearch, int start, int end, Sort sort) 1286 throws SystemException { 1287 1288 try { 1289 SearchContext searchContext = new SearchContext(); 1290 1291 searchContext.setAndSearch(andSearch); 1292 1293 Map<String, Serializable> attributes = 1294 new HashMap<String, Serializable>(); 1295 1296 attributes.put("city", city); 1297 attributes.put("country", country); 1298 attributes.put("name", name); 1299 attributes.put("params", params); 1300 1301 if (parentOrganizationId != 1302 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { 1303 1304 attributes.put( 1305 "parentOrganizationId", 1306 String.valueOf(parentOrganizationId)); 1307 } 1308 1309 attributes.put("region", region); 1310 attributes.put("street", street); 1311 attributes.put("type", type); 1312 attributes.put("zip", zip); 1313 1314 searchContext.setAttributes(attributes); 1315 1316 searchContext.setCompanyId(companyId); 1317 searchContext.setEnd(end); 1318 1319 if (params != null) { 1320 String keywords = (String)params.remove("keywords"); 1321 1322 if (Validator.isNotNull(keywords)) { 1323 searchContext.setKeywords(keywords); 1324 } 1325 } 1326 1327 QueryConfig queryConfig = new QueryConfig(); 1328 1329 queryConfig.setHighlightEnabled(false); 1330 queryConfig.setScoreEnabled(false); 1331 1332 searchContext.setQueryConfig(queryConfig); 1333 1334 searchContext.setSorts(new Sort[] {sort}); 1335 searchContext.setStart(start); 1336 1337 Indexer indexer = IndexerRegistryUtil.getIndexer( 1338 Organization.class); 1339 1340 return indexer.search(searchContext); 1341 } 1342 catch (Exception e) { 1343 throw new SystemException(e); 1344 } 1345 } 1346 1347 /** 1348 * Returns the number of organizations that match the keywords, type, 1349 * region, and country. 1350 * 1351 * @param companyId the primary key of the organization's company 1352 * @param parentOrganizationId the primary key of the organization's parent 1353 * organization 1354 * @param keywords the keywords (space separated), which may occur in the 1355 * organization's name, street, city, or zipcode (optionally 1356 * <code>null</code>) 1357 * @param type the organization's type (optionally <code>null</code>) 1358 * @param regionId the primary key of the organization's region (optionally 1359 * <code>null</code>) 1360 * @param countryId the primary key of the organization's country 1361 * (optionally <code>null</code>) 1362 * @param params the finder parameters (optionally <code>null</code>). For 1363 * more information see {@link 1364 * com.liferay.portal.service.persistence.OrganizationFinder} 1365 * @return the number of matching organizations 1366 * @throws SystemException if a system exception occurred 1367 * @see com.liferay.portal.service.persistence.OrganizationFinder 1368 */ 1369 public int searchCount( 1370 long companyId, long parentOrganizationId, String keywords, 1371 String type, Long regionId, Long countryId, 1372 LinkedHashMap<String, Object> params) 1373 throws SystemException { 1374 1375 String parentOrganizationIdComparator = StringPool.EQUAL; 1376 1377 if (parentOrganizationId == 1378 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { 1379 1380 parentOrganizationIdComparator = StringPool.NOT_EQUAL; 1381 } 1382 1383 return organizationFinder.countByKeywords( 1384 companyId, parentOrganizationId, parentOrganizationIdComparator, 1385 keywords, type, regionId, countryId, params); 1386 } 1387 1388 /** 1389 * Returns the number of organizations with the type, region, and country, 1390 * and whose name, street, city, and zipcode match the keywords specified 1391 * for them. 1392 * 1393 * @param companyId the primary key of the organization's company 1394 * @param parentOrganizationId the primary key of the organization's parent 1395 * organization 1396 * @param name the name keywords (space separated, optionally 1397 * <code>null</code>) 1398 * @param type the organization's type (optionally <code>null</code>) 1399 * @param street the street keywords (optionally <code>null</code>) 1400 * @param city the city keywords (optionally <code>null</code>) 1401 * @param zip the zipcode keywords (optionally <code>null</code>) 1402 * @param regionId the primary key of the organization's region (optionally 1403 * <code>null</code>) 1404 * @param countryId the primary key of the organization's country 1405 * (optionally <code>null</code>) 1406 * @param params the finder parameters (optionally <code>null</code>). For 1407 * more information see {@link 1408 * com.liferay.portal.service.persistence.OrganizationFinder} 1409 * @param andOperator whether every field must match its keywords, or just 1410 * one field. For example, "organizations with the name 1411 * 'Employees' and city 'Chicago'" vs "organizations with 1412 * the name 'Employees' or the city 'Chicago'". 1413 * @return the number of matching organizations 1414 * @throws SystemException if a system exception occurred 1415 * @see com.liferay.portal.service.persistence.OrganizationFinder 1416 */ 1417 public int searchCount( 1418 long companyId, long parentOrganizationId, String name, String type, 1419 String street, String city, String zip, Long regionId, 1420 Long countryId, LinkedHashMap<String, Object> params, 1421 boolean andOperator) 1422 throws SystemException { 1423 1424 String parentOrganizationIdComparator = StringPool.EQUAL; 1425 1426 if (parentOrganizationId == 1427 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { 1428 1429 parentOrganizationIdComparator = StringPool.NOT_EQUAL; 1430 } 1431 1432 return organizationFinder.countByC_PO_N_T_S_C_Z_R_C( 1433 companyId, parentOrganizationId, parentOrganizationIdComparator, 1434 name, type, street, city, zip, regionId, countryId, params, 1435 andOperator); 1436 } 1437 1438 /** 1439 * Sets the organizations in the group, removing and adding organizations to 1440 * the group as necessary. 1441 * 1442 * @param groupId the primary key of the group 1443 * @param organizationIds the primary keys of the organizations 1444 * @throws PortalException if a portal exception occurred 1445 * @throws SystemException if a system exception occurred 1446 */ 1447 public void setGroupOrganizations(long groupId, long[] organizationIds) 1448 throws PortalException, SystemException { 1449 1450 groupPersistence.setOrganizations(groupId, organizationIds); 1451 1452 Indexer indexer = IndexerRegistryUtil.getIndexer(Organization.class); 1453 1454 indexer.reindex(organizationIds); 1455 1456 PermissionCacheUtil.clearCache(); 1457 } 1458 1459 /** 1460 * Removes the organizations from the group. 1461 * 1462 * @param groupId the primary key of the group 1463 * @param organizationIds the primary keys of the organizations 1464 * @throws PortalException if a portal exception occurred 1465 * @throws SystemException if a system exception occurred 1466 */ 1467 public void unsetGroupOrganizations(long groupId, long[] organizationIds) 1468 throws PortalException, SystemException { 1469 1470 groupPersistence.removeOrganizations(groupId, organizationIds); 1471 1472 Indexer indexer = IndexerRegistryUtil.getIndexer(Organization.class); 1473 1474 indexer.reindex(organizationIds); 1475 1476 PermissionCacheUtil.clearCache(); 1477 } 1478 1479 /** 1480 * Removes the organizations from the password policy. 1481 * 1482 * @param passwordPolicyId the primary key of the password policy 1483 * @param organizationIds the primary keys of the organizations 1484 * @throws SystemException if a system exception occurred 1485 */ 1486 public void unsetPasswordPolicyOrganizations( 1487 long passwordPolicyId, long[] organizationIds) 1488 throws SystemException { 1489 1490 passwordPolicyRelLocalService.deletePasswordPolicyRels( 1491 passwordPolicyId, Organization.class.getName(), organizationIds); 1492 } 1493 1494 /** 1495 * Updates the organization's asset with the new asset categories and tag 1496 * names, removing and adding asset categories and tag names as necessary. 1497 * 1498 * @param userId the primary key of the user 1499 * @param organization the organization 1500 * @param assetCategoryIds the primary keys of the asset categories 1501 * @param assetTagNames the asset tag names 1502 * @throws PortalException if a user with the primary key could not be found 1503 * @throws SystemException if a system exception occurred 1504 */ 1505 public void updateAsset( 1506 long userId, Organization organization, long[] assetCategoryIds, 1507 String[] assetTagNames) 1508 throws PortalException, SystemException { 1509 1510 User user = userPersistence.findByPrimaryKey(userId); 1511 1512 Company company = companyPersistence.findByPrimaryKey( 1513 user.getCompanyId()); 1514 1515 Group companyGroup = company.getGroup(); 1516 1517 assetEntryLocalService.updateEntry( 1518 userId, companyGroup.getGroupId(), Organization.class.getName(), 1519 organization.getOrganizationId(), null, 0, assetCategoryIds, 1520 assetTagNames, false, null, null, null, null, null, 1521 organization.getName(), StringPool.BLANK, null, null, null, 0, 0, 1522 null, false); 1523 } 1524 1525 /** 1526 * Updates the organization. 1527 * 1528 * @param companyId the primary key of the organization's company 1529 * @param organizationId the primary key of the organization 1530 * @param parentOrganizationId the primary key of organization's parent 1531 * organization 1532 * @param name the organization's name 1533 * @param type the organization's type 1534 * @param recursable whether permissions of the organization are to be 1535 * inherited by its sub-organizations 1536 * @param regionId the primary key of the organization's region 1537 * @param countryId the primary key of the organization's country 1538 * @param statusId the organization's workflow status 1539 * @param comments the comments about the organization 1540 * @param site whether the organization is to be associated with a main 1541 * site 1542 * @param serviceContext the organization's service context (optionally 1543 * <code>null</code>). Can set asset category IDs and asset tag 1544 * names for the organization, and merge expando bridge attributes 1545 * for the organization. 1546 * @return the organization 1547 * @throws PortalException if an organization or parent organization with 1548 * the primary key could not be found or if the new information was 1549 * invalid 1550 * @throws SystemException if a system exception occurred 1551 */ 1552 public Organization updateOrganization( 1553 long companyId, long organizationId, long parentOrganizationId, 1554 String name, String type, boolean recursable, long regionId, 1555 long countryId, int statusId, String comments, boolean site, 1556 ServiceContext serviceContext) 1557 throws PortalException, SystemException { 1558 1559 // Organization 1560 1561 parentOrganizationId = getParentOrganizationId( 1562 companyId, parentOrganizationId); 1563 recursable = true; 1564 1565 validate( 1566 companyId, organizationId, parentOrganizationId, name, type, 1567 countryId, statusId); 1568 1569 Organization organization = organizationPersistence.findByPrimaryKey( 1570 organizationId); 1571 1572 long oldParentOrganizationId = organization.getParentOrganizationId(); 1573 String oldName = organization.getName(); 1574 1575 organization.setParentOrganizationId(parentOrganizationId); 1576 1577 String treePath = organization.buildTreePath(); 1578 1579 organization.setTreePath(treePath); 1580 1581 organization.setName(name); 1582 organization.setType(type); 1583 organization.setRecursable(recursable); 1584 organization.setRegionId(regionId); 1585 organization.setCountryId(countryId); 1586 organization.setStatusId(statusId); 1587 organization.setComments(comments); 1588 1589 organizationPersistence.update(organization, false); 1590 1591 // Group 1592 1593 Group group = organization.getGroup(); 1594 1595 if (!oldName.equals(name)) { 1596 groupLocalService.updateGroup( 1597 group.getGroupId(), name, group.getDescription(), 1598 group.getType(), group.getFriendlyURL(), group.isActive(), 1599 null); 1600 } 1601 1602 if (group.isSite() != site) { 1603 groupLocalService.updateSite(group.getGroupId(), site); 1604 } 1605 1606 // Asset 1607 1608 if (serviceContext != null) { 1609 updateAsset( 1610 serviceContext.getUserId(), organization, 1611 serviceContext.getAssetCategoryIds(), 1612 serviceContext.getAssetTagNames()); 1613 } 1614 1615 // Expando 1616 1617 if (serviceContext != null) { 1618 ExpandoBridge expandoBridge = organization.getExpandoBridge(); 1619 1620 expandoBridge.setAttributes(serviceContext); 1621 } 1622 1623 // Indexer 1624 1625 Indexer indexer = IndexerRegistryUtil.getIndexer(Organization.class); 1626 1627 if (oldParentOrganizationId != parentOrganizationId) { 1628 long[] organizationIds = getReindexOrganizationIds(organization); 1629 1630 indexer.reindex(organizationIds); 1631 } 1632 else { 1633 indexer.reindex(organization); 1634 } 1635 1636 return organization; 1637 } 1638 1639 protected void addSuborganizations( 1640 List<Organization> allSuborganizations, 1641 List<Organization> organizations) 1642 throws SystemException { 1643 1644 for (Organization organization : organizations) { 1645 if (!allSuborganizations.contains(organization)) { 1646 allSuborganizations.add(organization); 1647 1648 List<Organization> suborganizations = 1649 organizationPersistence.findByC_P( 1650 organization.getCompanyId(), 1651 organization.getOrganizationId()); 1652 1653 addSuborganizations(allSuborganizations, suborganizations); 1654 } 1655 } 1656 } 1657 1658 protected long getParentOrganizationId( 1659 long companyId, long parentOrganizationId) 1660 throws SystemException { 1661 1662 if (parentOrganizationId != 1663 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { 1664 1665 // Ensure parent organization exists and belongs to the proper 1666 // company 1667 1668 Organization parentOrganization = 1669 organizationPersistence.fetchByPrimaryKey(parentOrganizationId); 1670 1671 if ((parentOrganization == null) || 1672 (companyId != parentOrganization.getCompanyId())) { 1673 1674 parentOrganizationId = 1675 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID; 1676 } 1677 } 1678 1679 return parentOrganizationId; 1680 } 1681 1682 protected List<Organization> getParentOrganizations( 1683 Organization organization, boolean lastOrganization) 1684 throws PortalException, SystemException { 1685 1686 List<Organization> organizations = new ArrayList<Organization>(); 1687 1688 if (!lastOrganization) { 1689 organizations.add(organization); 1690 } 1691 1692 long parentOrganizationId = organization.getParentOrganizationId(); 1693 1694 if (parentOrganizationId == 1695 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { 1696 1697 return organizations; 1698 } 1699 1700 Organization parentOrganization = 1701 organizationPersistence.findByPrimaryKey(parentOrganizationId); 1702 1703 List<Organization> parentOrganizatons = getParentOrganizations( 1704 parentOrganization, false); 1705 1706 organizations.addAll(parentOrganizatons); 1707 1708 return organizations; 1709 } 1710 1711 protected long[] getReindexOrganizationIds(Organization organization) 1712 throws PortalException, SystemException { 1713 1714 List<Organization> organizationsTree = new ArrayList<Organization>(); 1715 1716 organizationsTree.add(organization); 1717 1718 LinkedHashMap<String, Object> params = 1719 new LinkedHashMap<String, Object>(); 1720 1721 params.put("organizationsTree", organizationsTree); 1722 1723 List<Organization> organizations = search( 1724 organization.getCompanyId(), params, QueryUtil.ALL_POS, 1725 QueryUtil.ALL_POS); 1726 1727 long[] organizationIds = new long[organizations.size()]; 1728 1729 for (int i = 0; i < organizations.size(); i++) { 1730 Organization curOrganization = organizations.get(i); 1731 1732 String treePath = curOrganization.buildTreePath(); 1733 1734 curOrganization.setTreePath(treePath.toString()); 1735 1736 organizationPersistence.update(curOrganization, false); 1737 1738 organizationIds[i] = curOrganization.getOrganizationId(); 1739 } 1740 1741 if (!ArrayUtil.contains( 1742 organizationIds, organization.getOrganizationId())) { 1743 1744 organizationIds = ArrayUtil.append( 1745 organizationIds, organization.getOrganizationId()); 1746 } 1747 1748 return organizationIds; 1749 } 1750 1751 protected boolean isParentOrganization( 1752 long parentOrganizationId, long organizationId) 1753 throws PortalException, SystemException { 1754 1755 // Return true if parentOrganizationId is among the parent organizatons 1756 // of organizationId 1757 1758 Organization parentOrganization = 1759 organizationPersistence.findByPrimaryKey(parentOrganizationId); 1760 1761 List<Organization> parentOrganizations = getParentOrganizations( 1762 organizationId); 1763 1764 if (parentOrganizations.contains(parentOrganization)) { 1765 return true; 1766 } 1767 else { 1768 return false; 1769 } 1770 } 1771 1772 protected void validate( 1773 long companyId, long organizationId, long parentOrganizationId, 1774 String name, String type, long countryId, int statusId) 1775 throws PortalException, SystemException { 1776 1777 if (!ArrayUtil.contains(PropsValues.ORGANIZATIONS_TYPES, type)) { 1778 throw new OrganizationTypeException( 1779 "Invalid organization type " + type); 1780 } 1781 1782 if ((parentOrganizationId == 1783 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) { 1784 1785 if (!OrganizationImpl.isRootable(type)) { 1786 throw new OrganizationParentException( 1787 "Organization of type " + type + " cannot be a root"); 1788 } 1789 } 1790 else { 1791 Organization parentOrganization = 1792 organizationPersistence.fetchByPrimaryKey(parentOrganizationId); 1793 1794 if (parentOrganization == null) { 1795 throw new OrganizationParentException( 1796 "Organization " + parentOrganizationId + " doesn't exist"); 1797 } 1798 1799 String[] childrenTypes = OrganizationImpl.getChildrenTypes( 1800 parentOrganization.getType()); 1801 1802 if (childrenTypes.length == 0) { 1803 throw new OrganizationParentException( 1804 "Organization of type " + type + " cannot have children"); 1805 } 1806 1807 if ((companyId != parentOrganization.getCompanyId()) || 1808 (parentOrganizationId == organizationId)) { 1809 1810 throw new OrganizationParentException(); 1811 } 1812 1813 if (!ArrayUtil.contains(childrenTypes, type)) { 1814 throw new OrganizationParentException( 1815 "Type " + type + " not allowed as child of " + 1816 parentOrganization.getType()); 1817 } 1818 } 1819 1820 if ((organizationId > 0) && 1821 (parentOrganizationId != 1822 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) { 1823 1824 // Prevent circular organizational references 1825 1826 if (isParentOrganization(organizationId, parentOrganizationId)) { 1827 throw new OrganizationParentException(); 1828 } 1829 } 1830 1831 if (Validator.isNull(name)) { 1832 throw new OrganizationNameException(); 1833 } 1834 else { 1835 Organization organization = organizationPersistence.fetchByC_N( 1836 companyId, name); 1837 1838 if ((organization != null) && 1839 (organization.getName().equalsIgnoreCase(name))) { 1840 1841 if ((organizationId <= 0) || 1842 (organization.getOrganizationId() != organizationId)) { 1843 1844 throw new DuplicateOrganizationException(); 1845 } 1846 } 1847 } 1848 1849 boolean countryRequired = GetterUtil.getBoolean( 1850 PropsUtil.get( 1851 PropsKeys.ORGANIZATIONS_COUNTRY_REQUIRED, new Filter(type))); 1852 1853 if (countryRequired || (countryId > 0)) { 1854 countryPersistence.findByPrimaryKey(countryId); 1855 } 1856 1857 listTypeService.validate( 1858 statusId, ListTypeConstants.ORGANIZATION_STATUS); 1859 } 1860 1861 protected void validate( 1862 long companyId, long parentOrganizationId, String name, String type, 1863 long countryId, int statusId) 1864 throws PortalException, SystemException { 1865 1866 validate( 1867 companyId, 0, parentOrganizationId, name, type, countryId, 1868 statusId); 1869 } 1870 1871 }