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