001
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.servlet.GenericServletWrapper;
023 import com.liferay.portal.kernel.servlet.PipingServletResponse;
024 import com.liferay.portal.kernel.template.TemplateConstants;
025 import com.liferay.portal.kernel.template.TemplateHandler;
026 import com.liferay.portal.kernel.template.TemplateHandlerRegistryUtil;
027 import com.liferay.portal.kernel.template.TemplateVariableGroup;
028 import com.liferay.portal.kernel.util.ArrayUtil;
029 import com.liferay.portal.kernel.util.JavaConstants;
030 import com.liferay.portal.kernel.util.PropsKeys;
031 import com.liferay.portal.kernel.util.ProxyUtil;
032 import com.liferay.portal.kernel.util.Validator;
033 import com.liferay.portal.kernel.util.WebKeys;
034 import com.liferay.portal.model.Group;
035 import com.liferay.portal.service.GroupLocalServiceUtil;
036 import com.liferay.portal.templateparser.Transformer;
037 import com.liferay.portal.theme.ThemeDisplay;
038 import com.liferay.portal.util.PortletKeys;
039 import com.liferay.portlet.PortletURLUtil;
040 import com.liferay.portlet.dynamicdatamapping.NoSuchTemplateException;
041 import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
042 import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
043 import com.liferay.taglib.util.VelocityTaglib;
044 import com.liferay.taglib.util.VelocityTaglibImpl;
045 import com.liferay.util.freemarker.FreeMarkerTaglibFactoryUtil;
046
047 import freemarker.ext.servlet.HttpRequestHashModel;
048 import freemarker.ext.servlet.ServletContextHashModel;
049
050 import freemarker.template.ObjectWrapper;
051 import freemarker.template.TemplateHashModel;
052
053 import java.lang.reflect.InvocationHandler;
054
055 import java.util.ArrayList;
056 import java.util.HashMap;
057 import java.util.LinkedHashMap;
058 import java.util.List;
059 import java.util.Locale;
060 import java.util.Map;
061
062 import javax.portlet.PortletPreferences;
063 import javax.portlet.PortletURL;
064 import javax.portlet.RenderRequest;
065 import javax.portlet.RenderResponse;
066
067 import javax.servlet.GenericServlet;
068 import javax.servlet.Servlet;
069 import javax.servlet.ServletContext;
070 import javax.servlet.http.HttpServletRequest;
071 import javax.servlet.http.HttpServletResponse;
072 import javax.servlet.http.HttpSession;
073 import javax.servlet.jsp.PageContext;
074
075
080 @DoPrivileged
081 public class PortletDisplayTemplateImpl implements PortletDisplayTemplate {
082
083 @Override
084 public DDMTemplate fetchDDMTemplate(long groupId, String displayStyle) {
085 try {
086 Group group = GroupLocalServiceUtil.getGroup(groupId);
087
088 Group companyGroup = GroupLocalServiceUtil.getCompanyGroup(
089 group.getCompanyId());
090
091 String uuid = getDDMTemplateUuid(displayStyle);
092
093 if (Validator.isNull(uuid)) {
094 return null;
095 }
096
097 try {
098 return
099 DDMTemplateLocalServiceUtil.getDDMTemplateByUuidAndGroupId(
100 uuid, groupId);
101 }
102 catch (NoSuchTemplateException nste) {
103 }
104
105 try {
106 return
107 DDMTemplateLocalServiceUtil.getDDMTemplateByUuidAndGroupId(
108 uuid, companyGroup.getGroupId());
109 }
110 catch (NoSuchTemplateException nste) {
111 }
112 }
113 catch (Exception e) {
114 if (_log.isWarnEnabled()) {
115 _log.warn(e, e);
116 }
117 }
118
119 return null;
120 }
121
122 @Override
123 public long getDDMTemplateGroupId(long groupId) {
124 try {
125 Group group = GroupLocalServiceUtil.getGroup(groupId);
126
127 if (group.isLayout()) {
128 group = group.getParentGroup();
129 }
130
131 if (group.isStagingGroup()) {
132 Group liveGroup = group.getLiveGroup();
133
134 if (!liveGroup.isStagedPortlet(
135 PortletKeys.PORTLET_DISPLAY_TEMPLATES)) {
136
137 return liveGroup.getGroupId();
138 }
139 }
140
141 return group.getGroupId();
142 }
143 catch (Exception e) {
144 if (_log.isWarnEnabled()) {
145 _log.warn(e, e);
146 }
147 }
148
149 return groupId;
150 }
151
152 @Override
153 public String getDDMTemplateUuid(String displayStyle) {
154 if (!displayStyle.startsWith(DISPLAY_STYLE_PREFIX)) {
155 return null;
156 }
157
158 return displayStyle.substring(DISPLAY_STYLE_PREFIX.length());
159 }
160
161 @Override
162 public long getPortletDisplayTemplateDDMTemplateId(
163 long groupId, String displayStyle) {
164
165 long portletDisplayDDMTemplateId = 0;
166
167 long portletDisplayDDMTemplateGroupId = getDDMTemplateGroupId(groupId);
168
169 if (displayStyle.startsWith(DISPLAY_STYLE_PREFIX)) {
170 DDMTemplate portletDisplayDDMTemplate = fetchDDMTemplate(
171 portletDisplayDDMTemplateGroupId, displayStyle);
172
173 if (portletDisplayDDMTemplate != null) {
174 portletDisplayDDMTemplateId =
175 portletDisplayDDMTemplate.getTemplateId();
176 }
177 }
178
179 return portletDisplayDDMTemplateId;
180 }
181
182 @Override
183 public List<TemplateHandler> getPortletDisplayTemplateHandlers() {
184 List<TemplateHandler> templateHandlers =
185 TemplateHandlerRegistryUtil.getTemplateHandlers();
186
187 List<TemplateHandler> portletDisplayTemplateHandlers =
188 new ArrayList<TemplateHandler>();
189
190 for (TemplateHandler templateHandler : templateHandlers) {
191 if (templateHandler instanceof BasePortletDisplayTemplateHandler) {
192 portletDisplayTemplateHandlers.add(templateHandler);
193 }
194 else if (ProxyUtil.isProxyClass(templateHandler.getClass())) {
195 InvocationHandler invocationHandler =
196 ProxyUtil.getInvocationHandler(templateHandler);
197
198 if (invocationHandler instanceof ClassLoaderBeanHandler) {
199 ClassLoaderBeanHandler classLoaderBeanHandler =
200 (ClassLoaderBeanHandler)invocationHandler;
201
202 Object bean = classLoaderBeanHandler.getBean();
203
204 if (bean instanceof BasePortletDisplayTemplateHandler) {
205 portletDisplayTemplateHandlers.add(templateHandler);
206 }
207 }
208 }
209 }
210
211 return portletDisplayTemplateHandlers;
212 }
213
214 @Override
215 public Map<String, TemplateVariableGroup> getTemplateVariableGroups(
216 String language) {
217
218 Map<String, TemplateVariableGroup> templateVariableGroups =
219 new LinkedHashMap<String, TemplateVariableGroup>();
220
221 TemplateVariableGroup fieldsTemplateVariableGroup =
222 new TemplateVariableGroup("fields");
223
224 fieldsTemplateVariableGroup.addCollectionVariable(
225 "entries", List.class, PortletDisplayTemplateConstants.ENTRIES,
226 "entries-item", null, "curEntry", null);
227 fieldsTemplateVariableGroup.addVariable(
228 "entry", null, PortletDisplayTemplateConstants.ENTRY);
229
230 templateVariableGroups.put("fields", fieldsTemplateVariableGroup);
231
232 TemplateVariableGroup generalVariablesTemplateVariableGroup =
233 new TemplateVariableGroup("general-variables");
234
235 generalVariablesTemplateVariableGroup.addVariable(
236 "current-url", String.class,
237 PortletDisplayTemplateConstants.CURRENT_URL);
238 generalVariablesTemplateVariableGroup.addVariable(
239 "locale", Locale.class, PortletDisplayTemplateConstants.LOCALE);
240 generalVariablesTemplateVariableGroup.addVariable(
241 "portlet-preferences", Map.class,
242 PortletDisplayTemplateConstants.PORTLET_PREFERENCES);
243 generalVariablesTemplateVariableGroup.addVariable(
244 "template-id", null, PortletDisplayTemplateConstants.TEMPLATE_ID);
245 generalVariablesTemplateVariableGroup.addVariable(
246 "theme-display", ThemeDisplay.class,
247 PortletDisplayTemplateConstants.THEME_DISPLAY);
248
249 templateVariableGroups.put(
250 "general-variables", generalVariablesTemplateVariableGroup);
251
252 TemplateVariableGroup utilTemplateVariableGroup =
253 new TemplateVariableGroup("util");
254
255 utilTemplateVariableGroup.addVariable(
256 "http-request", HttpServletRequest.class,
257 PortletDisplayTemplateConstants.REQUEST);
258
259 if (language.equals(TemplateConstants.LANG_TYPE_VM)) {
260 utilTemplateVariableGroup.addVariable(
261 "liferay-taglib", VelocityTaglib.class,
262 PortletDisplayTemplateConstants.TAGLIB_LIFERAY);
263 }
264
265 utilTemplateVariableGroup.addVariable(
266 "render-request", RenderRequest.class,
267 PortletDisplayTemplateConstants.RENDER_REQUEST);
268 utilTemplateVariableGroup.addVariable(
269 "render-response", RenderResponse.class,
270 PortletDisplayTemplateConstants.RENDER_RESPONSE);
271
272 templateVariableGroups.put("util", utilTemplateVariableGroup);
273
274 return templateVariableGroups;
275 }
276
277 @Override
278 public String renderDDMTemplate(
279 PageContext pageContext, long ddmTemplateId, List<?> entries)
280 throws Exception {
281
282 Map<String, Object> contextObjects = new HashMap<String, Object>();
283
284 return renderDDMTemplate(
285 pageContext, ddmTemplateId, entries, contextObjects);
286 }
287
288 @Override
289 public String renderDDMTemplate(
290 PageContext pageContext, long ddmTemplateId, List<?> entries,
291 Map<String, Object> contextObjects)
292 throws Exception {
293
294 contextObjects.put(
295 PortletDisplayTemplateConstants.TEMPLATE_ID, ddmTemplateId);
296 contextObjects.put(PortletDisplayTemplateConstants.ENTRIES, entries);
297
298 if (!entries.isEmpty()) {
299 contextObjects.put(
300 PortletDisplayTemplateConstants.ENTRY, entries.get(0));
301 }
302
303 HttpServletRequest request =
304 (HttpServletRequest)pageContext.getRequest();
305
306 contextObjects.put(
307 PortletDisplayTemplateConstants.LOCALE, request.getLocale());
308
309 contextObjects.put(PortletDisplayTemplateConstants.REQUEST, request);
310
311 RenderRequest renderRequest = (RenderRequest)request.getAttribute(
312 JavaConstants.JAVAX_PORTLET_REQUEST);
313
314 contextObjects.put(
315 PortletDisplayTemplateConstants.RENDER_REQUEST, renderRequest);
316
317 RenderResponse renderResponse = (RenderResponse)request.getAttribute(
318 JavaConstants.JAVAX_PORTLET_RESPONSE);
319
320 contextObjects.put(
321 PortletDisplayTemplateConstants.RENDER_RESPONSE, renderResponse);
322
323 PortletURL currentURL = PortletURLUtil.getCurrent(
324 renderRequest, renderResponse);
325
326 contextObjects.put(
327 PortletDisplayTemplateConstants.CURRENT_URL, currentURL.toString());
328
329 ThemeDisplay themeDisplay = (ThemeDisplay)renderRequest.getAttribute(
330 WebKeys.THEME_DISPLAY);
331
332 contextObjects.put(
333 PortletDisplayTemplateConstants.THEME_DISPLAY, themeDisplay);
334
335
336
337 DDMTemplate ddmTemplate = DDMTemplateLocalServiceUtil.getTemplate(
338 ddmTemplateId);
339
340 contextObjects.put("class_name_id", ddmTemplate.getClassNameId());
341
342 String language = ddmTemplate.getLanguage();
343
344 if (language.equals(TemplateConstants.LANG_TYPE_FTL)) {
345 _addTaglibSupportFTL(contextObjects, pageContext);
346 }
347 else if (language.equals(TemplateConstants.LANG_TYPE_VM)) {
348 _addTaglibSupportVM(contextObjects, pageContext);
349 }
350
351 contextObjects.putAll(_getPortletPreferences(renderRequest));
352
353 return _transformer.transform(
354 themeDisplay, contextObjects, ddmTemplate.getScript(), language);
355 }
356
357 private void _addTaglibSupportFTL(
358 Map<String, Object> contextObjects, PageContext pageContext)
359 throws Exception {
360
361
362
363 final Servlet servlet = (Servlet)pageContext.getPage();
364
365 GenericServlet genericServlet = null;
366
367 if (servlet instanceof GenericServlet) {
368 genericServlet = (GenericServlet)servlet;
369 }
370 else {
371 genericServlet = new GenericServletWrapper(servlet);
372
373 genericServlet.init(pageContext.getServletConfig());
374 }
375
376 ServletContextHashModel servletContextHashModel =
377 new ServletContextHashModel(
378 genericServlet, ObjectWrapper.DEFAULT_WRAPPER);
379
380 contextObjects.put(
381 PortletDisplayTemplateConstants.FREEMARKER_SERVLET_APPLICATION,
382 servletContextHashModel);
383
384
385
386 HttpServletRequest request =
387 (HttpServletRequest)pageContext.getRequest();
388 HttpServletResponse response =
389 (HttpServletResponse)pageContext.getResponse();
390
391 HttpRequestHashModel requestHashModel = new HttpRequestHashModel(
392 request, response, ObjectWrapper.DEFAULT_WRAPPER);
393
394 contextObjects.put(
395 PortletDisplayTemplateConstants.FREEMARKER_SERVLET_REQUEST,
396 requestHashModel);
397
398
399
400 TemplateHashModel taglibLiferayHash =
401 FreeMarkerTaglibFactoryUtil.createTaglibFactory(
402 pageContext.getServletContext());
403
404 contextObjects.put(
405 PortletDisplayTemplateConstants.TAGLIB_LIFERAY_HASH,
406 taglibLiferayHash);
407 }
408
409 private void _addTaglibSupportVM(
410 Map<String, Object> contextObjects, PageContext pageContext) {
411
412 contextObjects.put(
413 PortletDisplayTemplateConstants.TAGLIB_LIFERAY,
414 _getVelocityTaglib(pageContext));
415 }
416
417 private Map<String, Object> _getPortletPreferences(
418 RenderRequest renderRequest) {
419
420 Map<String, Object> contextObjects = new HashMap<String, Object>();
421
422 PortletPreferences portletPreferences = renderRequest.getPreferences();
423
424 Map<String, String[]> map = portletPreferences.getMap();
425
426 contextObjects.put(
427 PortletDisplayTemplateConstants.PORTLET_PREFERENCES, map);
428
429 for (Map.Entry<String, String[]> entry : map.entrySet()) {
430 String[] values = entry.getValue();
431
432 if (ArrayUtil.isEmpty(values)) {
433 continue;
434 }
435
436 String value = values[0];
437
438 if (value == null) {
439 continue;
440 }
441
442 contextObjects.put(entry.getKey(), value);
443 }
444
445 return contextObjects;
446 }
447
448 private VelocityTaglib _getVelocityTaglib(PageContext pageContext) {
449 HttpServletRequest request =
450 (HttpServletRequest)pageContext.getRequest();
451
452 HttpSession session = request.getSession();
453
454 ServletContext servletContext = session.getServletContext();
455
456 HttpServletResponse response =
457 (HttpServletResponse)pageContext.getResponse();
458
459 VelocityTaglib velocityTaglib = new VelocityTaglibImpl(
460 servletContext, request,
461 new PipingServletResponse(response, pageContext.getOut()),
462 pageContext, null);
463
464 return velocityTaglib;
465 }
466
467 private static Log _log = LogFactoryUtil.getLog(
468 PortletDisplayTemplateImpl.class);
469
470 private Transformer _transformer = new Transformer(
471 PropsKeys.DYNAMIC_DATA_LISTS_ERROR_TEMPLATE, true);
472
473 }