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