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