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