1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.communities.model;
16  
17  import com.liferay.portal.NoSuchGroupException;
18  import com.liferay.portal.PortalException;
19  import com.liferay.portal.SystemException;
20  import com.liferay.portal.kernel.log.Log;
21  import com.liferay.portal.kernel.log.LogFactoryUtil;
22  import com.liferay.portal.lar.PortletDataHandlerKeys;
23  import com.liferay.portal.lar.UserIdStrategy;
24  import com.liferay.portal.model.BaseModelListener;
25  import com.liferay.portal.model.Group;
26  import com.liferay.portal.model.GroupConstants;
27  import com.liferay.portal.model.LayoutSet;
28  import com.liferay.portal.service.GroupLocalServiceUtil;
29  import com.liferay.portal.service.LayoutLocalServiceUtil;
30  
31  import java.io.File;
32  
33  import java.util.LinkedHashMap;
34  import java.util.Map;
35  
36  /**
37   * <a href="CommunityTemplateModelListener.java.html"><b><i>View Source</i></b>
38   * </a>
39   *
40   * <p>
41   * A ModelListener that listens for creation of communities and attempts to
42   * prepopulate the community pages from a template community.
43   * </p>
44   *
45   * <p>
46   * The template community should be a private community to avoid unauthorized
47   * access. The templated pages are stored in the community's staging area to
48   * avoid users accidentally coming to this community.
49   * </p>
50   *
51   * <p>
52   * You may create a separate template for private, open, and protected
53   * communities. You may also create a default template that will apply if the
54   * open, private, and restricted templates are not defined. The template
55   * community names must be: DEFAULT_TEMPLATE, OPEN_TEMPLATE, PRIVATE_TEMPLATE,
56   * or RESTRICTED_TEMPLATE.
57   * </p>
58   *
59   * <p>
60   * A newly created community will have its layouts preconfigured based on its
61   * type. If community is public, templates pages from OPEN_TEMPLATE will be
62   * used. If community is restricted, template pages from RESTRICTED_TEMPLATE
63   * will be used. If community is private, template pages from PRIVATE_TEMPLATE
64   * will be used. If any of the above templates are not found, the
65   * DEFAULT_TEMPLATE will be used. If there are no templates, then nothing is
66   * done.
67   * </p>
68   *
69   * @author Michael C. Han
70   */
71  public class CommunityTemplateModelListener
72      extends BaseModelListener<LayoutSet> {
73  
74      public CommunityTemplateModelListener() {
75          _templateParameters = getTemplateParameters();
76      }
77  
78      public void onAfterCreate(LayoutSet layoutSet) {
79          File file = null;
80  
81          try {
82              Group group = GroupLocalServiceUtil.getGroup(
83                  layoutSet.getGroupId());
84  
85              if (!group.isCommunity() ||
86                  group.getName().contains(_TEMPLATE_POSTFIX)) {
87  
88                  return;
89              }
90  
91              Group templateGroup = getTemplateGroup(group);
92  
93              if (templateGroup == null) {
94                  return;
95              }
96  
97              Group templateStagingGroup = templateGroup.getStagingGroup();
98  
99              if (templateStagingGroup == null) {
100                 return;
101             }
102 
103             file = LayoutLocalServiceUtil.exportLayoutsAsFile(
104                 templateStagingGroup.getGroupId(), layoutSet.isPrivateLayout(),
105                 null, _templateParameters, null, null);
106 
107             LayoutLocalServiceUtil.importLayouts(
108                 group.getCreatorUserId(), group.getGroupId(),
109                 layoutSet.isPrivateLayout(), _templateParameters, file);
110         }
111         catch (Exception e) {
112             _log.error(
113                 "Unble to import layouts for group " + layoutSet.getGroupId(),
114                 e);
115         }
116         finally {
117             if (file != null) {
118                 file.delete();
119             }
120         }
121     }
122 
123     protected Group getTemplateGroup(Group group)
124         throws PortalException, SystemException {
125 
126         String templateCommunityName = null;
127 
128         int type = group.getType();
129 
130         if (type == GroupConstants.TYPE_COMMUNITY_OPEN) {
131             templateCommunityName = _OPEN_TEMPLATE_COMMUNITY_NAME;
132         }
133         else if (type == GroupConstants.TYPE_COMMUNITY_PRIVATE) {
134             templateCommunityName = _PRIVATE_TEMPLATE_COMMUNITY_NAME;
135         }
136         else if (type == GroupConstants.TYPE_COMMUNITY_RESTRICTED) {
137             templateCommunityName = _RESTRICTED_TEMPLATE_COMMUNITY_NAME;
138         }
139         else {
140             throw new IllegalArgumentException(
141                 "Invalid community type " + group.getType());
142         }
143 
144         Group templateGroup = null;
145 
146         try {
147             templateGroup = GroupLocalServiceUtil.getGroup(
148                 group.getCompanyId(), templateCommunityName);
149         }
150         catch (NoSuchGroupException nsge1) {
151             try {
152                 templateGroup = GroupLocalServiceUtil.getGroup(
153                     group.getCompanyId(), _DEFAULT_TEMPLATE_COMMUNITY_NAME);
154             }
155             catch (NoSuchGroupException nsge2) {
156             }
157         }
158 
159         return templateGroup;
160     }
161 
162     protected Map<String, String[]> getTemplateParameters() {
163         Map<String, String[]> parameterMap =
164             new LinkedHashMap<String, String[]>();
165 
166         parameterMap.put(
167             PortletDataHandlerKeys.DATA_STRATEGY,
168             new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
169         parameterMap.put(
170             PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
171             new String[] {Boolean.FALSE.toString()});
172         parameterMap.put(
173             PortletDataHandlerKeys.DELETE_PORTLET_DATA,
174             new String[] {Boolean.FALSE.toString()});
175         parameterMap.put(
176             PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
177             new String[] {
178                 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_NAME
179             });
180         parameterMap.put(
181             PortletDataHandlerKeys.PERMISSIONS,
182             new String[] {Boolean.TRUE.toString()});
183         parameterMap.put(
184             PortletDataHandlerKeys.PORTLET_DATA,
185             new String[] {Boolean.TRUE.toString()});
186         parameterMap.put(
187             PortletDataHandlerKeys.PORTLET_DATA_ALL,
188             new String[] {Boolean.TRUE.toString()});
189         parameterMap.put(
190             PortletDataHandlerKeys.PORTLET_SETUP,
191             new String[] {Boolean.TRUE.toString()});
192         parameterMap.put(
193             PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
194             new String[] {Boolean.TRUE.toString()});
195         parameterMap.put(
196             PortletDataHandlerKeys.PORTLETS_MERGE_MODE,
197             new String[] {
198                 PortletDataHandlerKeys.PORTLETS_MERGE_MODE_ADD_TO_BOTTOM
199             });
200         parameterMap.put(
201             PortletDataHandlerKeys.THEME,
202             new String[] {Boolean.FALSE.toString()});
203         parameterMap.put(
204             PortletDataHandlerKeys.USER_ID_STRATEGY,
205             new String[] {UserIdStrategy.CURRENT_USER_ID});
206         parameterMap.put(
207             PortletDataHandlerKeys.USER_PERMISSIONS,
208             new String[] {Boolean.FALSE.toString()});
209 
210         return parameterMap;
211     }
212 
213     private static final String _DEFAULT_TEMPLATE_COMMUNITY_NAME =
214         "DEFAULT_TEMPLATE";
215 
216     private static final String _OPEN_TEMPLATE_COMMUNITY_NAME =
217         "OPEN_TEMPLATE";
218 
219     private static final String _PRIVATE_TEMPLATE_COMMUNITY_NAME =
220         "PRIVATE_TEMPLATE";
221 
222     private static final String _RESTRICTED_TEMPLATE_COMMUNITY_NAME =
223         "RESTRICTED_TEMPLATE";
224 
225     private static final String _TEMPLATE_POSTFIX = "_TEMPLATE";
226 
227     private static Log _log = LogFactoryUtil.getLog(
228         CommunityTemplateModelListener.class);
229 
230     private Map<String, String[]> _templateParameters;
231 
232 }