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