1   /**
2    * Copyright (c) 2000-2009 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.dao.orm.QueryUtil;
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.RoleConstants;
42  import com.liferay.portal.model.User;
43  import com.liferay.portal.model.impl.ListTypeImpl;
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  
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     public Organization getOrganization(long organizationId)
242         throws PortalException, SystemException {
243 
244         return organizationPersistence.findByPrimaryKey(organizationId);
245     }
246 
247     public Organization getOrganization(long companyId, String name)
248         throws PortalException, SystemException {
249 
250         return organizationPersistence.findByC_N(companyId, name);
251     }
252 
253     public long getOrganizationId(long companyId, String name)
254         throws SystemException {
255 
256         Organization organization = organizationPersistence.fetchByC_N(
257             companyId, name);
258 
259         if (organization != null) {
260             return organization.getOrganizationId();
261         }
262         else {
263             return 0;
264         }
265     }
266 
267     public List<Organization> getOrganizations(long[] organizationIds)
268         throws PortalException, SystemException {
269 
270         List<Organization> organizations = new ArrayList<Organization>();
271 
272         for (int i = 0; i < organizationIds.length; i++) {
273             Organization organization = getOrganization(organizationIds[i]);
274 
275             organizations.add(organization);
276         }
277 
278         return organizations;
279     }
280 
281     public List<Organization> getParentOrganizations(long organizationId)
282         throws PortalException, SystemException {
283 
284         if (organizationId ==
285                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
286 
287             return new ArrayList<Organization>();
288         }
289 
290         Organization organization =
291             organizationPersistence.findByPrimaryKey(organizationId);
292 
293         return getParentOrganizations(organization, true);
294     }
295 
296     public List<Organization> getSuborganizations(
297             List<Organization> organizations)
298         throws SystemException {
299 
300         List<Organization> allSuborganizations = new ArrayList<Organization>();
301 
302         for (int i = 0; i < organizations.size(); i++) {
303             Organization organization = organizations.get(i);
304 
305             List<Organization> suborganizations =
306                 organizationPersistence.findByC_P(
307                     organization.getCompanyId(),
308                     organization.getOrganizationId());
309 
310             addSuborganizations(allSuborganizations, suborganizations);
311         }
312 
313         return allSuborganizations;
314     }
315 
316     public List<Organization> getSubsetOrganizations(
317         List<Organization> allOrganizations,
318         List<Organization> availableOrganizations) {
319 
320         List<Organization> subsetOrganizations = new ArrayList<Organization>();
321 
322         Iterator<Organization> itr = allOrganizations.iterator();
323 
324         while (itr.hasNext()) {
325             Organization organization = itr.next();
326 
327             if (availableOrganizations.contains(organization)) {
328                 subsetOrganizations.add(organization);
329             }
330         }
331 
332         return subsetOrganizations;
333     }
334 
335     public List<Organization> getUserOrganizations(long userId)
336         throws PortalException, SystemException {
337 
338         return getUserOrganizations(userId, false);
339     }
340 
341     public List<Organization> getUserOrganizations(
342             long userId, boolean inheritUserGroups)
343         throws PortalException, SystemException {
344 
345         return getUserOrganizations(
346             userId, inheritUserGroups, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
347     }
348 
349     public List<Organization> getUserOrganizations(
350             long userId, int start, int end)
351         throws PortalException, SystemException {
352 
353         return getUserOrganizations(userId, false, start, end);
354     }
355 
356     public List<Organization> getUserOrganizations(
357             long userId, boolean inheritUserGroups, int start, int end)
358         throws PortalException, SystemException {
359 
360         if (inheritUserGroups &&
361             PropsValues.ORGANIZATIONS_USER_GROUP_MEMBERSHIP_ENABLED) {
362 
363             User user = userPersistence.findByPrimaryKey(userId);
364 
365             LinkedHashMap<String, Object> organizationParams =
366                 new LinkedHashMap<String, Object>();
367 
368             organizationParams.put("usersOrgs", new Long(userId));
369 
370             return search(
371                 user.getCompanyId(),
372                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID, null,
373                 OrganizationConstants.ANY_TYPE, null, null, organizationParams,
374                 start, end);
375         }
376         else {
377             return userPersistence.getOrganizations(userId, start, end);
378         }
379     }
380 
381     public int getUserOrganizationsCount(long userId) throws SystemException {
382         return userPersistence.getOrganizationsSize(userId);
383     }
384 
385     public boolean hasGroupOrganization(long groupId, long organizationId)
386         throws SystemException {
387 
388         return groupPersistence.containsOrganization(groupId, organizationId);
389     }
390 
391     public boolean hasUserOrganization(long userId, long organizationId)
392         throws SystemException {
393 
394         return userPersistence.containsOrganization(userId, organizationId);
395     }
396 
397     public boolean hasUserOrganization(
398             long userId, long organizationId, boolean inheritUserGroups)
399         throws PortalException, SystemException {
400 
401         if (inheritUserGroups) {
402             if (organizationFinder.countByO_U(organizationId, userId) > 0) {
403                 return true;
404             }
405             else {
406                 return false;
407             }
408         }
409         else {
410             return userPersistence.containsOrganization(userId, organizationId);
411         }
412     }
413 
414     public boolean hasPasswordPolicyOrganization(
415             long passwordPolicyId, long organizationId)
416         throws SystemException {
417 
418         return passwordPolicyRelLocalService.hasPasswordPolicyRel(
419             passwordPolicyId, Organization.class.getName(), organizationId);
420     }
421 
422     public void rebuildTree(long companyId, boolean force)
423         throws SystemException {
424 
425         organizationPersistence.rebuildTree(companyId, force);
426     }
427 
428     public List<Organization> search(
429             long companyId, long parentOrganizationId, String keywords,
430             int type, Long regionId, Long countryId,
431             LinkedHashMap<String, Object> params,
432             int start, int end)
433         throws SystemException {
434 
435         return search(
436             companyId, parentOrganizationId, keywords, type, regionId,
437             countryId, params, start, end,
438             new OrganizationNameComparator(true));
439     }
440 
441     public List<Organization> search(
442             long companyId, long parentOrganizationId, String keywords,
443             int type, Long regionId, Long countryId,
444             LinkedHashMap<String, Object> params,
445             int start, int end, OrderByComparator obc)
446         throws SystemException {
447 
448         String parentOrganizationIdComparator = StringPool.EQUAL;
449 
450         if (parentOrganizationId ==
451                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
452 
453             parentOrganizationIdComparator = StringPool.NOT_EQUAL;
454         }
455 
456         return organizationFinder.findByKeywords(
457             companyId, parentOrganizationId, parentOrganizationIdComparator,
458             keywords, type, regionId, countryId, params, start, end,
459             obc);
460     }
461 
462     public List<Organization> search(
463             long companyId, long parentOrganizationId, String name, int type,
464             String street, String city, String zip,
465             Long regionId, Long countryId,
466             LinkedHashMap<String, Object> params, boolean andOperator,
467             int start, int end)
468         throws SystemException {
469 
470         return search(
471             companyId, parentOrganizationId, name, type, street, city, zip,
472             regionId, countryId, params, andOperator, start, end,
473             new OrganizationNameComparator(true));
474     }
475 
476     public List<Organization> search(
477             long companyId, long parentOrganizationId, String name, int type,
478             String street, String city, String zip,
479             Long regionId, Long countryId, LinkedHashMap<String, Object> params,
480             boolean andOperator, int start, int end, OrderByComparator obc)
481         throws SystemException {
482 
483         String parentOrganizationIdComparator = StringPool.EQUAL;
484 
485         if (parentOrganizationId ==
486                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
487 
488             parentOrganizationIdComparator = StringPool.NOT_EQUAL;
489         }
490 
491         return organizationFinder.findByC_PO_N_T_S_C_Z_R_C(
492             companyId, parentOrganizationId, parentOrganizationIdComparator,
493             name, type, street, city, zip, regionId, countryId, params,
494             andOperator, start, end, obc);
495     }
496 
497     public int searchCount(
498             long companyId, long parentOrganizationId, String keywords,
499             int type, Long regionId, Long countryId,
500             LinkedHashMap<String, Object> params)
501         throws SystemException {
502 
503         String parentOrganizationIdComparator = StringPool.EQUAL;
504 
505         if (parentOrganizationId ==
506                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
507 
508             parentOrganizationIdComparator = StringPool.NOT_EQUAL;
509         }
510 
511         return organizationFinder.countByKeywords(
512             companyId, parentOrganizationId, parentOrganizationIdComparator,
513             keywords, type, regionId, countryId, params);
514     }
515 
516     public int searchCount(
517             long companyId, long parentOrganizationId, String name, int type,
518             String street, String city, String zip,
519             Long regionId, Long countryId, LinkedHashMap<String, Object> params,
520             boolean andOperator)
521         throws SystemException {
522 
523         String parentOrganizationIdComparator = StringPool.EQUAL;
524 
525         if (parentOrganizationId ==
526                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
527 
528             parentOrganizationIdComparator = StringPool.NOT_EQUAL;
529         }
530 
531         return organizationFinder.countByC_PO_N_T_S_C_Z_R_C(
532             companyId, parentOrganizationId, parentOrganizationIdComparator,
533             name, type, street, city, zip, regionId, countryId, params,
534             andOperator);
535     }
536 
537     public void setGroupOrganizations(long groupId, long[] organizationIds)
538         throws SystemException {
539 
540         groupPersistence.setOrganizations(groupId, organizationIds);
541 
542         PermissionCacheUtil.clearCache();
543     }
544 
545     public void unsetGroupOrganizations(long groupId, long[] organizationIds)
546         throws SystemException {
547 
548         groupPersistence.removeOrganizations(groupId, organizationIds);
549 
550         PermissionCacheUtil.clearCache();
551     }
552 
553     public void unsetPasswordPolicyOrganizations(
554             long passwordPolicyId, long[] organizationIds)
555         throws SystemException {
556 
557         passwordPolicyRelLocalService.deletePasswordPolicyRels(
558             passwordPolicyId, Organization.class.getName(), organizationIds);
559     }
560 
561     public Organization updateOrganization(
562             long companyId, long organizationId, long parentOrganizationId,
563             String name, int type, boolean recursable, long regionId,
564             long countryId, int statusId, String comments)
565         throws PortalException, SystemException {
566 
567         parentOrganizationId = getParentOrganizationId(
568             companyId, parentOrganizationId);
569         recursable = true;
570 
571         validate(
572             companyId, organizationId, parentOrganizationId, name, type,
573             countryId, statusId);
574 
575         Organization organization = organizationPersistence.findByPrimaryKey(
576             organizationId);
577 
578         organization.setParentOrganizationId(parentOrganizationId);
579         organization.setName(name);
580 
581         if (type == OrganizationConstants.TYPE_LOCATION) {
582             organization.setLocation(true);
583         }
584         else {
585             organization.setLocation(false);
586         }
587 
588         organization.setRecursable(recursable);
589         organization.setRegionId(regionId);
590         organization.setCountryId(countryId);
591         organization.setStatusId(statusId);
592         organization.setComments(comments);
593 
594         organizationPersistence.update(organization, false);
595 
596         return organization;
597     }
598 
599     protected void addSuborganizations(
600             List<Organization> allSuborganizations,
601             List<Organization> organizations)
602         throws SystemException {
603 
604         for (Organization organization : organizations) {
605             if (!allSuborganizations.contains(organization)) {
606                 allSuborganizations.add(organization);
607 
608                 List<Organization> suborganizations =
609                     organizationPersistence.findByC_P(
610                         organization.getCompanyId(),
611                         organization.getOrganizationId());
612 
613                 addSuborganizations(allSuborganizations, suborganizations);
614             }
615         }
616     }
617 
618     protected long getParentOrganizationId(
619             long companyId, long parentOrganizationId)
620         throws SystemException {
621 
622         if (parentOrganizationId !=
623                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
624 
625             // Ensure parent organization exists and belongs to the proper
626             // company
627 
628             Organization parentOrganization =
629                 organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
630 
631             if ((parentOrganization == null) ||
632                 (companyId != parentOrganization.getCompanyId())) {
633 
634                 parentOrganizationId =
635                     OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;
636             }
637         }
638 
639         return parentOrganizationId;
640     }
641 
642     protected List<Organization> getParentOrganizations(
643             Organization organization, boolean lastOrganization)
644         throws PortalException, SystemException {
645 
646         List<Organization> organizations = new ArrayList<Organization>();
647 
648         if (!lastOrganization) {
649             organizations.add(organization);
650         }
651 
652         long parentOrganizationId = organization.getParentOrganizationId();
653 
654         if (parentOrganizationId ==
655                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
656 
657             return organizations;
658         }
659 
660         Organization parentOrganization =
661             organizationPersistence.findByPrimaryKey(parentOrganizationId);
662 
663         List<Organization> parentOrganizatons = getParentOrganizations(
664             parentOrganization, false);
665 
666         organizations.addAll(parentOrganizatons);
667 
668         return organizations;
669     }
670 
671     protected boolean isParentOrganization(
672             long parentOrganizationId, long organizationId)
673         throws PortalException, SystemException {
674 
675         // Return true if parentOrganizationId is among the parent organizatons
676         // of organizationId
677 
678         Organization parentOrganization =
679             organizationPersistence.findByPrimaryKey(
680                 parentOrganizationId);
681 
682         List<Organization> parentOrganizations = getParentOrganizations(
683             organizationId);
684 
685         if (parentOrganizations.contains(parentOrganization)) {
686             return true;
687         }
688         else {
689             return false;
690         }
691     }
692 
693     protected void validate(
694             long companyId, long parentOrganizationId, String name, int type,
695             long countryId, int statusId)
696         throws PortalException, SystemException {
697 
698         validate(
699             companyId, 0, parentOrganizationId, name, type, countryId,
700             statusId);
701     }
702 
703     protected void validate(
704             long companyId, long organizationId, long parentOrganizationId,
705             String name, int type, long countryId, int statusId)
706         throws PortalException, SystemException {
707 
708         if ((type == OrganizationConstants.TYPE_LOCATION) ||
709             (parentOrganizationId !=
710                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
711 
712             Organization parentOrganization =
713                 organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
714 
715             if ((parentOrganization == null) ||
716                 (companyId != parentOrganization.getCompanyId()) ||
717                 (parentOrganizationId == organizationId) ||
718                 (parentOrganization.isLocation())) {
719 
720                 throw new OrganizationParentException();
721             }
722         }
723 
724         if ((organizationId > 0) &&
725             (parentOrganizationId !=
726                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
727 
728             // Prevent circular organizational references
729 
730             if (isParentOrganization(organizationId, parentOrganizationId)) {
731                 throw new OrganizationParentException();
732             }
733         }
734 
735         if (Validator.isNull(name)) {
736             throw new OrganizationNameException();
737         }
738         else {
739             Organization organization = organizationPersistence.fetchByC_N(
740                 companyId, name);
741 
742             if ((organization != null) &&
743                 (organization.getName().equalsIgnoreCase(name))) {
744 
745                 if ((organizationId <= 0) ||
746                     (organization.getOrganizationId() != organizationId)) {
747 
748                     throw new DuplicateOrganizationException();
749                 }
750             }
751         }
752 
753         try {
754             if ((countryId > 0) || PropsValues.ORGANIZATIONS_COUNTRY_REQUIRED) {
755                 countryPersistence.findByPrimaryKey(countryId);
756             }
757 
758             listTypeService.validate(
759                 statusId, ListTypeImpl.ORGANIZATION_STATUS);
760         }
761         catch (RemoteException re) {
762             throw new SystemException(re);
763         }
764     }
765 
766 }