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