001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.jsp; 029 030import org.opencms.ade.containerpage.CmsContainerpageActionElement; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.file.history.CmsHistoryResourceHandler; 034import org.opencms.flex.CmsFlexController; 035import org.opencms.gwt.CmsGwtActionElement; 036import org.opencms.gwt.shared.CmsGwtConstants; 037import org.opencms.i18n.CmsEncoder; 038import org.opencms.json.JSONException; 039import org.opencms.json.JSONObject; 040import org.opencms.main.CmsLog; 041import org.opencms.main.OpenCms; 042import org.opencms.main.OpenCmsServlet; 043import org.opencms.util.CmsStringUtil; 044import org.opencms.workplace.CmsWorkplace; 045import org.opencms.workplace.editors.directedit.CmsAdvancedDirectEditProvider; 046import org.opencms.workplace.editors.directedit.CmsDirectEditMode; 047import org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider; 048 049import java.io.IOException; 050 051import javax.servlet.ServletRequest; 052import javax.servlet.http.HttpServletRequest; 053import javax.servlet.http.HttpServletResponse; 054import javax.servlet.http.HttpSession; 055import javax.servlet.jsp.JspException; 056import javax.servlet.jsp.PageContext; 057import javax.servlet.jsp.tagext.BodyTagSupport; 058 059import org.apache.commons.logging.Log; 060 061/** 062 * Implementation of the <code><enable-ade/></code> tag.<p> 063 * 064 * @since 7.6 065 */ 066public class CmsJspTagEnableAde extends BodyTagSupport { 067 068 /** Logger instance for this class. */ 069 private static final Log LOG = CmsLog.getLog(CmsJspTagEnableAde.class); 070 071 /** Serial version UID required for safe serialization. */ 072 private static final long serialVersionUID = 8447599916548975733L; 073 074 /** 075 * Enable-ade action method.<p> 076 * 077 * @param context the current JSP page context 078 * 079 * @throws JspException in case something goes wrong 080 */ 081 public static void enableAdeTagAction(PageContext context) throws JspException { 082 083 ServletRequest req = context.getRequest(); 084 if (CmsHistoryResourceHandler.isHistoryRequest(req)) { 085 // don't display advanced direct edit buttons on an historical resource 086 return; 087 } 088 089 CmsFlexController controller = CmsFlexController.getController(req); 090 CmsObject cms = controller.getCmsObject(); 091 092 if (cms.getRequestContext().getCurrentProject().isOnlineProject()) { 093 // advanced direct edit is never enabled in the online project 094 return; 095 } 096 097 if (CmsResource.isTemporaryFileName(cms.getRequestContext().getUri())) { 098 // don't display advanced direct edit buttons if a temporary file is displayed 099 return; 100 } 101 updateDirectEditFlagInSession(req); 102 if (isDirectEditDisabled(req)) { 103 try { 104 String buttonLeft = null; 105 Integer left = (Integer)((HttpServletRequest)req).getSession().getAttribute( 106 CmsGwtConstants.PARAM_BUTTON_LEFT); 107 108 if (left != null) { 109 buttonLeft = left.toString() + "px"; 110 } else { 111 buttonLeft = "20%"; 112 } 113 String titleMessage = Messages.get().getBundle( 114 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key(Messages.GUI_TOOLBAR_ENABLE_EDIT_MODE_0); 115 context.getOut().print(getPreviewInclude(buttonLeft, titleMessage)); 116 } catch (IOException e) { 117 throw new JspException(e); 118 } 119 } else { 120 121 I_CmsDirectEditProvider eb = new CmsAdvancedDirectEditProvider(); 122 eb.init(cms, CmsDirectEditMode.TRUE, ""); 123 CmsJspTagEditable.setDirectEditProvider(context, eb); 124 125 try { 126 CmsContainerpageActionElement actionEl = new CmsContainerpageActionElement( 127 context, 128 (HttpServletRequest)req, 129 (HttpServletResponse)context.getResponse()); 130 context.getOut().print(actionEl.exportAll()); 131 } catch (Exception e) { 132 throw new JspException(e); 133 } 134 } 135 } 136 137 /** 138 * Returns if direct edit is disabled for the current request.<p> 139 * 140 * @param request the servlet request 141 * 142 * @return <code>true</code> if direct edit is disabled for the current request 143 */ 144 public static boolean isDirectEditDisabled(ServletRequest request) { 145 146 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(request.getParameter(CmsGwtConstants.PARAM_TEMPLATE_CONTEXT))) { 147 return true; 148 } 149 String disabledParam = request.getParameter(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 150 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(disabledParam)) { 151 return Boolean.parseBoolean(disabledParam); 152 } else { 153 HttpSession session = ((HttpServletRequest)request).getSession(false); 154 Boolean disabledAttr = null == session 155 ? null 156 : (Boolean)session.getAttribute(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 157 return (disabledAttr != null) && disabledAttr.booleanValue(); 158 } 159 } 160 161 /** 162 * Removes the direct edit flag from session, turning the preview mode off.<p> 163 * 164 * @param session the session 165 */ 166 public static void removeDirectEditFlagFromSession(HttpSession session) { 167 168 session.removeAttribute(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 169 } 170 171 /** 172 * Updates the direct edit flag in the session and also storing the button left info if available.<p> 173 * 174 * @param request the request 175 */ 176 public static void updateDirectEditFlagInSession(ServletRequest request) { 177 178 String disabledParam = request.getParameter(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 179 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(disabledParam)) { 180 if (Boolean.parseBoolean(disabledParam)) { 181 ((HttpServletRequest)request).getSession().setAttribute( 182 CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT, 183 Boolean.TRUE); 184 String buttonLeft = request.getParameter(CmsGwtConstants.PARAM_BUTTON_LEFT); 185 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(buttonLeft)) { 186 Integer left = null; 187 try { 188 left = Integer.valueOf(buttonLeft); 189 if (left.intValue() > 0) { 190 ((HttpServletRequest)request).getSession().setAttribute( 191 CmsGwtConstants.PARAM_BUTTON_LEFT, 192 left); 193 } 194 } catch (NumberFormatException e) { 195 // malformed parameter, ignore 196 } 197 } 198 } else { 199 ((HttpServletRequest)request).getSession().removeAttribute(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 200 } 201 } 202 } 203 204 /** 205 * Returns the preview mode include.<p> 206 * 207 * @param buttonLeft the button left parameter 208 * @param titleMessage the title attribute of the "Editor mode" button rendered by the include 209 * 210 * @return the preview mode include 211 */ 212 private static String getPreviewInclude(String buttonLeft, String titleMessage) { 213 214 StringBuffer buffer = new StringBuffer(); 215 buffer.append("<style type=\"text/css\"> @import url(\"").append( 216 CmsGwtActionElement.getFontIconCssLink()).append("\"); </style>\n"); 217 String heartbeatUrl = CmsStringUtil.joinPaths( 218 OpenCms.getStaticExportManager().getVfsPrefix(), 219 OpenCmsServlet.HANDLE_BUILTIN_SERVICE, 220 CmsGwtConstants.HANDLER_UPDATE_SESSION); 221 JSONObject previewSettings = new JSONObject(); 222 try { 223 previewSettings.put("heartbeatUrl", heartbeatUrl); 224 previewSettings.put("buttonLeft", buttonLeft); 225 previewSettings.put("titleMessage", CmsEncoder.escapeXml(titleMessage)); 226 } catch (JSONException e) { 227 // shouldn't happen 228 LOG.error(e.getLocalizedMessage(), e); 229 } 230 buffer.append("<script>\nvar previewSettings = " + previewSettings.toString() + ";\n</script>\n"); 231 buffer.append("<script src=\"" + CmsWorkplace.getStaticResourceUri("/ade/page-preview.js") + "\"></script>\n"); 232 return buffer.toString(); 233 } 234 235 /** 236 * Close the direct edit tag, also prints the direct edit HTML to the current page.<p> 237 * 238 * @return {@link #EVAL_PAGE} 239 * 240 * @throws JspException in case something goes wrong 241 */ 242 @Override 243 public int doEndTag() throws JspException { 244 245 // only execute action for the first "ade" tag on the page (include file) 246 enableAdeTagAction(pageContext); 247 248 if (OpenCms.getSystemInfo().getServletContainerSettings().isReleaseTagsAfterEnd()) { 249 // need to release manually, JSP container may not call release as required (happens with Tomcat) 250 release(); 251 } 252 253 return EVAL_PAGE; 254 } 255 256 /** 257 * Opens the direct edit tag, if manual mode is set then the next 258 * start HTML for the direct edit buttons is printed to the page.<p> 259 * 260 * @return {@link #EVAL_BODY_INCLUDE} 261 */ 262 @Override 263 public int doStartTag() { 264 265 return EVAL_BODY_INCLUDE; 266 } 267}