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 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 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         if ((userLocalService.getOrganizationUsersCount(
171                 organization.getOrganizationId(), true) > 0) ||
172             (organizationPersistence.countByC_P(
173                 organization.getCompanyId(),
174                 organization.getOrganizationId()) > 0)) {
175 
176             throw new RequiredOrganizationException();
177         }
178 
179         // Addresses
180 
181         addressLocalService.deleteAddresses(
182             organization.getCompanyId(), Organization.class.getName(),
183             organization.getOrganizationId());
184 
185         // Email addresses
186 
187         emailAddressLocalService.deleteEmailAddresses(
188             organization.getCompanyId(), Organization.class.getName(),
189             organization.getOrganizationId());
190 
191         // Password policy relation
192 
193         passwordPolicyRelLocalService.deletePasswordPolicyRel(
194             Organization.class.getName(), organization.getOrganizationId());
195 
196         // Phone
197 
198         phoneLocalService.deletePhones(
199             organization.getCompanyId(), Organization.class.getName(),
200             organization.getOrganizationId());
201 
202         // Website
203 
204         websiteLocalService.deleteWebsites(
205             organization.getCompanyId(), Organization.class.getName(),
206             organization.getOrganizationId());
207 
208         // Group
209 
210         Group group = organization.getGroup();
211 
212         groupLocalService.deleteGroup(group);
213 
214         // Resources
215 
216         String name = Organization.class.getName();
217 
218         if (organization.isLocation()) {
219             name = Location.class.getName();
220         }
221 
222         resourceLocalService.deleteResource(
223             organization.getCompanyId(), name,
224             ResourceConstants.SCOPE_INDIVIDUAL,
225             organization.getOrganizationId());
226 
227         // Organization
228 
229         organizationPersistence.remove(organization);
230 
231         // Permission cache
232 
233         PermissionCacheUtil.clearCache();
234     }
235 
236     public List<Organization> getGroupOrganizations(long groupId)
237         throws SystemException {
238 
239         return groupPersistence.getOrganizations(groupId);
240     }
241 
242     /**
243      * Gets a list of organizations that a user has access to administrate. This
244      * includes organizations that a user belongs to and all suborganizations of
245      * those organizations.
246      *
247      * @param       userId the user id of the user
248      * @return      a list of organizations
249      */
250     public List<Organization> getManageableOrganizations(long userId)
251         throws SystemException {
252 
253         List<Organization> manageableOrganizations =
254             new UniqueList<Organization>();
255 
256         List<Organization> userOrganizations = userPersistence.getOrganizations(
257             userId);
258 
259         manageableOrganizations.addAll(userOrganizations);
260         manageableOrganizations.addAll(getSuborganizations(userOrganizations));
261 
262         return manageableOrganizations;
263     }
264 
265     public Organization getOrganization(long organizationId)
266         throws PortalException, SystemException {
267 
268         return organizationPersistence.findByPrimaryKey(organizationId);
269     }
270 
271     public Organization getOrganization(long companyId, String name)
272         throws PortalException, SystemException {
273 
274         return organizationPersistence.findByC_N(companyId, name);
275     }
276 
277     public long getOrganizationId(long companyId, String name)
278         throws SystemException {
279 
280         try {
281             Organization organization = organizationPersistence.findByC_N(
282                 companyId, name);
283 
284             return organization.getOrganizationId();
285         }
286         catch (NoSuchOrganizationException nsoge) {
287             return 0;
288         }
289     }
290 
291     public List<Organization> getOrganizations(long[] organizationIds)
292         throws PortalException, SystemException {
293 
294         List<Organization> organizations = new ArrayList<Organization>();
295 
296         for (int i = 0; i < organizationIds.length; i++) {
297             Organization organization = getOrganization(organizationIds[i]);
298 
299             organizations.add(organization);
300         }
301 
302         return organizations;
303     }
304 
305     public List<Organization> getParentOrganizations(long organizationId)
306         throws PortalException, SystemException {
307 
308         if (organizationId ==
309                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
310 
311             return new ArrayList<Organization>();
312         }
313 
314         Organization organization =
315             organizationPersistence.findByPrimaryKey(organizationId);
316 
317         return getParentOrganizations(organization, true);
318     }
319 
320     public List<Organization> getSuborganizations(
321             List<Organization> organizations)
322         throws SystemException {
323 
324         List<Organization> allSuborganizations = new ArrayList<Organization>();
325 
326         for (int i = 0; i < organizations.size(); i++) {
327             Organization organization = organizations.get(i);
328 
329             List<Organization> suborganizations =
330                 organizationPersistence.findByC_P(
331                     organization.getCompanyId(),
332                     organization.getOrganizationId());
333 
334             addSuborganizations(allSuborganizations, suborganizations);
335         }
336 
337         return allSuborganizations;
338     }
339 
340     public List<Organization> getSubsetOrganizations(
341         List<Organization> allOrganizations,
342         List<Organization> availableOrganizations) {
343 
344         List<Organization> subsetOrganizations = new ArrayList<Organization>();
345 
346         Iterator<Organization> itr = allOrganizations.iterator();
347 
348         while (itr.hasNext()) {
349             Organization organization = itr.next();
350 
351             if (availableOrganizations.contains(organization)) {
352                 subsetOrganizations.add(organization);
353             }
354         }
355 
356         return subsetOrganizations;
357     }
358 
359     public List<Organization> getUserOrganizations(long userId)
360         throws SystemException {
361 
362         return userPersistence.getOrganizations(userId);
363     }
364 
365     public int getUserOrganizationsCount(long userId) throws SystemException {
366         return userPersistence.getOrganizationsSize(userId);
367     }
368 
369     public boolean hasGroupOrganization(long groupId, long organizationId)
370         throws SystemException {
371 
372         return groupPersistence.containsOrganization(groupId, organizationId);
373     }
374 
375     public boolean hasUserOrganization(long userId, long organizationId)
376         throws SystemException {
377 
378         return userPersistence.containsOrganization(userId, organizationId);
379     }
380 
381     public boolean hasPasswordPolicyOrganization(
382             long passwordPolicyId, long organizationId)
383         throws SystemException {
384 
385         return passwordPolicyRelLocalService.hasPasswordPolicyRel(
386             passwordPolicyId, Organization.class.getName(), organizationId);
387     }
388 
389     public List<Organization> search(
390             long companyId, long parentOrganizationId, String keywords,
391             int type, Long regionId, Long countryId,
392             LinkedHashMap<String, Object> params,
393             int start, int end)
394         throws SystemException {
395 
396         return search(
397             companyId, parentOrganizationId, keywords, type, regionId,
398             countryId, params, start, end,
399             new OrganizationNameComparator(true));
400     }
401 
402     public List<Organization> search(
403             long companyId, long parentOrganizationId, String keywords,
404             int type, Long regionId, Long countryId,
405             LinkedHashMap<String, Object> params,
406             int start, int end, OrderByComparator obc)
407         throws SystemException {
408 
409         String parentOrganizationComparator = StringPool.EQUAL;
410 
411         if (parentOrganizationId ==
412                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
413 
414             parentOrganizationComparator = StringPool.NOT_EQUAL;
415         }
416 
417         return organizationFinder.findByKeywords(
418             companyId, parentOrganizationId, parentOrganizationComparator,
419             keywords, type, regionId, countryId, params, start, end,
420             obc);
421     }
422 
423     public List<Organization> search(
424             long companyId, long parentOrganizationId, String name, int type,
425             String street, String city, String zip,
426             Long regionId, Long countryId,
427             LinkedHashMap<String, Object> params, boolean andOperator,
428             int start, int end)
429         throws SystemException {
430 
431         return search(
432             companyId, parentOrganizationId, name, type, street, city, zip,
433             regionId, countryId, params, andOperator, start, end,
434             new OrganizationNameComparator(true));
435     }
436 
437     public List<Organization> search(
438             long companyId, long parentOrganizationId, String name, int type,
439             String street, String city, String zip,
440             Long regionId, Long countryId, LinkedHashMap<String, Object> params,
441             boolean andOperator, int start, int end, OrderByComparator obc)
442         throws SystemException {
443 
444         String parentOrganizationComparator = StringPool.EQUAL;
445 
446         if (parentOrganizationId ==
447                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
448 
449             parentOrganizationComparator = StringPool.NOT_EQUAL;
450         }
451 
452         return organizationFinder.findByC_PO_N_T_S_C_Z_R_C(
453             companyId, parentOrganizationId, parentOrganizationComparator,
454             name, type, street, city, zip, regionId, countryId, params,
455             andOperator, start, end, obc);
456     }
457 
458     public int searchCount(
459             long companyId, long parentOrganizationId, String keywords,
460             int type, Long regionId, Long countryId,
461             LinkedHashMap<String, Object> params)
462         throws SystemException {
463 
464         String parentOrganizationComparator = StringPool.EQUAL;
465 
466         if (parentOrganizationId ==
467                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
468 
469             parentOrganizationComparator = StringPool.NOT_EQUAL;
470         }
471 
472         return organizationFinder.countByKeywords(
473             companyId, parentOrganizationId, parentOrganizationComparator,
474             keywords, type, regionId, countryId, params);
475     }
476 
477     public int searchCount(
478             long companyId, long parentOrganizationId, String name, int type,
479             String street, String city, String zip,
480             Long regionId, Long countryId, LinkedHashMap<String, Object> params,
481             boolean andOperator)
482         throws SystemException {
483 
484         String parentOrganizationComparator = StringPool.EQUAL;
485 
486         if (parentOrganizationId ==
487                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
488 
489             parentOrganizationComparator = StringPool.NOT_EQUAL;
490         }
491 
492         return organizationFinder.countByC_PO_N_T_S_C_Z_R_C(
493             companyId, parentOrganizationId, parentOrganizationComparator,
494             name, type, street, city, zip, regionId, countryId, params,
495             andOperator);
496     }
497 
498     public void setGroupOrganizations(long groupId, long[] organizationIds)
499         throws SystemException {
500 
501         groupPersistence.setOrganizations(groupId, organizationIds);
502 
503         PermissionCacheUtil.clearCache();
504     }
505 
506     public void unsetGroupOrganizations(long groupId, long[] organizationIds)
507         throws SystemException {
508 
509         groupPersistence.removeOrganizations(groupId, organizationIds);
510 
511         PermissionCacheUtil.clearCache();
512     }
513 
514     public void unsetPasswordPolicyOrganizations(
515             long passwordPolicyId, long[] organizationIds)
516         throws SystemException {
517 
518         passwordPolicyRelLocalService.deletePasswordPolicyRels(
519             passwordPolicyId, Organization.class.getName(), organizationIds);
520     }
521 
522     public Organization updateOrganization(
523             long companyId, long organizationId, long parentOrganizationId,
524             String name, int type, boolean recursable, long regionId,
525             long countryId, int statusId, String comments)
526         throws PortalException, SystemException {
527 
528         parentOrganizationId = getParentOrganizationId(
529             companyId, parentOrganizationId);
530         recursable = true;
531 
532         validate(
533             companyId, organizationId, parentOrganizationId, name, type,
534             countryId, statusId);
535 
536         Organization organization = organizationPersistence.findByPrimaryKey(
537             organizationId);
538 
539         organization.setParentOrganizationId(parentOrganizationId);
540         organization.setName(name);
541 
542         if (type == OrganizationConstants.TYPE_LOCATION) {
543             organization.setLocation(true);
544         }
545         else {
546             organization.setLocation(false);
547         }
548 
549         organization.setRecursable(recursable);
550         organization.setRegionId(regionId);
551         organization.setCountryId(countryId);
552         organization.setStatusId(statusId);
553         organization.setComments(comments);
554 
555         organizationPersistence.update(organization, false);
556 
557         return organization;
558     }
559 
560     protected void addSuborganizations(
561             List<Organization> allSuborganizations,
562             List<Organization> organizations)
563         throws SystemException {
564 
565         for (Organization organization : organizations) {
566             if (!allSuborganizations.contains(organization)) {
567                 allSuborganizations.add(organization);
568 
569                 List<Organization> suborganizations =
570                     organizationPersistence.findByC_P(
571                         organization.getCompanyId(),
572                         organization.getOrganizationId());
573 
574                 addSuborganizations(allSuborganizations, suborganizations);
575             }
576         }
577     }
578 
579     protected long getParentOrganizationId(
580             long companyId, long parentOrganizationId)
581         throws SystemException {
582 
583         if (parentOrganizationId !=
584                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
585 
586             // Ensure parent organization exists and belongs to the proper
587             // company
588 
589             try {
590                 Organization parentOrganization =
591                     organizationPersistence.findByPrimaryKey(
592                         parentOrganizationId);
593 
594                 if (companyId != parentOrganization.getCompanyId()) {
595                     parentOrganizationId =
596                         OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;
597                 }
598             }
599             catch (NoSuchOrganizationException nsoe) {
600                 parentOrganizationId =
601                     OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;
602             }
603         }
604 
605         return parentOrganizationId;
606     }
607 
608     protected List<Organization> getParentOrganizations(
609             Organization organization, boolean lastOrganization)
610         throws PortalException, SystemException {
611 
612         List<Organization> organizations = new ArrayList<Organization>();
613 
614         if (!lastOrganization) {
615             organizations.add(organization);
616         }
617 
618         long parentOrganizationId = organization.getParentOrganizationId();
619 
620         if (parentOrganizationId ==
621                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
622 
623             return organizations;
624         }
625 
626         Organization parentOrganization =
627             organizationPersistence.findByPrimaryKey(parentOrganizationId);
628 
629         List<Organization> parentOrganizatons = getParentOrganizations(
630             parentOrganization, false);
631 
632         organizations.addAll(parentOrganizatons);
633 
634         return organizations;
635     }
636 
637     protected boolean isParentOrganization(
638             long parentOrganizationId, long organizationId)
639         throws PortalException, SystemException {
640 
641         // Return true if parentOrganizationId is among the parent organizatons
642         // of organizationId
643 
644         Organization parentOrganization =
645             organizationPersistence.findByPrimaryKey(
646                 parentOrganizationId);
647 
648         List<Organization> parentOrganizations = getParentOrganizations(
649             organizationId);
650 
651         if (parentOrganizations.contains(parentOrganization)) {
652             return true;
653         }
654         else {
655             return false;
656         }
657     }
658 
659     protected void validate(
660             long companyId, long parentOrganizationId, String name, int type,
661             long countryId, int statusId)
662         throws PortalException, SystemException {
663 
664         validate(
665             companyId, 0, parentOrganizationId, name, type, countryId,
666             statusId);
667     }
668 
669     protected void validate(
670             long companyId, long organizationId, long parentOrganizationId,
671             String name, int type, long countryId, int statusId)
672         throws PortalException, SystemException {
673 
674         if ((type == OrganizationConstants.TYPE_LOCATION) ||
675             (parentOrganizationId !=
676                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
677 
678             try {
679                 Organization parentOrganization =
680                     organizationPersistence.findByPrimaryKey(
681                         parentOrganizationId);
682 
683                 if ((companyId != parentOrganization.getCompanyId()) ||
684                     (parentOrganizationId == organizationId) ||
685                     (parentOrganization.isLocation())) {
686 
687                     throw new OrganizationParentException();
688                 }
689             }
690             catch (NoSuchOrganizationException nsoe) {
691                 throw new OrganizationParentException();
692             }
693         }
694 
695         if ((organizationId > 0) &&
696             (parentOrganizationId !=
697                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
698 
699             // Prevent circular organizational references
700 
701             if (isParentOrganization(organizationId, parentOrganizationId)) {
702                 throw new OrganizationParentException();
703             }
704         }
705 
706         if (Validator.isNull(name)) {
707             throw new OrganizationNameException();
708         }
709         else {
710             try {
711                 Organization organization = organizationPersistence.findByC_N(
712                     companyId, name);
713 
714                 if (organization.getName().equalsIgnoreCase(name)) {
715                     if ((organizationId <= 0) ||
716                         (organization.getOrganizationId() != organizationId)) {
717 
718                         throw new DuplicateOrganizationException();
719                     }
720                 }
721             }
722             catch (NoSuchOrganizationException nsoe) {
723             }
724         }
725 
726         try {
727             if ((countryId > 0) || PropsValues.ORGANIZATIONS_COUNTRY_REQUIRED) {
728                 countryPersistence.findByPrimaryKey(countryId);
729             }
730 
731             listTypeService.validate(
732                 statusId, ListTypeImpl.ORGANIZATION_STATUS);
733         }
734         catch (RemoteException re) {
735             throw new SystemException(re);
736         }
737     }
738 
739 }