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);
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 int getUserOrganizationsCount(long userId) throws SystemException {
365         return userPersistence.getOrganizationsSize(userId);
366     }
367 
368     public boolean hasGroupOrganization(long groupId, long organizationId)
369         throws SystemException {
370 
371         return groupPersistence.containsOrganization(groupId, organizationId);
372     }
373 
374     public boolean hasUserOrganization(long userId, long organizationId)
375         throws SystemException {
376 
377         return userPersistence.containsOrganization(userId, organizationId);
378     }
379 
380     public boolean hasPasswordPolicyOrganization(
381             long passwordPolicyId, long organizationId)
382         throws SystemException {
383 
384         return passwordPolicyRelLocalService.hasPasswordPolicyRel(
385             passwordPolicyId, Organization.class.getName(), organizationId);
386     }
387 
388     public List<Organization> search(
389             long companyId, long parentOrganizationId, String keywords,
390             int type, Long regionId, Long countryId,
391             LinkedHashMap<String, Object> params,
392             int start, int end)
393         throws SystemException {
394 
395         return search(
396             companyId, parentOrganizationId, keywords, type, regionId,
397             countryId, params, start, end,
398             new OrganizationNameComparator(true));
399     }
400 
401     public List<Organization> search(
402             long companyId, long parentOrganizationId, String keywords,
403             int type, Long regionId, Long countryId,
404             LinkedHashMap<String, Object> params,
405             int start, int end, OrderByComparator obc)
406         throws SystemException {
407 
408         String parentOrganizationComparator = StringPool.EQUAL;
409 
410         if (parentOrganizationId ==
411                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
412 
413             parentOrganizationComparator = StringPool.NOT_EQUAL;
414         }
415 
416         return organizationFinder.findByKeywords(
417             companyId, parentOrganizationId, parentOrganizationComparator,
418             keywords, type, regionId, countryId, params, start, end,
419             obc);
420     }
421 
422     public List<Organization> search(
423             long companyId, long parentOrganizationId, String name, int type,
424             String street, String city, String zip,
425             Long regionId, Long countryId,
426             LinkedHashMap<String, Object> params, boolean andOperator,
427             int start, int end)
428         throws SystemException {
429 
430         return search(
431             companyId, parentOrganizationId, name, type, street, city, zip,
432             regionId, countryId, params, andOperator, start, end,
433             new OrganizationNameComparator(true));
434     }
435 
436     public List<Organization> search(
437             long companyId, long parentOrganizationId, String name, int type,
438             String street, String city, String zip,
439             Long regionId, Long countryId, LinkedHashMap<String, Object> params,
440             boolean andOperator, int start, int end, OrderByComparator obc)
441         throws SystemException {
442 
443         String parentOrganizationComparator = StringPool.EQUAL;
444 
445         if (parentOrganizationId ==
446                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
447 
448             parentOrganizationComparator = StringPool.NOT_EQUAL;
449         }
450 
451         return organizationFinder.findByC_PO_N_T_S_C_Z_R_C(
452             companyId, parentOrganizationId, parentOrganizationComparator,
453             name, type, street, city, zip, regionId, countryId, params,
454             andOperator, start, end, obc);
455     }
456 
457     public int searchCount(
458             long companyId, long parentOrganizationId, String keywords,
459             int type, Long regionId, Long countryId,
460             LinkedHashMap<String, Object> params)
461         throws SystemException {
462 
463         String parentOrganizationComparator = StringPool.EQUAL;
464 
465         if (parentOrganizationId ==
466                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
467 
468             parentOrganizationComparator = StringPool.NOT_EQUAL;
469         }
470 
471         return organizationFinder.countByKeywords(
472             companyId, parentOrganizationId, parentOrganizationComparator,
473             keywords, type, regionId, countryId, params);
474     }
475 
476     public int searchCount(
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)
481         throws SystemException {
482 
483         String parentOrganizationComparator = StringPool.EQUAL;
484 
485         if (parentOrganizationId ==
486                 OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
487 
488             parentOrganizationComparator = StringPool.NOT_EQUAL;
489         }
490 
491         return organizationFinder.countByC_PO_N_T_S_C_Z_R_C(
492             companyId, parentOrganizationId, parentOrganizationComparator,
493             name, type, street, city, zip, regionId, countryId, params,
494             andOperator);
495     }
496 
497     public void setGroupOrganizations(long groupId, long[] organizationIds)
498         throws SystemException {
499 
500         groupPersistence.setOrganizations(groupId, organizationIds);
501 
502         PermissionCacheUtil.clearCache();
503     }
504 
505     public void unsetGroupOrganizations(long groupId, long[] organizationIds)
506         throws SystemException {
507 
508         groupPersistence.removeOrganizations(groupId, organizationIds);
509 
510         PermissionCacheUtil.clearCache();
511     }
512 
513     public void unsetPasswordPolicyOrganizations(
514             long passwordPolicyId, long[] organizationIds)
515         throws SystemException {
516 
517         passwordPolicyRelLocalService.deletePasswordPolicyRels(
518             passwordPolicyId, Organization.class.getName(), organizationIds);
519     }
520 
521     public Organization updateOrganization(
522             long companyId, long organizationId, long parentOrganizationId,
523             String name, int type, boolean recursable, long regionId,
524             long countryId, int statusId, String comments)
525         throws PortalException, SystemException {
526 
527         parentOrganizationId = getParentOrganizationId(
528             companyId, parentOrganizationId);
529         recursable = true;
530 
531         validate(
532             companyId, organizationId, parentOrganizationId, name, type,
533             countryId, statusId);
534 
535         Organization organization = organizationPersistence.findByPrimaryKey(
536             organizationId);
537 
538         organization.setParentOrganizationId(parentOrganizationId);
539         organization.setName(name);
540 
541         if (type == OrganizationConstants.TYPE_LOCATION) {
542             organization.setLocation(true);
543         }
544         else {
545             organization.setLocation(false);
546         }
547 
548         organization.setRecursable(recursable);
549         organization.setRegionId(regionId);
550         organization.setCountryId(countryId);
551         organization.setStatusId(statusId);
552         organization.setComments(comments);
553 
554         organizationPersistence.update(organization, false);
555 
556         return organization;
557     }
558 
559     protected void addSuborganizations(
560             List<Organization> allSuborganizations,
561             List<Organization> organizations)
562         throws SystemException {
563 
564         for (Organization organization : organizations) {
565             if (!allSuborganizations.contains(organization)) {
566                 allSuborganizations.add(organization);
567 
568                 List<Organization> suborganizations =
569                     organizationPersistence.findByC_P(
570                         organization.getCompanyId(),
571                         organization.getOrganizationId());
572 
573                 addSuborganizations(allSuborganizations, suborganizations);
574             }
575         }
576     }
577 
578     protected long getParentOrganizationId(
579             long companyId, long parentOrganizationId)
580         throws SystemException {
581 
582         if (parentOrganizationId !=
583                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
584 
585             // Ensure parent organization exists and belongs to the proper
586             // company
587 
588             Organization parentOrganization =
589                 organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
590 
591             if ((parentOrganization == null) ||
592                 (companyId != parentOrganization.getCompanyId())) {
593 
594                 parentOrganizationId =
595                     OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;
596             }
597         }
598 
599         return parentOrganizationId;
600     }
601 
602     protected List<Organization> getParentOrganizations(
603             Organization organization, boolean lastOrganization)
604         throws PortalException, SystemException {
605 
606         List<Organization> organizations = new ArrayList<Organization>();
607 
608         if (!lastOrganization) {
609             organizations.add(organization);
610         }
611 
612         long parentOrganizationId = organization.getParentOrganizationId();
613 
614         if (parentOrganizationId ==
615                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
616 
617             return organizations;
618         }
619 
620         Organization parentOrganization =
621             organizationPersistence.findByPrimaryKey(parentOrganizationId);
622 
623         List<Organization> parentOrganizatons = getParentOrganizations(
624             parentOrganization, false);
625 
626         organizations.addAll(parentOrganizatons);
627 
628         return organizations;
629     }
630 
631     protected boolean isParentOrganization(
632             long parentOrganizationId, long organizationId)
633         throws PortalException, SystemException {
634 
635         // Return true if parentOrganizationId is among the parent organizatons
636         // of organizationId
637 
638         Organization parentOrganization =
639             organizationPersistence.findByPrimaryKey(
640                 parentOrganizationId);
641 
642         List<Organization> parentOrganizations = getParentOrganizations(
643             organizationId);
644 
645         if (parentOrganizations.contains(parentOrganization)) {
646             return true;
647         }
648         else {
649             return false;
650         }
651     }
652 
653     protected void validate(
654             long companyId, long parentOrganizationId, String name, int type,
655             long countryId, int statusId)
656         throws PortalException, SystemException {
657 
658         validate(
659             companyId, 0, parentOrganizationId, name, type, countryId,
660             statusId);
661     }
662 
663     protected void validate(
664             long companyId, long organizationId, long parentOrganizationId,
665             String name, int type, long countryId, int statusId)
666         throws PortalException, SystemException {
667 
668         if ((type == OrganizationConstants.TYPE_LOCATION) ||
669             (parentOrganizationId !=
670                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
671 
672             Organization parentOrganization =
673                 organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
674 
675             if ((parentOrganization == null) ||
676                 (companyId != parentOrganization.getCompanyId()) ||
677                 (parentOrganizationId == organizationId) ||
678                 (parentOrganization.isLocation())) {
679 
680                 throw new OrganizationParentException();
681             }
682         }
683 
684         if ((organizationId > 0) &&
685             (parentOrganizationId !=
686                 OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
687 
688             // Prevent circular organizational references
689 
690             if (isParentOrganization(organizationId, parentOrganizationId)) {
691                 throw new OrganizationParentException();
692             }
693         }
694 
695         if (Validator.isNull(name)) {
696             throw new OrganizationNameException();
697         }
698         else {
699             Organization organization = organizationPersistence.fetchByC_N(
700                 companyId, name);
701 
702             if ((organization != null) &&
703                 (organization.getName().equalsIgnoreCase(name))) {
704 
705                 if ((organizationId <= 0) ||
706                     (organization.getOrganizationId() != organizationId)) {
707 
708                     throw new DuplicateOrganizationException();
709                 }
710             }
711         }
712 
713         try {
714             if ((countryId > 0) || PropsValues.ORGANIZATIONS_COUNTRY_REQUIRED) {
715                 countryPersistence.findByPrimaryKey(countryId);
716             }
717 
718             listTypeService.validate(
719                 statusId, ListTypeImpl.ORGANIZATION_STATUS);
720         }
721         catch (RemoteException re) {
722             throw new SystemException(re);
723         }
724     }
725 
726 }