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