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.taglib.util;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.log.LogUtil;
021    import com.liferay.portal.kernel.servlet.DirectRequestDispatcherFactoryUtil;
022    import com.liferay.portal.kernel.servlet.PipingServletResponse;
023    import com.liferay.portal.kernel.servlet.TrackedServletRequest;
024    import com.liferay.portal.kernel.servlet.taglib.FileAvailabilityUtil;
025    import com.liferay.portal.kernel.staging.StagingUtil;
026    import com.liferay.portal.kernel.util.GetterUtil;
027    import com.liferay.portal.kernel.util.PropsKeys;
028    import com.liferay.portal.kernel.util.PropsUtil;
029    import com.liferay.portal.kernel.util.ServerDetector;
030    import com.liferay.portal.kernel.util.UnicodeProperties;
031    import com.liferay.portal.kernel.util.Validator;
032    import com.liferay.portal.kernel.util.WebKeys;
033    import com.liferay.portal.model.Group;
034    import com.liferay.portal.model.Portlet;
035    import com.liferay.portal.model.PortletApp;
036    import com.liferay.portal.model.Theme;
037    import com.liferay.portal.service.PortletLocalServiceUtil;
038    import com.liferay.portal.theme.ThemeDisplay;
039    import com.liferay.portal.util.CustomJspRegistryUtil;
040    import com.liferay.portal.util.PortalUtil;
041    
042    import javax.servlet.RequestDispatcher;
043    import javax.servlet.ServletContext;
044    import javax.servlet.http.HttpServletRequest;
045    import javax.servlet.http.HttpServletResponse;
046    import javax.servlet.jsp.JspException;
047    
048    /**
049     * @author Brian Wing Shun Chan
050     * @author Shuyang Zhou
051     * @author Eduardo Lundgren
052     * @author Raymond Aug??
053     */
054    public class IncludeTag extends AttributesTagSupport {
055    
056            @Override
057            public int doEndTag() throws JspException {
058                    try {
059                            ServletContext servletContext = getServletContext();
060                            HttpServletRequest request = getServletRequest();
061    
062                            String page = null;
063    
064                            if (_useCustomPage) {
065                                    page = getCustomPage(servletContext, request);
066                            }
067    
068                            if (Validator.isNull(page)) {
069                                    page = getPage();
070                            }
071    
072                            if (Validator.isNull(page)) {
073                                    page = getEndPage();
074                            }
075    
076                            callSetAttributes();
077    
078                            if (themeResourceExists(page)) {
079                                    doIncludeTheme(page);
080    
081                                    return EVAL_PAGE;
082                            }
083                            else if (!FileAvailabilityUtil.isAvailable(servletContext, page)) {
084                                    return processEndTag();
085                            }
086                            else {
087                                    doInclude(page);
088    
089                                    return EVAL_PAGE;
090                            }
091                    }
092                    catch (Exception e) {
093                            throw new JspException(e);
094                    }
095                    finally {
096                            clearDynamicAttributes();
097                            clearParams();
098                            clearProperties();
099    
100                            cleanUpSetAttributes();
101    
102                            if (!ServerDetector.isResin()) {
103                                    setPage(null);
104                                    setUseCustomPage(true);
105    
106                                    cleanUp();
107                            }
108                    }
109            }
110    
111            @Override
112            public int doStartTag() throws JspException {
113                    try {
114                            ServletContext servletContext = getServletContext();
115    
116                            String page = getStartPage();
117    
118                            callSetAttributes();
119    
120                            if (themeResourceExists(page)) {
121                                    doIncludeTheme(page);
122    
123                                    return EVAL_BODY_INCLUDE;
124                            }
125                            else if (!FileAvailabilityUtil.isAvailable(servletContext, page)) {
126                                    return processStartTag();
127                            }
128                            else {
129                                    doInclude(page);
130    
131                                    return EVAL_BODY_INCLUDE;
132                            }
133                    }
134                    catch (Exception e) {
135                            throw new JspException(e);
136                    }
137            }
138    
139            @Override
140            public ServletContext getServletContext() {
141                    ServletContext servletContext = super.getServletContext();
142    
143                    try {
144                            if (Validator.isNull(_portletId)) {
145                                    return servletContext;
146                            }
147    
148                            HttpServletRequest request = getServletRequest();
149    
150                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
151                                    WebKeys.THEME_DISPLAY);
152    
153                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
154                                    themeDisplay.getCompanyId(), _portletId);
155    
156                            if (portlet == null) {
157                                    return servletContext;
158                            }
159    
160                            PortletApp portletApp = portlet.getPortletApp();
161    
162                            if (!portletApp.isWARFile()) {
163                                    return servletContext;
164                            }
165    
166                            return PortalUtil.getServletContext(portlet, servletContext);
167                    }
168                    catch (SystemException se) {
169                            return servletContext;
170                    }
171            }
172    
173            public void runEndTag() throws JspException {
174                    doEndTag();
175            }
176    
177            public void runStartTag() throws JspException {
178                    doStartTag();
179            }
180    
181            public void runTag() throws JspException {
182                    doStartTag();
183                    doEndTag();
184            }
185    
186            public void setPage(String page) {
187                    _page = page;
188            }
189    
190            public void setPortletId(String portletId) {
191                    _portletId = portletId;
192            }
193    
194            public void setStrict(boolean strict) {
195                    _strict = strict;
196            }
197    
198            public void setUseCustomPage(boolean useCustomPage) {
199                    _useCustomPage = useCustomPage;
200            }
201    
202            protected void callSetAttributes() {
203                    if (_calledSetAttributes) {
204                            return;
205                    }
206    
207                    _calledSetAttributes = true;
208    
209                    HttpServletRequest request = getOriginalServletRequest();
210    
211                    if (isCleanUpSetAttributes()) {
212                            _trackedRequest = new TrackedServletRequest(request);
213    
214                            request = _trackedRequest;
215                    }
216    
217                    setNamespacedAttribute(request, "bodyContent", getBodyContent());
218                    setNamespacedAttribute(
219                            request, "customAttributes", getCustomAttributes());
220                    setNamespacedAttribute(
221                            request, "dynamicAttributes", getDynamicAttributes());
222                    setNamespacedAttribute(
223                            request, "scopedAttributes", getScopedAttributes());
224    
225                    setAttributes(request);
226            }
227    
228            protected void cleanUp() {
229            }
230    
231            protected void cleanUpSetAttributes() {
232                    _calledSetAttributes = false;
233    
234                    if (isCleanUpSetAttributes()) {
235                            for (String name : _trackedRequest.getSetAttributes()) {
236                                    _trackedRequest.removeAttribute(name);
237                            }
238    
239                            _trackedRequest = null;
240                    }
241            }
242    
243            protected void doInclude(String page) throws JspException {
244                    try {
245                            include(page);
246                    }
247                    catch (Exception e) {
248                            HttpServletRequest request = getServletRequest();
249    
250                            String currentURL = (String)request.getAttribute(
251                                    WebKeys.CURRENT_URL);
252    
253                            _log.error(
254                                    "Current URL " + currentURL + " generates exception: " +
255                                            e.getMessage());
256    
257                            LogUtil.log(_log, e);
258    
259                            if (e instanceof JspException) {
260                                    throw (JspException)e;
261                            }
262                    }
263            }
264    
265            protected void doIncludeTheme(String page) throws Exception {
266                    ServletContext servletContext = getServletContext();
267                    HttpServletRequest request = getServletRequest();
268                    HttpServletResponse response = getServletResponse();
269    
270                    Theme theme = (Theme)request.getAttribute(WebKeys.THEME);
271    
272                    ThemeUtil.include(
273                            servletContext, request, response, pageContext, page, theme);
274            }
275    
276            protected String getCustomPage(
277                    ServletContext servletContext, HttpServletRequest request) {
278    
279                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
280                            WebKeys.THEME_DISPLAY);
281    
282                    if (themeDisplay == null) {
283                            return null;
284                    }
285    
286                    Group group = null;
287    
288                    try {
289                            group = StagingUtil.getLiveGroup(themeDisplay.getScopeGroupId());
290                    }
291                    catch (Exception e) {
292                            return null;
293                    }
294    
295                    UnicodeProperties typeSettingsProperties =
296                            group.getTypeSettingsProperties();
297    
298                    String customJspServletContextName = typeSettingsProperties.getProperty(
299                            "customJspServletContextName");
300    
301                    if (Validator.isNull(customJspServletContextName)) {
302                            return null;
303                    }
304    
305                    String page = getPage();
306    
307                    if (Validator.isNull(page)) {
308                            page = getEndPage();
309                    }
310    
311                    if (Validator.isNull(page)) {
312                            return null;
313                    }
314    
315                    String customPage = CustomJspRegistryUtil.getCustomJspFileName(
316                            customJspServletContextName, page);
317    
318                    if (FileAvailabilityUtil.isAvailable(servletContext, customPage)) {
319                            return customPage;
320                    }
321    
322                    return null;
323            }
324    
325            protected String getEndPage() {
326                    return null;
327            }
328    
329            protected HttpServletRequest getOriginalServletRequest() {
330                    return (HttpServletRequest)pageContext.getRequest();
331            }
332    
333            protected String getPage() {
334                    return _page;
335            }
336    
337            protected String getStartPage() {
338                    return null;
339            }
340    
341            protected void include(String page) throws Exception {
342                    ServletContext servletContext = getServletContext();
343    
344                    RequestDispatcher requestDispatcher =
345                            DirectRequestDispatcherFactoryUtil.getRequestDispatcher(
346                                    servletContext, page);
347    
348                    HttpServletRequest request = getServletRequest();
349    
350                    request.setAttribute(
351                            WebKeys.SERVLET_CONTEXT_INCLUDE_FILTER_STRICT, _strict);
352    
353                    HttpServletResponse response = new PipingServletResponse(
354                            pageContext, isTrimNewLines());
355    
356                    requestDispatcher.include(request, response);
357    
358                    request.removeAttribute(WebKeys.SERVLET_CONTEXT_INCLUDE_FILTER_STRICT);
359            }
360    
361            protected boolean isCleanUpSetAttributes() {
362                    return _CLEAN_UP_SET_ATTRIBUTES;
363            }
364    
365            protected boolean isTrimNewLines() {
366                    return _TRIM_NEW_LINES;
367            }
368    
369            protected boolean isUseCustomPage() {
370                    return _useCustomPage;
371            }
372    
373            protected int processEndTag() throws Exception {
374                    return EVAL_PAGE;
375            }
376    
377            protected int processStartTag() throws Exception {
378                    return EVAL_BODY_INCLUDE;
379            }
380    
381            protected void setAttributes(HttpServletRequest request) {
382            }
383    
384            protected void setCalledSetAttributes(boolean calledSetAttributes) {
385                    _calledSetAttributes = calledSetAttributes;
386            }
387    
388            protected boolean themeResourceExists(String page) throws Exception {
389                    if ((page == null) || !_THEME_JSP_OVERRIDE_ENABLED || _strict) {
390                            return false;
391                    }
392    
393                    ServletContext servletContext = getServletContext();
394                    HttpServletRequest request = getServletRequest();
395    
396                    Theme theme = (Theme)request.getAttribute(WebKeys.THEME);
397    
398                    if (theme == null) {
399                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
400                                    WebKeys.THEME_DISPLAY);
401    
402                            if (themeDisplay != null) {
403                                    theme = themeDisplay.getTheme();
404                            }
405                    }
406    
407                    if (theme == null) {
408                            return false;
409                    }
410    
411                    String portletId = ThemeUtil.getPortletId(request);
412    
413                    boolean exists = theme.resourceExists(servletContext, portletId, page);
414    
415                    if (_log.isDebugEnabled() && exists) {
416                            String resourcePath = theme.getResourcePath(
417                                    servletContext, null, page);
418    
419                            _log.debug(resourcePath);
420                    }
421    
422                    return exists;
423            }
424    
425            private static final boolean _CLEAN_UP_SET_ATTRIBUTES = false;
426    
427            private static final boolean _THEME_JSP_OVERRIDE_ENABLED =
428                    GetterUtil.getBoolean(
429                            PropsUtil.get(PropsKeys.THEME_JSP_OVERRIDE_ENABLED));
430    
431            private static final boolean _TRIM_NEW_LINES = false;
432    
433            private static Log _log = LogFactoryUtil.getLog(IncludeTag.class);
434    
435            private boolean _calledSetAttributes;
436            private String _page;
437            private String _portletId;
438            private boolean _strict;
439            private TrackedServletRequest _trackedRequest;
440            private boolean _useCustomPage = true;
441    
442    }