1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
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.getType() == GroupConstants.TYPE_COMMUNITY_SYSTEM) ||
87                  group.getName().contains(_TEMPLATE_POSTFIX)) {
88  
89                  return;
90              }
91  
92              Group templateGroup = getTemplateGroup(group);
93  
94              if (templateGroup == null) {
95                  return;
96              }
97  
98              Group templateStagingGroup = templateGroup.getStagingGroup();
99  
100             if (templateStagingGroup == null) {
101                 return;
102             }
103 
104             file = LayoutLocalServiceUtil.exportLayoutsAsFile(
105                 templateStagingGroup.getGroupId(), layoutSet.isPrivateLayout(),
106                 null, _templateParameters, null, null);
107 
108             LayoutLocalServiceUtil.importLayouts(
109                 group.getCreatorUserId(), group.getGroupId(),
110                 layoutSet.isPrivateLayout(), _templateParameters, file);
111         }
112         catch (Exception e) {
113             _log.error(
114                 "Unble to import layouts for group " + layoutSet.getGroupId(),
115                 e);
116         }
117         finally {
118             if (file != null) {
119                 file.delete();
120             }
121         }
122     }
123 
124     protected Group getTemplateGroup(Group group)
125         throws PortalException, SystemException {
126 
127         String templateCommunityName = null;
128 
129         int type = group.getType();
130 
131         if (type == GroupConstants.TYPE_COMMUNITY_OPEN) {
132             templateCommunityName = _OPEN_TEMPLATE_COMMUNITY_NAME;
133         }
134         else if (type == GroupConstants.TYPE_COMMUNITY_PRIVATE) {
135             templateCommunityName = _PRIVATE_TEMPLATE_COMMUNITY_NAME;
136         }
137         else if (type == GroupConstants.TYPE_COMMUNITY_RESTRICTED) {
138             templateCommunityName = _RESTRICTED_TEMPLATE_COMMUNITY_NAME;
139         }
140         else {
141             throw new IllegalArgumentException(
142                 "Invalid community type " + group.getType());
143         }
144 
145         Group templateGroup = null;
146 
147         try {
148             templateGroup = GroupLocalServiceUtil.getGroup(
149                 group.getCompanyId(), templateCommunityName);
150         }
151         catch (NoSuchGroupException nsge1) {
152             try {
153                 templateGroup = GroupLocalServiceUtil.getGroup(
154                     group.getCompanyId(), _DEFAULT_TEMPLATE_COMMUNITY_NAME);
155             }
156             catch (NoSuchGroupException nsge2) {
157             }
158         }
159 
160         return templateGroup;
161     }
162 
163     protected Map<String, String[]> getTemplateParameters() {
164         Map<String, String[]> parameterMap =
165             new LinkedHashMap<String, String[]>();
166 
167         parameterMap.put(
168             PortletDataHandlerKeys.CATEGORIES,
169             new String[] {Boolean.TRUE.toString()});
170         parameterMap.put(
171             PortletDataHandlerKeys.DATA_STRATEGY,
172             new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
173         parameterMap.put(
174             PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
175             new String[] {Boolean.FALSE.toString()});
176         parameterMap.put(
177             PortletDataHandlerKeys.DELETE_PORTLET_DATA,
178             new String[] {Boolean.FALSE.toString()});
179         parameterMap.put(
180             PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
181             new String[] {
182                 PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_NAME
183             });
184         parameterMap.put(
185             PortletDataHandlerKeys.PERMISSIONS,
186             new String[] {Boolean.TRUE.toString()});
187         parameterMap.put(
188             PortletDataHandlerKeys.PORTLET_DATA,
189             new String[] {Boolean.TRUE.toString()});
190         parameterMap.put(
191             PortletDataHandlerKeys.PORTLET_DATA_ALL,
192             new String[] {Boolean.TRUE.toString()});
193         parameterMap.put(
194             PortletDataHandlerKeys.PORTLET_SETUP,
195             new String[] {Boolean.TRUE.toString()});
196         parameterMap.put(
197             PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
198             new String[] {Boolean.TRUE.toString()});
199         parameterMap.put(
200             PortletDataHandlerKeys.PORTLETS_MERGE_MODE,
201             new String[] {
202                 PortletDataHandlerKeys.PORTLETS_MERGE_MODE_ADD_TO_BOTTOM
203             });
204         parameterMap.put(
205             PortletDataHandlerKeys.THEME,
206             new String[] {Boolean.FALSE.toString()});
207         parameterMap.put(
208             PortletDataHandlerKeys.USER_ID_STRATEGY,
209             new String[] {UserIdStrategy.CURRENT_USER_ID});
210         parameterMap.put(
211             PortletDataHandlerKeys.USER_PERMISSIONS,
212             new String[] {Boolean.FALSE.toString()});
213 
214         return parameterMap;
215     }
216 
217     private static final String _DEFAULT_TEMPLATE_COMMUNITY_NAME =
218         "DEFAULT_TEMPLATE";
219 
220     private static final String _OPEN_TEMPLATE_COMMUNITY_NAME =
221         "OPEN_TEMPLATE";
222 
223     private static final String _PRIVATE_TEMPLATE_COMMUNITY_NAME =
224         "PRIVATE_TEMPLATE";
225 
226     private static final String _RESTRICTED_TEMPLATE_COMMUNITY_NAME =
227         "RESTRICTED_TEMPLATE";
228 
229     private static final String _TEMPLATE_POSTFIX = "_TEMPLATE";
230 
231     private static Log _log = LogFactoryUtil.getLog(
232         CommunityTemplateModelListener.class);
233 
234     private Map<String, String[]> _templateParameters;
235 
236 }