1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.service.impl;
24  
25  import com.liferay.portal.DuplicateOrganizationException;
26  import com.liferay.portal.NoSuchOrganizationException;
27  import com.liferay.portal.OrganizationNameException;
28  import com.liferay.portal.OrganizationParentException;
29  import com.liferay.portal.PortalException;
30  import com.liferay.portal.RequiredOrganizationException;
31  import com.liferay.portal.SystemException;
32  import com.liferay.portal.kernel.util.OrderByComparator;
33  import com.liferay.portal.kernel.util.StringPool;
34  import com.liferay.portal.kernel.util.Validator;
35  import com.liferay.portal.model.Group;
36  import com.liferay.portal.model.Location;
37  import com.liferay.portal.model.Organization;
38  import com.liferay.portal.model.OrganizationConstants;
39  import com.liferay.portal.model.ResourceConstants;
40  import com.liferay.portal.model.Role;
41  import com.liferay.portal.model.User;
42  import com.liferay.portal.model.impl.ListTypeImpl;
43  import com.liferay.portal.model.impl.RoleImpl;
44  import com.liferay.portal.security.permission.PermissionCacheUtil;
45  import com.liferay.portal.service.base.OrganizationLocalServiceBaseImpl;
46  import com.liferay.portal.util.PropsValues;
47  import com.liferay.portal.util.comparator.OrganizationNameComparator;
48  import com.liferay.util.UniqueList;
49  
50  import java.rmi.RemoteException;
51  
52  import java.util.ArrayList;
53  import java.util.Iterator;
54  import java.util.LinkedHashMap;
55  import java.util.List;
56  
57  /**
58   * <a href="OrganizationLocalServiceImpl.java.html"><b><i>View Source</i></b>
59   * </a>
60   *
61   * @author Brian Wing Shun Chan
62   * @author Jorge Ferrer
63   *
64   */
65  public class OrganizationLocalServiceImpl
66      extends OrganizationLocalServiceBaseImpl {
67  
68      public void addGroupOrganizations(long groupId, long[] organizationIds)
69          throws PortalException, SystemException {
70  
71          groupPersistence.addOrganizations(groupId, organizationIds);
72  
73          PermissionCacheUtil.clearCache();
74      }
75  
76      public Organization addOrganization(
77              long userId, long parentOrganizationId, String name,
78              int type, boolean recursable, long regionId, long countryId,
79              int statusId, String comments)
80          throws PortalException, SystemException {
81  
82          // Organization
83  
84          User user = userPersistence.findByPrimaryKey(userId);
85          parentOrganizationId = getParentOrganizationId(
86              user.getCompanyId(), parentOrganizationId);
87          recursable = true;
88  
89          validate(
90              user.getCompanyId(), parentOrganizationId, name, type, countryId,
91              statusId);
92  
93          long organizationId = counterLocalService.increment();
94  
95          Organization organization = organizationPersistence.create(
96              organizationId);
97  
98          organization.setCompanyId(user.getCompanyId());
99          organization.setParentOrganizationId(parentOrganizationId);
100         organization.setName(name);
101 
102         if (type == OrganizationConstants.TYPE_LOCATION) {
103             organization.setLocation(true);
104         }
105         else {
106             organization.setLocation(false);
107         }
108 
109         organization.setRecursable(recursable);
110         organization.setRegionId(regionId);
111         organization.setCountryId(countryId);
112         organization.setStatusId(statusId);
113         organization.setComments(comments);
114 
115         organizationPersistence.update(organization, false);
116 
117         // Group
118 
119         Group group = groupLocalService.addGroup(
120             userId, Organization.class.getName(), organizationId, null, null, 0,
121             null, true);
122 
123         // Role
124 
125         Role role = roleLocalService.getRole(
126             organization.getCompanyId(), RoleImpl.ORGANIZATION_OWNER);
127 
128         userGroupRoleLocalService.addUserGroupRoles(
129             userId, group.getGroupId(), new long[] {role.getRoleId()});
130 
131         // User
132 
133         userPersistence.addOrganization(userId, organizationId);
134 
135         // Resources
136 
137         addOrganizationResources(userId, organization);
138 
139         return organization;
140     }
141 
142     public void addOrganizationResources(long userId, Organization organization)
143         throws PortalException, SystemException {
144 
145         String name = Organization.class.getName();
146 
147         if (organization.isLocation()) {
148             name = Location.class.getName();
149         }
150 
151         resourceLocalService.addResources(
152             organization.getCompanyId(), 0, userId, name,
153             organization.getOrganizationId(), false, false, false);
154     }
155 
156     public void addPasswordPolicyOrganizations(
157             long passwordPolicyId, long[] organizationIds)
158         throws PortalException, SystemException {
159 
160         passwordPolicyRelLocalService.addPasswordPolicyRels(
161             passwordPolicyId, Organization.class.getName(), organizationIds);
162     }
163 
164     public void deleteOrganization(long organizationId)
165         throws PortalException, SystemException {
166 
167         Organization organization = organizationPersistence.findByPrimaryKey(
168             organizationId);
169 
170         deleteOrganization(organization);
171     }
172 
173     public void deleteOrganization(Organization organization)
174         throws PortalException, SystemException {
175 
176         if ((userLocalService.getOrganizationUsersCount(
177                 organization.getOrganizationId(), true) > 0) ||
178             (organizationPersistence.countByC_P(
179                 organization.getCompanyId(),
180                 organization.getOrganizationId()) > 0)) {
181 
182             throw new RequiredOrganizationException();
183         }
184 
185         // Addresses
186 
187         addressLocalService.deleteAddresses(
188             organization.getCompanyId(), Organization.class.getName(),
189             organization.getOrganizationId());
190 
191         // Email addresses
192 
193         emailAddressLocalService.deleteEmailAddresses(
194             organization.getCompanyId(), Organization.class.getName(),
195             organization.getOrganizationId());
196 
197         // Password policy relation
198 
199         passwordPolicyRelLocalService.deletePasswordPolicyRel(
200             Organization.class.getName(), organization.getOrganizationId());
201 
202         // Phone
203 
204         phoneLocalService.deletePhones(
205             organization.getCompanyId(), Organization.class.getName(),
206             organization.getOrganizationId());
207 
208         // Website
209 
210         websiteLocalService.deleteWebsites(
211             organization.getCompanyId(), Organization.class.getName(),
212             organization.getOrganizationId());
213 
214         // Group
215 
216         Group group = organization.getGroup();
217 
218         groupLocalService.deleteGroup(group.getGroupId());
219 
220         // Resources
221 
222         String name = Organization.class.getName();
223 
224         if (organization.isLocation()) {
225             name = Location.class.getName();
226         }
227 
228         resourceLocalService.deleteResource(
229             organization.getCompanyId(), name,
230             ResourceConstants.SCOPE_INDIVIDUAL,
231             organization.getOrganizationId());
232 
233         // Organization
234 
235         organizationPersistence.remove(organization.getOrganizationId());
236 
237         // Permission cache
238 
239         PermissionCacheUtil.clearCache();
240     }
241 
242     public List<Organization> getGroupOrganizations(long groupId)
243         throws PortalException, SystemException {
244 
245         return groupPersistence.getOrganizations(groupId);
246     }
247 
248     /**
249      * Gets a list of organizations that a user has access to administrate. This
250      * includes organizations that a user belongs to and all suborganizations of
251      * those organizations.
252      *
253      * @param       userId the user id of the user
254      * @return      a list of organizations
255      */
256     public List<Organization> getManageableOrganizations(long userId)
257         throws PortalException, SystemException {
258 
259         List<Organization> manageableOrganizations =
260             new UniqueList<Organization>();
261 
262         List<Organization> userOrganizations = userPersistence.getOrganizations(
263             userId);
264 
265         manageableOrganizations.addAll(userOrganizations);
266         manageableOrganizations.addAll(getSuborganizations(userOrganizations));
267 
268         return manageableOrganizations;
269     }
270 
271     public Organization getOrganization(long organizationId)
272         throws PortalException, SystemException {
273 
274         return organizationPersistence.findByPrimaryKey(organizationId);
275     }
276 
277     public Organization getOrganization(long companyId, String name)
278         throws PortalException, SystemException {
279 
280         return organizationPersistence.findByC_N(companyId, name);
281     }
282 
283     public long getOrganizationId(long companyId, String name)
284         throws PortalException, SystemException {
285 
286         try {
287             Organization organization = organizationPersistence.findByC_N(
288                 companyId, name);
289 
290             return organization.getOrganizationId();
291         }
292         catch (NoSuchOrganizationException nsoge) {
293             return 0;
294         }
295     }
296 
297     public List<Organization> getOrganizations(long[] organizationIds)
298         throws PortalException, SystemException {
299 
300         List<Organization> organizations = new ArrayList<Organization>();
301 
302         for (int i = 0; i < organizationIds.length; i++) {
303             Organization organization = getOrganization(organizationIds[i]);
304 
305             organizations.add(organization);
306         }
307 
308         return organizations;
309     }
310 
311     public List<Organization> getParentOrganizations(long organizationId)
312         throws PortalException, SystemException {
313 
314         if (organizationId ==
315                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
316 
317             return new ArrayList<Organization>();
318         }
319 
320         Organization organization =
321             organizationPersistence.findByPrimaryKey(organizationId);
322 
323         return getParentOrganizations(organization, true);
324     }
325 
326     public List<Organization> getSuborganizations(
327             List<Organization> organizations)
328         throws SystemException {
329 
330         List<Organization> allSuborganizations = new ArrayList<Organization>();
331 
332         for (int i = 0; i < organizations.size(); i++) {
333             Organization organization = organizations.get(i);
334 
335             List<Organization> suborganizations =
336                 organizationPersistence.findByC_P(
337                     organization.getCompanyId(),
338                     organization.getOrganizationId());
339 
340             addSuborganizations(allSuborganizations, suborganizations);
341         }
342 
343         return allSuborganizations;
344     }
345 
346     public List<Organization> getSubsetOrganizations(
347             List<Organization> allOrganizations,
348             List<Organization> availableOrganizations)
349         throws PortalException, SystemException {
350 
351         List<Organization> subsetOrganizations = new ArrayList<Organization>();
352 
353         Iterator<Organization> itr = allOrganizations.iterator();
354 
355         while (itr.hasNext()) {
356             Organization organization = itr.next();
357 
358             if (availableOrganizations.contains(organization)) {
359                 subsetOrganizations.add(organization);
360             }
361         }
362 
363         return subsetOrganizations;
364     }
365 
366     public List<Organization> getUserOrganizations(long userId)
367         throws PortalException, SystemException {
368 
369         return userPersistence.getOrganizations(userId);
370     }
371 
372     public int getUserOrganizationsCount(long userId)
373         throws PortalException, SystemException {
374 
375         return userPersistence.getOrganizationsSize(userId);
376     }
377 
378     public boolean hasGroupOrganization(long groupId, long organizationId)
379         throws PortalException, SystemException {
380 
381         return groupPersistence.containsOrganization(groupId, organizationId);
382     }
383 
384     public boolean hasUserOrganization(long userId, long organizationId)
385         throws PortalException, SystemException {
386 
387         return userPersistence.containsOrganization(userId, organizationId);
388     }
389 
390     public boolean hasPasswordPolicyOrganization(
391             long passwordPolicyId, long organizationId)
392         throws PortalException, SystemException {
393 
394         return passwordPolicyRelLocalService.hasPasswordPolicyRel(
395             passwordPolicyId, Organization.class.getName(), organizationId);
396     }
397 
398     public List<Organization> search(
399             long companyId, long parentOrganizationId, String keywords,
400             int type, Long regionId, Long countryId,
401             LinkedHashMap<String, Object> params,
402             int begin, int end)
403         throws PortalException, SystemException {
404 
405         return search(
406             companyId, parentOrganizationId, keywords, type, regionId,
407             countryId, params, begin, end,
408             new OrganizationNameComparator(true));
409     }
410 
411     public List<Organization> search(
412             long companyId, long parentOrganizationId, String keywords,
413             int type, Long regionId, Long countryId,
414             LinkedHashMap<String, Object> params,
415             int begin, int end, OrderByComparator obc)
416         throws PortalException, SystemException {
417 
418         String parentOrganizationComparator = StringPool.EQUAL;
419 
420         if (parentOrganizationId ==
421                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
422 
423             parentOrganizationComparator = StringPool.NOT_EQUAL;
424         }
425 
426         return organizationFinder.findByKeywords(
427             companyId, parentOrganizationId, parentOrganizationComparator,
428             keywords, type, regionId, countryId, params, begin, end,
429             obc);
430     }
431 
432     public List<Organization> search(
433             long companyId, long parentOrganizationId, String name, int type,
434             String street, String city, String zip,
435             Long regionId, Long countryId,
436             LinkedHashMap<String, Object> params, boolean andOperator,
437             int begin, int end)
438         throws PortalException, SystemException {
439 
440         return search(
441             companyId, parentOrganizationId, name, type, street, city, zip,
442             regionId, countryId, params, andOperator, begin, end,
443             new OrganizationNameComparator(true));
444     }
445 
446     public List<Organization> search(
447             long companyId, long parentOrganizationId, String name, int type,
448             String street, String city, String zip,
449             Long regionId, Long countryId, LinkedHashMap<String, Object> params,
450             boolean andOperator, int begin, int end, OrderByComparator obc)
451         throws PortalException, SystemException {
452 
453         String parentOrganizationComparator = StringPool.EQUAL;
454 
455         if (parentOrganizationId ==
456                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
457 
458             parentOrganizationComparator = StringPool.NOT_EQUAL;
459         }
460 
461         return organizationFinder.findByC_PO_N_T_S_C_Z_R_C(
462             companyId, parentOrganizationId, parentOrganizationComparator,
463             name, type, street, city, zip, regionId, countryId, params,
464             andOperator, begin, end, obc);
465     }
466 
467     public int searchCount(
468             long companyId, long parentOrganizationId, String keywords,
469             int type, Long regionId, Long countryId,
470             LinkedHashMap<String, Object> params)
471         throws PortalException, SystemException {
472 
473         String parentOrganizationComparator = StringPool.EQUAL;
474 
475         if (parentOrganizationId ==
476                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
477 
478             parentOrganizationComparator = StringPool.NOT_EQUAL;
479         }
480 
481         return organizationFinder.countByKeywords(
482             companyId, parentOrganizationId, parentOrganizationComparator,
483             keywords, type, regionId, countryId, params);
484     }
485 
486     public int searchCount(
487             long companyId, long parentOrganizationId, String name, int type,
488             String street, String city, String zip,
489             Long regionId, Long countryId, LinkedHashMap<String, Object> params,
490             boolean andOperator)
491         throws PortalException, SystemException {
492 
493         String parentOrganizationComparator = StringPool.EQUAL;
494 
495         if (parentOrganizationId ==
496                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
497 
498             parentOrganizationComparator = StringPool.NOT_EQUAL;
499         }
500 
501         return organizationFinder.countByC_PO_N_T_S_C_Z_R_C(
502             companyId, parentOrganizationId, parentOrganizationComparator,
503             name, type, street, city, zip, regionId, countryId, params,
504             andOperator);
505     }
506 
507     public void setGroupOrganizations(long groupId, long[] organizationIds)
508         throws PortalException, SystemException {
509 
510         groupPersistence.setOrganizations(groupId, organizationIds);
511 
512         PermissionCacheUtil.clearCache();
513     }
514 
515     public void unsetGroupOrganizations(long groupId, long[] organizationIds)
516         throws PortalException, SystemException {
517 
518         groupPersistence.removeOrganizations(groupId, organizationIds);
519 
520         PermissionCacheUtil.clearCache();
521     }
522 
523     public void unsetPasswordPolicyOrganizations(
524             long passwordPolicyId, long[] organizationIds)
525         throws PortalException, SystemException {
526 
527         passwordPolicyRelLocalService.deletePasswordPolicyRels(
528             passwordPolicyId, Organization.class.getName(), organizationIds);
529     }
530 
531     public Organization updateOrganization(
532             long companyId, long organizationId, long parentOrganizationId,
533             String name, int type, boolean recursable, long regionId,
534             long countryId, int statusId, String comments)
535         throws PortalException, SystemException {
536 
537         parentOrganizationId = getParentOrganizationId(
538             companyId, parentOrganizationId);
539         recursable = true;
540 
541         validate(
542             companyId, organizationId, parentOrganizationId, name, type,
543             countryId, statusId);
544 
545         Organization organization = organizationPersistence.findByPrimaryKey(
546             organizationId);
547 
548         organization.setParentOrganizationId(parentOrganizationId);
549         organization.setName(name);
550 
551         if (type == OrganizationConstants.TYPE_LOCATION) {
552             organization.setLocation(true);
553         }
554         else {
555             organization.setLocation(false);
556         }
557 
558         organization.setRecursable(recursable);
559         organization.setRegionId(regionId);
560         organization.setCountryId(countryId);
561         organization.setStatusId(statusId);
562         organization.setComments(comments);
563 
564         organizationPersistence.update(organization, false);
565 
566         return organization;
567     }
568 
569     protected void addSuborganizations(
570             List<Organization> allSuborganizations,
571             List<Organization> organizations)
572         throws SystemException {
573 
574         for (Organization organization : organizations) {
575             if (!allSuborganizations.contains(organization)) {
576                 allSuborganizations.add(organization);
577 
578                 List<Organization> suborganizations =
579                     organizationPersistence.findByC_P(
580                         organization.getCompanyId(),
581                         organization.getOrganizationId());
582 
583                 addSuborganizations(allSuborganizations, suborganizations);
584             }
585         }
586     }
587 
588     protected long getParentOrganizationId(
589             long companyId, long parentOrganizationId)
590         throws PortalException, SystemException {
591 
592         if (parentOrganizationId !=
593                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
594 
595             // Ensure parent organization exists and belongs to the proper
596             // company
597 
598             try {
599                 Organization parentOrganization =
600                     organizationPersistence.findByPrimaryKey(
601                         parentOrganizationId);
602 
603                 if (companyId != parentOrganization.getCompanyId()) {
604                     parentOrganizationId =
605                         OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;
606                 }
607             }
608             catch (NoSuchOrganizationException nsoe) {
609                 parentOrganizationId =
610                     OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;
611             }
612         }
613 
614         return parentOrganizationId;
615     }
616 
617     protected List<Organization> getParentOrganizations(
618             Organization organization, boolean lastOrganization)
619         throws PortalException, SystemException {
620 
621         List<Organization> organizations = new ArrayList<Organization>();
622 
623         if (!lastOrganization) {
624             organizations.add(organization);
625         }
626 
627         long parentOrganizationId = organization.getParentOrganizationId();
628 
629         if (parentOrganizationId ==
630                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
631 
632             return organizations;
633         }
634 
635         Organization parentOrganization =
636             organizationPersistence.findByPrimaryKey(parentOrganizationId);
637 
638         List<Organization> parentOrganizatons = getParentOrganizations(
639             parentOrganization, false);
640 
641         organizations.addAll(parentOrganizatons);
642 
643         return organizations;
644     }
645 
646     protected boolean isParentOrganization(
647             long parentOrganizationId, long organizationId)
648         throws PortalException, SystemException {
649 
650         // Return true if parentOrganizationId is among the parent organizatons
651         // of organizationId
652 
653         Organization parentOrganization =
654             organizationPersistence.findByPrimaryKey(
655                 parentOrganizationId);
656 
657         List<Organization> parentOrganizations = getParentOrganizations(
658             organizationId);
659 
660         if (parentOrganizations.contains(parentOrganization)) {
661             return true;
662         }
663         else {
664             return false;
665         }
666     }
667 
668     protected void validate(
669             long companyId, long parentOrganizationId, String name, int type,
670             long countryId, int statusId)
671         throws PortalException, SystemException {
672 
673         validate(
674             companyId, 0, parentOrganizationId, name, type, countryId,
675             statusId);
676     }
677 
678     protected void validate(
679             long companyId, long organizationId, long parentOrganizationId,
680             String name, int type, long countryId, int statusId)
681         throws PortalException, SystemException {
682 
683         if ((type == OrganizationConstants.TYPE_LOCATION) ||
684             (parentOrganizationId !=
685                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
686 
687             try {
688                 Organization parentOrganization =
689                     organizationPersistence.findByPrimaryKey(
690                         parentOrganizationId);
691 
692                 if ((companyId != parentOrganization.getCompanyId()) ||
693                     (parentOrganizationId == organizationId) ||
694                     (parentOrganization.isLocation())) {
695 
696                     throw new OrganizationParentException();
697                 }
698             }
699             catch (NoSuchOrganizationException nsoe) {
700                 throw new OrganizationParentException();
701             }
702         }
703 
704         if ((organizationId > 0) &&
705             (parentOrganizationId !=
706                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
707 
708             // Prevent circular organizational references
709 
710             if (isParentOrganization(organizationId, parentOrganizationId)) {
711                 throw new OrganizationParentException();
712             }
713         }
714 
715         if (Validator.isNull(name)) {
716             throw new OrganizationNameException();
717         }
718         else {
719             try {
720                 Organization organization = organizationPersistence.findByC_N(
721                     companyId, name);
722 
723                 if (organization.getName().equalsIgnoreCase(name)) {
724                     if ((organizationId <= 0) ||
725                         (organization.getOrganizationId() != organizationId)) {
726 
727                         throw new DuplicateOrganizationException();
728                     }
729                 }
730             }
731             catch (NoSuchOrganizationException nsoe) {
732             }
733         }
734 
735         try {
736             if ((countryId > 0) || PropsValues.ORGANIZATIONS_COUNTRY_REQUIRED) {
737                 countryPersistence.findByPrimaryKey(countryId);
738             }
739 
740             listTypeService.validate(
741                 statusId, ListTypeImpl.ORGANIZATION_STATUS);
742         }
743         catch (RemoteException re) {
744             throw new SystemException(re);
745         }
746     }
747 
748 }