001    /**
002     * Copyright (c) 2000-2013 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.portal.bean;
016    
017    import com.liferay.portal.kernel.bean.BeanLocator;
018    import com.liferay.portal.kernel.bean.BeanLocatorException;
019    import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
020    import com.liferay.portal.kernel.bean.PortletBeanLocatorUtil;
021    import com.liferay.portal.kernel.bean.Renderer;
022    import com.liferay.portal.kernel.bean.RendererException;
023    import com.liferay.portal.kernel.exception.PortalException;
024    import com.liferay.portal.kernel.exception.SystemException;
025    import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
026    import com.liferay.portal.kernel.log.Log;
027    import com.liferay.portal.kernel.log.LogFactoryUtil;
028    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
029    import com.liferay.portal.kernel.template.StringTemplateResource;
030    import com.liferay.portal.kernel.template.Template;
031    import com.liferay.portal.kernel.template.TemplateConstants;
032    import com.liferay.portal.kernel.template.TemplateContextType;
033    import com.liferay.portal.kernel.template.TemplateManagerUtil;
034    import com.liferay.portal.kernel.template.TemplateResource;
035    import com.liferay.portal.kernel.template.URLTemplateResource;
036    import com.liferay.portal.kernel.util.ParamUtil;
037    import com.liferay.portal.kernel.util.PropsUtil;
038    import com.liferay.portal.kernel.util.StringPool;
039    import com.liferay.portal.kernel.util.StringUtil;
040    import com.liferay.portal.kernel.util.Validator;
041    import com.liferay.portal.util.PortalUtil;
042    import com.liferay.portal.util.PrefsPropsUtil;
043    import com.liferay.portlet.PortletPreferencesFactoryUtil;
044    
045    import java.lang.reflect.Method;
046    
047    import java.net.URL;
048    
049    import javax.portlet.PortletPreferences;
050    import javax.portlet.PortletRequest;
051    import javax.portlet.PortletResponse;
052    
053    import javax.servlet.http.HttpServletRequest;
054    import javax.servlet.http.HttpServletResponse;
055    
056    /**
057     * @author Raymond Augé
058     */
059    @DoPrivileged
060    public class RendererImpl implements Renderer {
061    
062            public String renderBean(
063                            HttpServletRequest request, HttpServletResponse response,
064                            Object bean)
065                    throws RendererException {
066    
067                    return renderBean(request, response, null, bean, null);
068            }
069    
070            public String renderBean(
071                            HttpServletRequest request, HttpServletResponse response,
072                            Object bean, String varientSuffix)
073                    throws RendererException {
074    
075                    return renderBean(request, response, null, bean, varientSuffix);
076            }
077    
078            public String renderBean(
079                            HttpServletRequest request, HttpServletResponse response,
080                            String servletContextName, Object bean)
081                    throws RendererException {
082    
083                    return renderBean(request, response, servletContextName, bean, null);
084            }
085    
086            public String renderBean(
087                            HttpServletRequest request, HttpServletResponse response,
088                            String servletContextName, Object bean, String varientSuffix)
089                    throws RendererException {
090    
091                    if (bean == null) {
092                            return null;
093                    }
094    
095                    long companyId = PortalUtil.getCompanyId(request);
096    
097                    String className = normalizeClassName(bean.getClass().getName());
098    
099                    if (Validator.isNotNull(varientSuffix)) {
100                            className = varientSuffix;
101                    }
102    
103                    TemplateResource templateResource = null;
104    
105                    PortletPreferences preferences = getPortletPreferences(request);
106    
107                    if (preferences != null) {
108                            String velocityTemplateContent = preferences.getValue(
109                                    RENDERER_TEMPLATE_PREFIX + className, StringPool.BLANK);
110    
111                            if (Validator.isNotNull(velocityTemplateContent)) {
112                                    templateResource = new StringTemplateResource(
113                                            className, velocityTemplateContent);
114                            }
115                    }
116    
117                    if ((templateResource == null) &&
118                            Validator.isNotNull(servletContextName)) {
119    
120                            if (servletContextName.startsWith(StringPool.SLASH)) {
121                                    servletContextName = servletContextName.substring(1);
122                            }
123    
124                            try {
125                                    BeanLocator beanLocator = PortletBeanLocatorUtil.getBeanLocator(
126                                            servletContextName);
127    
128                                    ClassLoader classLoader = beanLocator.getClassLoader();
129    
130                                    URL url = classLoader.getResource(
131                                            PropsUtil.get(RENDERER_TEMPLATE_PREFIX + className));
132    
133                                    templateResource = new URLTemplateResource(className, url);
134                            }
135                            catch (Exception e) {
136                            }
137                    }
138    
139                    if (templateResource == null) {
140                            try {
141                                    String velocityTemplateContent = PrefsPropsUtil.getContent(
142                                            companyId, RENDERER_TEMPLATE_PREFIX + className);
143    
144                                    if (Validator.isNotNull(velocityTemplateContent)) {
145                                            templateResource = new StringTemplateResource(
146                                                    className, velocityTemplateContent);
147                                    }
148                            }
149                            catch (Exception e) {
150                            }
151                    }
152    
153                    if (templateResource == null) {
154                            _log.warn("No entity renderer template found for " + className);
155    
156                            return null;
157                    }
158    
159                    try {
160                            Template template = TemplateManagerUtil.getTemplate(
161                                    TemplateConstants.LANG_TYPE_VM, templateResource,
162                                    TemplateContextType.STANDARD);
163    
164                            template.prepare(request);
165    
166                            template.put(_BEAN, bean);
167    
168                            UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
169    
170                            template.processTemplate(unsyncStringWriter);
171    
172                            return unsyncStringWriter.toString();
173                    }
174                    catch (Exception e) {
175                            _log.error(e, e);
176    
177                            throw new RendererException(e);
178                    }
179            }
180    
181            public String renderBean(
182                            PortletRequest portletRequest, PortletResponse portletResponse,
183                            Object bean)
184                    throws RendererException {
185    
186                    return renderBean(portletRequest, portletResponse, null, bean, null);
187            }
188    
189            public String renderBean(
190                            PortletRequest portletRequest, PortletResponse portletResponse,
191                            Object bean, String varientSuffix)
192                    throws RendererException {
193    
194                    return renderBean(
195                            portletRequest, portletResponse, null, bean, varientSuffix);
196            }
197    
198            public String renderBean(
199                            PortletRequest portletRequest, PortletResponse portletResponse,
200                            String servletContextName, Object bean)
201                    throws RendererException {
202    
203                    return renderBean(
204                            portletRequest, portletResponse, servletContextName, bean, null);
205            }
206    
207            public String renderBean(
208                            PortletRequest portletRequest, PortletResponse portletResponse,
209                            String servletContextName, Object bean, String varientSuffix)
210                    throws RendererException {
211    
212                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
213                            portletRequest);
214                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
215                            portletResponse);
216    
217                    return renderBean(
218                            request, response, servletContextName, bean, varientSuffix);
219            }
220    
221            public String renderEntity(
222                            HttpServletRequest request, HttpServletResponse response,
223                            String className, Object classPK)
224                    throws RendererException {
225    
226                    return renderEntity(request, response, null, className, classPK, null);
227            }
228    
229            public String renderEntity(
230                            HttpServletRequest request, HttpServletResponse response,
231                            String className, Object classPK, String varientSuffix)
232                    throws RendererException {
233    
234                    return renderEntity(
235                            request, response, null, className, classPK, varientSuffix);
236            }
237    
238            public String renderEntity(
239                            HttpServletRequest request, HttpServletResponse response,
240                            String servletContextName, String className, Object classPK)
241                    throws RendererException {
242    
243                    return renderEntity(
244                            request, response, servletContextName, className, classPK, null);
245            }
246    
247            public String renderEntity(
248                            HttpServletRequest request, HttpServletResponse response,
249                            String servletContextName, String className, Object classPK,
250                            String varientSuffix)
251                    throws RendererException {
252    
253                    if (Validator.isNull(className)) {
254                            return null;
255                    }
256    
257                    className = normalizeClassName(className);
258    
259                    String[] beanNameParts = StringUtil.split(className, _MODEL);
260    
261                    Object serviceBean = null;
262    
263                    if (Validator.isNotNull(servletContextName)) {
264                            if (servletContextName.startsWith(StringPool.SLASH)) {
265                                    servletContextName = servletContextName.substring(1);
266                            }
267    
268                            try {
269                                    serviceBean = PortletBeanLocatorUtil.locate(
270                                            servletContextName,
271                                            beanNameParts[0] + _SERVICE + beanNameParts[1] +
272                                                    _LOCAL_SERVICE_UTIL);
273                            }
274                            catch (BeanLocatorException ble) {
275                            }
276                    }
277                    else {
278                            try {
279                                    serviceBean = PortalBeanLocatorUtil.locate(
280                                            beanNameParts[0] + _SERVICE + beanNameParts[1] +
281                                                    _LOCAL_SERVICE_UTIL);
282                            }
283                            catch (BeanLocatorException ble) {
284                            }
285                    }
286    
287                    Object bean = null;
288    
289                    if (serviceBean != null) {
290                            Method getMethod = null;
291    
292                            try {
293                                    getMethod = serviceBean.getClass().getDeclaredMethod(
294                                            "get" + beanNameParts[1], classPK.getClass());
295                            }
296                            catch (Exception e) {
297                            }
298    
299                            if (getMethod == null) {
300                                    try {
301                                            getMethod = serviceBean.getClass().getDeclaredMethod(
302                                                    "get" + beanNameParts[1],
303                                                    mapToPrimitive(classPK.getClass()));
304                                    }
305                                    catch (Exception e) {
306                                    }
307                            }
308    
309                            if (getMethod != null) {
310                                    try {
311                                            bean = getMethod.invoke(null, classPK);
312                                    }
313                                    catch (Exception e) {
314                                            _log.warn(e.getMessage());
315                                    }
316                            }
317                    }
318    
319                    return renderBean(
320                            request, response, servletContextName, bean, varientSuffix);
321            }
322    
323            public String renderEntity(
324                            PortletRequest portletRequest, PortletResponse portletResponse,
325                            String className, Object classPK)
326                    throws RendererException {
327    
328                    return renderEntity(
329                            portletRequest, portletResponse, null, className, classPK, null);
330            }
331    
332            public String renderEntity(
333                            PortletRequest portletRequest, PortletResponse portletResponse,
334                            String className, Object classPK, String varientSuffix)
335                    throws RendererException {
336    
337                    return renderEntity(
338                            portletRequest, portletResponse, null, className, classPK,
339                            varientSuffix);
340            }
341    
342            public String renderEntity(
343                            PortletRequest portletRequest, PortletResponse portletResponse,
344                            String servletContextName, String className, Object classPK)
345                    throws RendererException {
346    
347                    return renderEntity(
348                            portletRequest, portletResponse, servletContextName, className,
349                            classPK, null);
350            }
351    
352            public String renderEntity(
353                            PortletRequest portletRequest, PortletResponse portletResponse,
354                            String servletContextName, String className, Object classPK,
355                            String varientSuffix)
356                    throws RendererException {
357    
358                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
359                            portletRequest);
360                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
361                            portletResponse);
362    
363                    return renderEntity(
364                            request, response, servletContextName, className, classPK,
365                            varientSuffix);
366            }
367    
368            protected PortletPreferences getPortletPreferences(
369                    HttpServletRequest request) {
370    
371                    PortletPreferences preferences = PortalUtil.getPreferences(request);
372    
373                    String portletResource = ParamUtil.getString(
374                            request, "portletResource");
375    
376                    if (Validator.isNotNull(portletResource)) {
377                            try {
378                                    preferences = PortletPreferencesFactoryUtil.getPortletSetup(
379                                            request, portletResource);
380                            }
381                            catch (PortalException pe) {
382                            }
383                            catch (SystemException se) {
384                            }
385                    }
386    
387                    return preferences;
388            }
389    
390            protected Class<?> mapToPrimitive(Class<?> clazz) {
391                    Class<?> mapping = clazz;
392    
393                    if (clazz == Integer.class) {
394                            mapping = int.class;
395                    }
396                    else if (clazz == Long.class) {
397                            mapping = long.class;
398                    }
399    
400                    return mapping;
401            }
402    
403            protected String normalizeClassName(String className) {
404                    className = StringUtil.replace(
405                            className,
406                            new String[] {
407                                    ".impl.", "Impl"
408                            },
409                            new String[] {
410                                    StringPool.PERIOD, StringPool.BLANK
411                            }
412                    );
413    
414                    return className;
415            }
416    
417            private static final String _BEAN = "bean";
418    
419            private static final String _LOCAL_SERVICE_UTIL = "LocalServiceUtil";
420    
421            private static final String _MODEL = ".model.";
422    
423            private static final String _SERVICE = ".service.";
424    
425            private static Log _log = LogFactoryUtil.getLog(RendererImpl.class);
426    
427    }