001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.portletdisplaytemplate.util;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.servlet.GenericServletWrapper;
020    import com.liferay.portal.kernel.servlet.PipingServletResponse;
021    import com.liferay.portal.kernel.staging.StagingConstants;
022    import com.liferay.portal.kernel.templateparser.Transformer;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.JavaConstants;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.kernel.util.WebKeys;
027    import com.liferay.portal.model.Group;
028    import com.liferay.portal.service.GroupLocalServiceUtil;
029    import com.liferay.portal.theme.ThemeDisplay;
030    import com.liferay.portal.util.PortletKeys;
031    import com.liferay.portlet.PortletURLUtil;
032    import com.liferay.portlet.dynamicdatalists.util.DDLTransformer;
033    import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
034    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
035    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
036    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
037    import com.liferay.taglib.util.VelocityTaglib;
038    import com.liferay.util.freemarker.FreeMarkerTaglibFactoryUtil;
039    
040    import freemarker.ext.servlet.HttpRequestHashModel;
041    import freemarker.ext.servlet.ServletContextHashModel;
042    
043    import freemarker.template.ObjectWrapper;
044    import freemarker.template.TemplateHashModel;
045    
046    import java.util.HashMap;
047    import java.util.List;
048    import java.util.Map;
049    
050    import javax.portlet.PortletPreferences;
051    import javax.portlet.PortletURL;
052    import javax.portlet.RenderRequest;
053    import javax.portlet.RenderResponse;
054    
055    import javax.servlet.GenericServlet;
056    import javax.servlet.Servlet;
057    import javax.servlet.ServletContext;
058    import javax.servlet.http.HttpServletRequest;
059    import javax.servlet.http.HttpServletResponse;
060    import javax.servlet.http.HttpSession;
061    import javax.servlet.jsp.PageContext;
062    
063    /**
064     * @author Eduardo Garcia
065     * @author Juan Fernández
066     * @author Brian Wing Shun Chan
067     */
068    public class PortletDisplayTemplateImpl implements PortletDisplayTemplate {
069    
070            public DDMTemplate fetchDDMTemplate(long groupId, String displayStyle) {
071                    try {
072                            Group group = GroupLocalServiceUtil.getGroup(groupId);
073    
074                            Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
075                                    group.getCompanyId());
076    
077                            if (!displayStyle.startsWith("ddmTemplate_")) {
078                                    return null;
079                            }
080    
081                            String uuid = displayStyle.substring(12);
082    
083                            if (Validator.isNull(uuid)) {
084                                    return null;
085                            }
086    
087                            try {
088                                    return
089                                            DDMTemplateLocalServiceUtil.getDDMTemplateByUuidAndGroupId(
090                                                    uuid, groupId);
091                            }
092                            catch (NoSuchTemplateException nste) {
093                            }
094    
095                            try {
096                                    return
097                                            DDMTemplateLocalServiceUtil.getDDMTemplateByUuidAndGroupId(
098                                                    uuid, companyGroup.getGroupId());
099                            }
100                            catch (NoSuchTemplateException nste) {
101                            }
102                    }
103                    catch (Exception e) {
104                            if (_log.isWarnEnabled()) {
105                                    _log.warn(e, e);
106                            }
107                    }
108    
109                    return null;
110            }
111    
112            public long getDDMTemplateGroupId(ThemeDisplay themeDisplay) {
113                    try {
114                            Group scopeGroup = themeDisplay.getScopeGroup();
115    
116                            if (scopeGroup.hasStagingGroup()) {
117                                    Group stagingGroup = GroupLocalServiceUtil.getStagingGroup(
118                                            scopeGroup.getGroupId());
119    
120                                    if (GetterUtil.getBoolean(
121                                                    scopeGroup.getTypeSettingsProperty(
122                                                            StagingConstants.STAGED_PORTLET +
123                                                                    PortletKeys.PORTLET_DISPLAY_TEMPLATES))) {
124    
125                                            return stagingGroup.getGroupId();
126                                    }
127                            }
128                            else if (scopeGroup.getLiveGroupId() > 0) {
129                                    Group liveGroup = scopeGroup.getLiveGroup();
130    
131                                    if (!GetterUtil.getBoolean(
132                                                    liveGroup.getTypeSettingsProperty(
133                                                            StagingConstants.STAGED_PORTLET +
134                                                                    PortletKeys.PORTLET_DISPLAY_TEMPLATES))) {
135    
136                                            return liveGroup.getGroupId();
137                                    }
138                            }
139                    }
140                    catch (Exception e) {
141                            if (_log.isWarnEnabled()) {
142                                    _log.warn(e, e);
143                            }
144                    }
145    
146                    return themeDisplay.getScopeGroupId();
147            }
148    
149            public long getPortletDisplayTemplateDDMTemplateId(
150                    ThemeDisplay themeDisplay, String displayStyle) {
151    
152                    long portletDisplayDDMTemplateId = 0;
153    
154                    long portletDisplayDDMTemplateGroupId = getDDMTemplateGroupId(
155                            themeDisplay);
156    
157                    if (displayStyle.startsWith("ddmTemplate_")) {
158                            DDMTemplate portletDisplayDDMTemplate = fetchDDMTemplate(
159                                    portletDisplayDDMTemplateGroupId, displayStyle);
160    
161                            if (portletDisplayDDMTemplate != null) {
162                                    portletDisplayDDMTemplateId =
163                                            portletDisplayDDMTemplate.getTemplateId();
164                            }
165                    }
166    
167                    return portletDisplayDDMTemplateId;
168            }
169    
170            public String renderDDMTemplate(
171                            PageContext pageContext, long ddmTemplateId, List<?> entries)
172                    throws Exception {
173    
174                    Map<String, Object> contextObjects = new HashMap<String, Object>();
175    
176                    return renderDDMTemplate(
177                            pageContext, ddmTemplateId, entries, contextObjects);
178            }
179    
180            public String renderDDMTemplate(
181                            PageContext pageContext, long ddmTemplateId, List<?> entries,
182                            Map<String, Object> contextObjects)
183                    throws Exception {
184    
185                    contextObjects.put(
186                            PortletDisplayTemplateConstants.DDM_TEMPLATE_ID, ddmTemplateId);
187                    contextObjects.put(PortletDisplayTemplateConstants.ENTRIES, entries);
188    
189                    if (entries.size() == 1) {
190                            contextObjects.put(
191                                    PortletDisplayTemplateConstants.ENTRY, entries.get(0));
192                    }
193    
194                    HttpServletRequest request =
195                            (HttpServletRequest)pageContext.getRequest();
196    
197                    contextObjects.put(
198                            PortletDisplayTemplateConstants.LOCALE, request.getLocale());
199    
200                    contextObjects.put(PortletDisplayTemplateConstants.REQUEST, request);
201    
202                    RenderRequest renderRequest = (RenderRequest)request.getAttribute(
203                            JavaConstants.JAVAX_PORTLET_REQUEST);
204    
205                    contextObjects.put(
206                            PortletDisplayTemplateConstants.RENDER_REQUEST, renderRequest);
207    
208                    RenderResponse renderResponse = (RenderResponse)request.getAttribute(
209                            JavaConstants.JAVAX_PORTLET_RESPONSE);
210    
211                    contextObjects.put(
212                            PortletDisplayTemplateConstants.RENDER_RESPONSE, renderResponse);
213    
214                    PortletURL currentURL = PortletURLUtil.getCurrent(
215                            renderRequest, renderResponse);
216    
217                    contextObjects.put(
218                            PortletDisplayTemplateConstants.CURRENT_URL, currentURL.toString());
219    
220                    ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
221                            WebKeys.THEME_DISPLAY);
222    
223                    contextObjects.put(
224                            PortletDisplayTemplateConstants.THEME_DISPLAY, themeDisplay);
225    
226                    // Taglibs
227    
228                    DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
229                            ddmTemplateId);
230    
231                    String language = ddmTemplate.getLanguage();
232    
233                    if (language.equals(DDMTemplateConstants.LANG_TYPE_FTL)) {
234                            _addTaglibSupportFTL(contextObjects, pageContext);
235                    }
236                    else if (language.equals(DDMTemplateConstants.LANG_TYPE_VM)) {
237                            _addTaglibSupportVM(contextObjects, pageContext);
238                    }
239    
240                    contextObjects.putAll(_getPortletPreferences(renderRequest));
241    
242                    return _transformer.transform(
243                            themeDisplay, contextObjects, ddmTemplate.getScript(), language);
244            }
245    
246            private void _addTaglibSupportFTL(
247                            Map<String, Object> contextObjects, PageContext pageContext)
248                    throws Exception {
249    
250                    // FreeMarker servlet application
251    
252                    final Servlet servlet = (Servlet)pageContext.getPage();
253    
254                    GenericServlet genericServlet = null;
255    
256                    if (servlet instanceof GenericServlet) {
257                            genericServlet = (GenericServlet)servlet;
258                    }
259                    else {
260                            genericServlet = new GenericServletWrapper(servlet);
261    
262                            genericServlet.init(pageContext.getServletConfig());
263                    }
264    
265                    ServletContextHashModel servletContextHashModel =
266                            new ServletContextHashModel(
267                                    genericServlet, ObjectWrapper.DEFAULT_WRAPPER);
268    
269                    contextObjects.put(
270                            PortletDisplayTemplateConstants.FREEMARKER_SERVLET_APPLICATION,
271                            servletContextHashModel);
272    
273                    // FreeMarker servlet request
274    
275                    HttpServletRequest request =
276                            (HttpServletRequest)pageContext.getRequest();
277                    HttpServletResponse response =
278                            (HttpServletResponse)pageContext.getResponse();
279    
280                    HttpRequestHashModel requestHashModel = new HttpRequestHashModel(
281                            request, response, ObjectWrapper.DEFAULT_WRAPPER);
282    
283                    contextObjects.put(
284                            PortletDisplayTemplateConstants.FREEMARKER_SERVLET_REQUEST,
285                            requestHashModel);
286    
287                    // Taglib Liferay hash
288    
289                    TemplateHashModel taglibLiferayHash =
290                            FreeMarkerTaglibFactoryUtil.createTaglibFactory(
291                                    pageContext.getServletContext());
292    
293                    contextObjects.put(
294                            PortletDisplayTemplateConstants.TAGLIB_LIFERAY_HASH,
295                            taglibLiferayHash);
296            }
297    
298            private void _addTaglibSupportVM(
299                    Map<String, Object> contextObjects, PageContext pageContext) {
300    
301                    contextObjects.put(
302                            PortletDisplayTemplateConstants.TAGLIB_LIFERAY,
303                            _getVelocityTaglib(pageContext));
304            }
305    
306            private Map<String, Object> _getPortletPreferences(
307                    RenderRequest renderRequest) {
308    
309                    Map<String, Object> contextObjects = new HashMap<String, Object>();
310    
311                    PortletPreferences portletPreferences = renderRequest.getPreferences();
312    
313                    Map<String, String[]> map = portletPreferences.getMap();
314    
315                    for (Map.Entry<String, String[]> entry : map.entrySet()) {
316                            String[] values = entry.getValue();
317    
318                            if ((values == null) || (values.length == 0)) {
319                                    continue;
320                            }
321    
322                            String value = values[0];
323    
324                            if (value == null) {
325                                    continue;
326                            }
327    
328                            contextObjects.put(entry.getKey(), value);
329                    }
330    
331                    return contextObjects;
332            }
333    
334            private VelocityTaglib _getVelocityTaglib(PageContext pageContext) {
335                    HttpServletRequest request =
336                            (HttpServletRequest)pageContext.getRequest();
337    
338                    HttpSession session = request.getSession();
339    
340                    ServletContext servletContext = session.getServletContext();
341    
342                    HttpServletResponse response =
343                            (HttpServletResponse)pageContext.getResponse();
344    
345                    VelocityTaglib velocityTaglib = new VelocityTaglib(
346                            servletContext, request,
347                            new PipingServletResponse(response, pageContext.getOut()),
348                            pageContext, null);
349    
350                    return velocityTaglib;
351            }
352    
353            private static Log _log = LogFactoryUtil.getLog(
354                    PortletDisplayTemplateImpl.class);
355    
356            private Transformer _transformer = new DDLTransformer();
357    
358    }