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.main.OpenCms; 038import org.opencms.util.CmsStringUtil; 039import org.opencms.workplace.editors.directedit.CmsAdvancedDirectEditProvider; 040import org.opencms.workplace.editors.directedit.CmsDirectEditMode; 041import org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider; 042 043import java.io.IOException; 044 045import javax.servlet.ServletRequest; 046import javax.servlet.http.HttpServletRequest; 047import javax.servlet.http.HttpServletResponse; 048import javax.servlet.http.HttpSession; 049import javax.servlet.jsp.JspException; 050import javax.servlet.jsp.PageContext; 051import javax.servlet.jsp.tagext.BodyTagSupport; 052 053/** 054 * Implementation of the <code><enable-ade/></code> tag.<p> 055 * 056 * @since 7.6 057 */ 058public class CmsJspTagEnableAde extends BodyTagSupport { 059 060 /** The preview mode JavaScript include. */ 061 private static final String PREVIEW_INCLUDE_SCRIPT = "<script type=\"text/javascript\"> " 062 + "function openEditor(){ " 063 + "var target=window.location.href; " 064 + "if (target.indexOf(\"" 065 + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT 066 + "\")>0){ " 067 + "target=target.replace(\"" 068 + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT 069 + "=true\",\"" 070 + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT 071 + "=false\"); " 072 + "} else { " 073 + "var anchor=\"\"; " 074 + "if (target.indexOf(\"#\")>0) { " 075 + "anchor=target.substring(target.indexOf(\"#\")); " 076 + "target=target.substring(0,target.indexOf(\"#\")); " 077 + "} " 078 + "if (target.indexOf(\"?\")>0) { " 079 + "target+=\"&\"; " 080 + "} else { " 081 + "target+=\"?\"; " 082 + "} " 083 + "target+=\"" 084 + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT 085 + "=false\"; " 086 + "target+=anchor; " 087 + "} " 088 + "window.location.href=target; " 089 + "} " 090 + "function injectButton(){ " 091 + "if (self === top){ " 092 + "var injectElement=document.createElement(\"div\"); " 093 + "injectElement.innerHTML=\"<button id='opencms-leave-preview' class='opencms-icon opencms-icon-edit-point cmsState-up' onClick='openEditor()' style='left:%s;' title='%s'></button>\"; " 094 + "document.body.appendChild(injectElement); " 095 + "}" 096 + "} " 097 + "document.addEventListener(\"DOMContentLoaded\",injectButton); " 098 + "</script>\n"; 099 100 /** Serial version UID required for safe serialization. */ 101 private static final long serialVersionUID = 8447599916548975733L; 102 103 /** 104 * Enable-ade action method.<p> 105 * 106 * @param context the current JSP page context 107 * 108 * @throws JspException in case something goes wrong 109 */ 110 public static void enableAdeTagAction(PageContext context) throws JspException { 111 112 ServletRequest req = context.getRequest(); 113 if (CmsHistoryResourceHandler.isHistoryRequest(req)) { 114 // don't display advanced direct edit buttons on an historical resource 115 return; 116 } 117 118 CmsFlexController controller = CmsFlexController.getController(req); 119 CmsObject cms = controller.getCmsObject(); 120 121 if (cms.getRequestContext().getCurrentProject().isOnlineProject()) { 122 // advanced direct edit is never enabled in the online project 123 return; 124 } 125 126 if (CmsResource.isTemporaryFileName(cms.getRequestContext().getUri())) { 127 // don't display advanced direct edit buttons if a temporary file is displayed 128 return; 129 } 130 updateDirectEditFlagInSession(req); 131 if (isDirectEditDisabled(req)) { 132 try { 133 String buttonLeft = null; 134 Integer left = (Integer)((HttpServletRequest)req).getSession().getAttribute( 135 CmsGwtConstants.PARAM_BUTTON_LEFT); 136 137 if (left != null) { 138 buttonLeft = left.toString() + "px"; 139 } else { 140 buttonLeft = "20%"; 141 } 142 String titleMessage = Messages.get().getBundle( 143 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key(Messages.GUI_TOOLBAR_ENABLE_EDIT_MODE_0); 144 context.getOut().print(getPreviewInclude(buttonLeft, titleMessage)); 145 } catch (IOException e) { 146 throw new JspException(e); 147 } 148 } else { 149 150 I_CmsDirectEditProvider eb = new CmsAdvancedDirectEditProvider(); 151 eb.init(cms, CmsDirectEditMode.TRUE, ""); 152 CmsJspTagEditable.setDirectEditProvider(context, eb); 153 154 try { 155 CmsContainerpageActionElement actionEl = new CmsContainerpageActionElement( 156 context, 157 (HttpServletRequest)req, 158 (HttpServletResponse)context.getResponse()); 159 context.getOut().print(actionEl.exportAll()); 160 } catch (Exception e) { 161 throw new JspException(e); 162 } 163 } 164 } 165 166 /** 167 * Returns if direct edit is disabled for the current request.<p> 168 * 169 * @param request the servlet request 170 * 171 * @return <code>true</code> if direct edit is disabled for the current request 172 */ 173 public static boolean isDirectEditDisabled(ServletRequest request) { 174 175 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(request.getParameter(CmsGwtConstants.PARAM_TEMPLATE_CONTEXT))) { 176 return true; 177 } 178 String disabledParam = request.getParameter(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 179 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(disabledParam)) { 180 return Boolean.parseBoolean(disabledParam); 181 } else { 182 HttpSession session = ((HttpServletRequest)request).getSession(false); 183 Boolean disabledAttr = null == session 184 ? null 185 : (Boolean)session.getAttribute(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 186 return (disabledAttr != null) && disabledAttr.booleanValue(); 187 } 188 } 189 190 /** 191 * Removes the direct edit flag from session, turning the preview mode off.<p> 192 * 193 * @param session the session 194 */ 195 public static void removeDirectEditFlagFromSession(HttpSession session) { 196 197 session.removeAttribute(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 198 } 199 200 /** 201 * Updates the direct edit flag in the session and also storing the button left info if available.<p> 202 * 203 * @param request the request 204 */ 205 public static void updateDirectEditFlagInSession(ServletRequest request) { 206 207 String disabledParam = request.getParameter(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 208 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(disabledParam)) { 209 if (Boolean.parseBoolean(disabledParam)) { 210 ((HttpServletRequest)request).getSession().setAttribute( 211 CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT, 212 Boolean.TRUE); 213 String buttonLeft = request.getParameter(CmsGwtConstants.PARAM_BUTTON_LEFT); 214 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(buttonLeft)) { 215 Integer left = null; 216 try { 217 left = Integer.valueOf(buttonLeft); 218 if (left.intValue() > 0) { 219 ((HttpServletRequest)request).getSession().setAttribute( 220 CmsGwtConstants.PARAM_BUTTON_LEFT, 221 left); 222 } 223 } catch (NumberFormatException e) { 224 // malformed parameter, ignore 225 } 226 } 227 } else { 228 ((HttpServletRequest)request).getSession().removeAttribute(CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT); 229 } 230 } 231 } 232 233 /** 234 * Returns the preview mode include.<p> 235 * 236 * @param buttonLeft the button left parameter 237 * @param titleMessage the title attribute of the "Editor mode" button rendered by the include 238 * 239 * @return the preview mode include 240 */ 241 private static String getPreviewInclude(String buttonLeft, String titleMessage) { 242 243 StringBuffer buffer = new StringBuffer(); 244 buffer.append("<style type=\"text/css\"> @import url(\"").append( 245 CmsGwtActionElement.getFontIconCssLink()).append("\"); </style>\n"); 246 buffer.append(String.format(PREVIEW_INCLUDE_SCRIPT, buttonLeft, titleMessage)); 247 return buffer.toString(); 248 } 249 250 /** 251 * Close the direct edit tag, also prints the direct edit HTML to the current page.<p> 252 * 253 * @return {@link #EVAL_PAGE} 254 * 255 * @throws JspException in case something goes wrong 256 */ 257 @Override 258 public int doEndTag() throws JspException { 259 260 // only execute action for the first "ade" tag on the page (include file) 261 enableAdeTagAction(pageContext); 262 263 if (OpenCms.getSystemInfo().getServletContainerSettings().isReleaseTagsAfterEnd()) { 264 // need to release manually, JSP container may not call release as required (happens with Tomcat) 265 release(); 266 } 267 268 return EVAL_PAGE; 269 } 270 271 /** 272 * Opens the direct edit tag, if manual mode is set then the next 273 * start HTML for the direct edit buttons is printed to the page.<p> 274 * 275 * @return {@link #EVAL_BODY_INCLUDE} 276 */ 277 @Override 278 public int doStartTag() { 279 280 return EVAL_BODY_INCLUDE; 281 } 282}