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