001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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.util.GetterUtil;
026    import com.liferay.portal.kernel.util.PropsKeys;
027    import com.liferay.portal.kernel.util.PropsUtil;
028    import com.liferay.portal.kernel.util.ServerDetector;
029    import com.liferay.portal.kernel.util.UnicodeProperties;
030    import com.liferay.portal.kernel.util.Validator;
031    import com.liferay.portal.kernel.util.WebKeys;
032    import com.liferay.portal.model.Group;
033    import com.liferay.portal.model.Portlet;
034    import com.liferay.portal.model.PortletApp;
035    import com.liferay.portal.model.Theme;
036    import com.liferay.portal.service.PortletLocalServiceUtil;
037    import com.liferay.portal.theme.ThemeDisplay;
038    import com.liferay.portal.util.CustomJspRegistryUtil;
039    import com.liferay.portal.util.PortalUtil;
040    
041    import javax.servlet.RequestDispatcher;
042    import javax.servlet.ServletContext;
043    import javax.servlet.http.HttpServletRequest;
044    import javax.servlet.http.HttpServletResponse;
045    import javax.servlet.jsp.JspException;
046    
047    /**
048     * @author Brian Wing Shun Chan
049     * @author Shuyang Zhou
050     * @author Eduardo Lundgren
051     * @author Raymond Augé
052     */
053    public class IncludeTag extends AttributesTagSupport {
054    
055            @Override
056            public int doEndTag() throws JspException {
057                    try {
058                            ServletContext servletContext = getServletContext();
059                            HttpServletRequest request = getServletRequest();
060    
061                            String page = null;
062    
063                            if (_useCustomPage) {
064                                    page = getCustomPage(servletContext, request);
065                            }
066    
067                            if (Validator.isNull(page)) {
068                                    page = getPage();
069                            }
070    
071                            if (Validator.isNull(page)) {
072                                    page = getEndPage();
073                            }
074    
075                            callSetAttributes();
076    
077                            if (themeResourceExists(page)) {
078                                    doIncludeTheme(page);
079    
080                                    return EVAL_PAGE;
081                            }
082                            else if (!FileAvailabilityUtil.isAvailable(servletContext, page)) {
083                                    return processEndTag();
084                            }
085                            else {
086                                    doInclude(page);
087    
088                                    return EVAL_PAGE;
089                            }
090                    }
091                    catch (Exception e) {
092                            throw new JspException(e);
093                    }
094                    finally {
095                            clearDynamicAttributes();
096                            clearParams();
097                            clearProperties();
098    
099                            cleanUpSetAttributes();
100    
101                            if (!ServerDetector.isResin()) {
102                                    setPage(null);
103                                    setUseCustomPage(true);
104    
105                                    cleanUp();
106                            }
107                    }
108            }
109    
110            @Override
111            public int doStartTag() throws JspException {
112                    try {
113                            ServletContext servletContext = getServletContext();
114    
115                            String page = getStartPage();
116    
117                            callSetAttributes();
118    
119                            if (themeResourceExists(page)) {
120                                    doIncludeTheme(page);
121    
122                                    return EVAL_BODY_INCLUDE;
123                            }
124                            else if (!FileAvailabilityUtil.isAvailable(servletContext, page)) {
125                                    return processStartTag();
126                            }
127                            else {
128                                    doInclude(page);
129    
130                                    return EVAL_BODY_INCLUDE;
131                            }
132                    }
133                    catch (Exception e) {
134                            throw new JspException(e);
135                    }
136            }
137    
138            @Override
139            public ServletContext getServletContext() {
140                    ServletContext servletContext = super.getServletContext();
141    
142                    try {
143                            if (Validator.isNull(_portletId)) {
144                                    return servletContext;
145                            }
146    
147                            HttpServletRequest request = getServletRequest();
148    
149                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
150                                    WebKeys.THEME_DISPLAY);
151    
152                            Portlet portlet = PortletLocalServiceUtil.getPortletById(
153                                    themeDisplay.getCompanyId(), _portletId);
154    
155                            if (portlet == null) {
156                                    return servletContext;
157                            }
158    
159                            PortletApp portletApp = portlet.getPortletApp();
160    
161                            if (!portletApp.isWARFile()) {
162                                    return servletContext;
163                            }
164    
165                            return PortalUtil.getServletContext(portlet, servletContext);
166                    }
167                    catch (SystemException se) {
168                            return servletContext;
169                    }
170            }
171    
172            public void runEndTag() throws JspException {
173                    doEndTag();
174            }
175    
176            public void runStartTag() throws JspException {
177                    doStartTag();
178            }
179    
180            public void runTag() throws JspException {
181                    doStartTag();
182                    doEndTag();
183            }
184    
185            public void setPage(String page) {
186                    _page = page;
187            }
188    
189            public void setPortletId(String portletId) {
190                    _portletId = portletId;
191            }
192    
193            public void setStrict(boolean strict) {
194                    _strict = strict;
195            }
196    
197            public void setUseCustomPage(boolean useCustomPage) {
198                    _useCustomPage = useCustomPage;
199            }
200    
201            protected void callSetAttributes() {
202                    if (_calledSetAttributes) {
203                            return;
204                    }
205    
206                    _calledSetAttributes = true;
207    
208                    HttpServletRequest request =
209                            (HttpServletRequest)pageContext.getRequest();
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 = themeDisplay.getScopeGroup();
287    
288                    UnicodeProperties typeSettingsProperties =
289                            group.getTypeSettingsProperties();
290    
291                    String customJspServletContextName = typeSettingsProperties.getProperty(
292                            "customJspServletContextName");
293    
294                    if (Validator.isNull(customJspServletContextName)) {
295                            return null;
296                    }
297    
298                    String page = getPage();
299    
300                    if (Validator.isNull(page)) {
301                            page = getEndPage();
302                    }
303    
304                    if (Validator.isNull(page)) {
305                            return null;
306                    }
307    
308                    String customPage = CustomJspRegistryUtil.getCustomJspFileName(
309                            customJspServletContextName, page);
310    
311                    if (FileAvailabilityUtil.isAvailable(servletContext, customPage)) {
312                            return customPage;
313                    }
314    
315                    return null;
316            }
317    
318            protected String getEndPage() {
319                    return null;
320            }
321    
322            protected String getPage() {
323                    return _page;
324            }
325    
326            protected String getStartPage() {
327                    return null;
328            }
329    
330            protected void include(String page) throws Exception {
331                    ServletContext servletContext = getServletContext();
332    
333                    RequestDispatcher requestDispatcher =
334                            DirectRequestDispatcherFactoryUtil.getRequestDispatcher(
335                                    servletContext, page);
336    
337                    HttpServletRequest request = getServletRequest();
338    
339                    request.setAttribute(
340                            WebKeys.SERVLET_CONTEXT_INCLUDE_FILTER_STRICT, _strict);
341    
342                    HttpServletResponse response = new PipingServletResponse(
343                            pageContext, isTrimNewLines());
344    
345                    requestDispatcher.include(request, response);
346    
347                    request.removeAttribute(WebKeys.SERVLET_CONTEXT_INCLUDE_FILTER_STRICT);
348            }
349    
350            protected boolean isCleanUpSetAttributes() {
351                    return _CLEAN_UP_SET_ATTRIBUTES;
352            }
353    
354            protected boolean isTrimNewLines() {
355                    return _TRIM_NEW_LINES;
356            }
357    
358            protected boolean isUseCustomPage() {
359                    return _useCustomPage;
360            }
361    
362            protected int processEndTag() throws Exception {
363                    return EVAL_PAGE;
364            }
365    
366            protected int processStartTag() throws Exception {
367                    return EVAL_BODY_INCLUDE;
368            }
369    
370            protected void setAttributes(HttpServletRequest request) {
371            }
372    
373            protected void setCalledSetAttributes(boolean calledSetAttributes) {
374                    _calledSetAttributes = calledSetAttributes;
375            }
376    
377            protected boolean themeResourceExists(String page) throws Exception {
378                    if ((page == null) || !_THEME_JSP_OVERRIDE_ENABLED || _strict) {
379                            return false;
380                    }
381    
382                    ServletContext servletContext = getServletContext();
383                    HttpServletRequest request = getServletRequest();
384    
385                    Theme theme = (Theme)request.getAttribute(WebKeys.THEME);
386    
387                    String portletId = ThemeUtil.getPortletId(request);
388    
389                    boolean exists = theme.resourceExists(servletContext, portletId, page);
390    
391                    if (_log.isDebugEnabled() && exists) {
392                            String resourcePath = theme.getResourcePath(
393                                    servletContext, null, page);
394    
395                            _log.debug(resourcePath);
396                    }
397    
398                    return exists;
399            }
400    
401            private static final boolean _CLEAN_UP_SET_ATTRIBUTES = false;
402    
403            private static final boolean _THEME_JSP_OVERRIDE_ENABLED =
404                    GetterUtil.getBoolean(
405                            PropsUtil.get(PropsKeys.THEME_JSP_OVERRIDE_ENABLED));
406    
407            private static final boolean _TRIM_NEW_LINES = false;
408    
409            private static Log _log = LogFactoryUtil.getLog(IncludeTag.class);
410    
411            private boolean _calledSetAttributes;
412            private String _page;
413            private String _portletId;
414            private boolean _strict;
415            private TrackedServletRequest _trackedRequest;
416            private boolean _useCustomPage = true;
417    
418    }