001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.portletdisplaytemplate.util;
016    
017    import com.liferay.portal.kernel.bean.ClassLoaderBeanHandler;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.portletdisplaytemplate.BasePortletDisplayTemplateHandler;
021    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
022    import com.liferay.portal.kernel.template.TemplateConstants;
023    import com.liferay.portal.kernel.template.TemplateHandler;
024    import com.liferay.portal.kernel.template.TemplateHandlerRegistryUtil;
025    import com.liferay.portal.kernel.template.TemplateVariableGroup;
026    import com.liferay.portal.kernel.util.ArrayUtil;
027    import com.liferay.portal.kernel.util.JavaConstants;
028    import com.liferay.portal.kernel.util.PropsKeys;
029    import com.liferay.portal.kernel.util.ProxyUtil;
030    import com.liferay.portal.kernel.util.Validator;
031    import com.liferay.portal.kernel.util.WebKeys;
032    import com.liferay.portal.model.Group;
033    import com.liferay.portal.service.GroupLocalServiceUtil;
034    import com.liferay.portal.templateparser.Transformer;
035    import com.liferay.portal.theme.ThemeDisplay;
036    import com.liferay.portal.util.PortletKeys;
037    import com.liferay.portlet.PortletURLUtil;
038    import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
039    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
040    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
041    import com.liferay.taglib.util.VelocityTaglib;
042    
043    import java.lang.reflect.InvocationHandler;
044    
045    import java.util.ArrayList;
046    import java.util.HashMap;
047    import java.util.LinkedHashMap;
048    import java.util.List;
049    import java.util.Locale;
050    import java.util.Map;
051    
052    import javax.portlet.PortletPreferences;
053    import javax.portlet.PortletURL;
054    import javax.portlet.RenderRequest;
055    import javax.portlet.RenderResponse;
056    
057    import javax.servlet.http.HttpServletRequest;
058    import javax.servlet.jsp.PageContext;
059    
060    /**
061     * @author Eduardo Garcia
062     * @author Juan Fern??ndez
063     * @author Brian Wing Shun Chan
064     */
065    @DoPrivileged
066    public class PortletDisplayTemplateImpl implements PortletDisplayTemplate {
067    
068            @Override
069            public DDMTemplate fetchDDMTemplate(long groupId, String displayStyle) {
070                    try {
071                            Group group = GroupLocalServiceUtil.getGroup(groupId);
072    
073                            Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
074                                    group.getCompanyId());
075    
076                            String uuid = getDDMTemplateUuid(displayStyle);
077    
078                            if (Validator.isNull(uuid)) {
079                                    return null;
080                            }
081    
082                            try {
083                                    return
084                                            DDMTemplateLocalServiceUtil.getDDMTemplateByUuidAndGroupId(
085                                                    uuid, groupId);
086                            }
087                            catch (NoSuchTemplateException nste) {
088                            }
089    
090                            try {
091                                    return
092                                            DDMTemplateLocalServiceUtil.getDDMTemplateByUuidAndGroupId(
093                                                    uuid, companyGroup.getGroupId());
094                            }
095                            catch (NoSuchTemplateException nste) {
096                            }
097                    }
098                    catch (Exception e) {
099                            if (_log.isWarnEnabled()) {
100                                    _log.warn(e, e);
101                            }
102                    }
103    
104                    return null;
105            }
106    
107            @Override
108            public long getDDMTemplateGroupId(long groupId) {
109                    try {
110                            Group group = GroupLocalServiceUtil.getGroup(groupId);
111    
112                            if (group.isLayout()) {
113                                    group = group.getParentGroup();
114                            }
115    
116                            if (group.isStagingGroup()) {
117                                    Group liveGroup = group.getLiveGroup();
118    
119                                    if (!liveGroup.isStagedPortlet(
120                                                    PortletKeys.PORTLET_DISPLAY_TEMPLATES)) {
121    
122                                            return liveGroup.getGroupId();
123                                    }
124                            }
125    
126                            return group.getGroupId();
127                    }
128                    catch (Exception e) {
129                            if (_log.isWarnEnabled()) {
130                                    _log.warn(e, e);
131                            }
132                    }
133    
134                    return groupId;
135            }
136    
137            @Override
138            public String getDDMTemplateUuid(String displayStyle) {
139                    if (!displayStyle.startsWith(DISPLAY_STYLE_PREFIX)) {
140                            return null;
141                    }
142    
143                    return displayStyle.substring(DISPLAY_STYLE_PREFIX.length());
144            }
145    
146            @Override
147            public long getPortletDisplayTemplateDDMTemplateId(
148                    long groupId, String displayStyle) {
149    
150                    long portletDisplayDDMTemplateId = 0;
151    
152                    long portletDisplayDDMTemplateGroupId = getDDMTemplateGroupId(groupId);
153    
154                    if (displayStyle.startsWith(DISPLAY_STYLE_PREFIX)) {
155                            DDMTemplate portletDisplayDDMTemplate = fetchDDMTemplate(
156                                    portletDisplayDDMTemplateGroupId, displayStyle);
157    
158                            if (portletDisplayDDMTemplate != null) {
159                                    portletDisplayDDMTemplateId =
160                                            portletDisplayDDMTemplate.getTemplateId();
161                            }
162                    }
163    
164                    return portletDisplayDDMTemplateId;
165            }
166    
167            @Override
168            public List<TemplateHandler> getPortletDisplayTemplateHandlers() {
169                    List<TemplateHandler> templateHandlers =
170                            TemplateHandlerRegistryUtil.getTemplateHandlers();
171    
172                    List<TemplateHandler> portletDisplayTemplateHandlers =
173                            new ArrayList<TemplateHandler>();
174    
175                    for (TemplateHandler templateHandler : templateHandlers) {
176                            if (templateHandler instanceof BasePortletDisplayTemplateHandler) {
177                                    portletDisplayTemplateHandlers.add(templateHandler);
178                            }
179                            else if (ProxyUtil.isProxyClass(templateHandler.getClass())) {
180                                    InvocationHandler invocationHandler =
181                                            ProxyUtil.getInvocationHandler(templateHandler);
182    
183                                    if (invocationHandler instanceof ClassLoaderBeanHandler) {
184                                            ClassLoaderBeanHandler classLoaderBeanHandler =
185                                                    (ClassLoaderBeanHandler)invocationHandler;
186    
187                                            Object bean = classLoaderBeanHandler.getBean();
188    
189                                            if (bean instanceof BasePortletDisplayTemplateHandler) {
190                                                    portletDisplayTemplateHandlers.add(templateHandler);
191                                            }
192                                    }
193                            }
194                    }
195    
196                    return portletDisplayTemplateHandlers;
197            }
198    
199            @Override
200            public Map<String, TemplateVariableGroup> getTemplateVariableGroups(
201                    String language) {
202    
203                    Map<String, TemplateVariableGroup> templateVariableGroups =
204                            new LinkedHashMap<String, TemplateVariableGroup>();
205    
206                    TemplateVariableGroup fieldsTemplateVariableGroup =
207                            new TemplateVariableGroup("fields");
208    
209                    fieldsTemplateVariableGroup.addCollectionVariable(
210                            "entries", List.class, PortletDisplayTemplateConstants.ENTRIES,
211                            "entries-item", null, "curEntry", null);
212                    fieldsTemplateVariableGroup.addVariable(
213                            "entry", null, PortletDisplayTemplateConstants.ENTRY);
214    
215                    templateVariableGroups.put("fields", fieldsTemplateVariableGroup);
216    
217                    TemplateVariableGroup generalVariablesTemplateVariableGroup =
218                            new TemplateVariableGroup("general-variables");
219    
220                    generalVariablesTemplateVariableGroup.addVariable(
221                            "current-url", String.class,
222                            PortletDisplayTemplateConstants.CURRENT_URL);
223                    generalVariablesTemplateVariableGroup.addVariable(
224                            "locale", Locale.class, PortletDisplayTemplateConstants.LOCALE);
225                    generalVariablesTemplateVariableGroup.addVariable(
226                            "portlet-preferences", Map.class,
227                            PortletDisplayTemplateConstants.PORTLET_PREFERENCES);
228                    generalVariablesTemplateVariableGroup.addVariable(
229                            "template-id", null, PortletDisplayTemplateConstants.TEMPLATE_ID);
230                    generalVariablesTemplateVariableGroup.addVariable(
231                            "theme-display", ThemeDisplay.class,
232                            PortletDisplayTemplateConstants.THEME_DISPLAY);
233    
234                    templateVariableGroups.put(
235                            "general-variables", generalVariablesTemplateVariableGroup);
236    
237                    TemplateVariableGroup utilTemplateVariableGroup =
238                            new TemplateVariableGroup("util");
239    
240                    utilTemplateVariableGroup.addVariable(
241                            "http-request", HttpServletRequest.class,
242                            PortletDisplayTemplateConstants.REQUEST);
243    
244                    if (language.equals(TemplateConstants.LANG_TYPE_VM)) {
245                            utilTemplateVariableGroup.addVariable(
246                                    "liferay-taglib", VelocityTaglib.class,
247                                    PortletDisplayTemplateConstants.TAGLIB_LIFERAY);
248                    }
249    
250                    utilTemplateVariableGroup.addVariable(
251                            "render-request", RenderRequest.class,
252                            PortletDisplayTemplateConstants.RENDER_REQUEST);
253                    utilTemplateVariableGroup.addVariable(
254                            "render-response", RenderResponse.class,
255                            PortletDisplayTemplateConstants.RENDER_RESPONSE);
256    
257                    templateVariableGroups.put("util", utilTemplateVariableGroup);
258    
259                    return templateVariableGroups;
260            }
261    
262            @Override
263            public String renderDDMTemplate(
264                            PageContext pageContext, long ddmTemplateId, List<?> entries)
265                    throws Exception {
266    
267                    Map<String, Object> contextObjects = new HashMap<String, Object>();
268    
269                    return renderDDMTemplate(
270                            pageContext, ddmTemplateId, entries, contextObjects);
271            }
272    
273            @Override
274            public String renderDDMTemplate(
275                            PageContext pageContext, long ddmTemplateId, List<?> entries,
276                            Map<String, Object> contextObjects)
277                    throws Exception {
278    
279                    contextObjects.put(
280                            PortletDisplayTemplateConstants.TEMPLATE_ID, ddmTemplateId);
281                    contextObjects.put(PortletDisplayTemplateConstants.ENTRIES, entries);
282    
283                    if (!entries.isEmpty()) {
284                            contextObjects.put(
285                                    PortletDisplayTemplateConstants.ENTRY, entries.get(0));
286                    }
287    
288                    HttpServletRequest request =
289                            (HttpServletRequest)pageContext.getRequest();
290    
291                    contextObjects.put(
292                            PortletDisplayTemplateConstants.LOCALE, request.getLocale());
293    
294                    contextObjects.put(PortletDisplayTemplateConstants.REQUEST, request);
295    
296                    RenderRequest renderRequest = (RenderRequest)request.getAttribute(
297                            JavaConstants.JAVAX_PORTLET_REQUEST);
298    
299                    contextObjects.put(
300                            PortletDisplayTemplateConstants.RENDER_REQUEST, renderRequest);
301    
302                    RenderResponse renderResponse = (RenderResponse)request.getAttribute(
303                            JavaConstants.JAVAX_PORTLET_RESPONSE);
304    
305                    contextObjects.put(
306                            PortletDisplayTemplateConstants.RENDER_RESPONSE, renderResponse);
307    
308                    PortletURL currentURL = PortletURLUtil.getCurrent(
309                            renderRequest, renderResponse);
310    
311                    contextObjects.put(
312                            PortletDisplayTemplateConstants.CURRENT_URL, currentURL.toString());
313    
314                    ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
315                            WebKeys.THEME_DISPLAY);
316    
317                    contextObjects.put(
318                            PortletDisplayTemplateConstants.THEME_DISPLAY, themeDisplay);
319    
320                    contextObjects.putAll(_getPortletPreferences(renderRequest));
321    
322                    DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
323                            ddmTemplateId);
324    
325                    contextObjects.put(
326                            TemplateConstants.CLASS_NAME_ID, ddmTemplate.getClassNameId());
327    
328                    return _transformer.transform(
329                            pageContext, themeDisplay, contextObjects, ddmTemplate.getScript(),
330                            ddmTemplate.getLanguage());
331            }
332    
333            private Map<String, Object> _getPortletPreferences(
334                    RenderRequest renderRequest) {
335    
336                    Map<String, Object> contextObjects = new HashMap<String, Object>();
337    
338                    PortletPreferences portletPreferences = renderRequest.getPreferences();
339    
340                    Map<String, String[]> map = portletPreferences.getMap();
341    
342                    contextObjects.put(
343                            PortletDisplayTemplateConstants.PORTLET_PREFERENCES, map);
344    
345                    for (Map.Entry<String, String[]> entry : map.entrySet()) {
346                            String[] values = entry.getValue();
347    
348                            if (ArrayUtil.isEmpty(values)) {
349                                    continue;
350                            }
351    
352                            String value = values[0];
353    
354                            if (value == null) {
355                                    continue;
356                            }
357    
358                            contextObjects.put(entry.getKey(), value);
359                    }
360    
361                    return contextObjects;
362            }
363    
364            private static Log _log = LogFactoryUtil.getLog(
365                    PortletDisplayTemplateImpl.class);
366    
367            private Transformer _transformer = new Transformer(
368                    PropsKeys.DYNAMIC_DATA_LISTS_ERROR_TEMPLATE, true);
369    
370    }