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, 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.workplace.editors.directedit; 029 030import org.opencms.cache.CmsMemoryObjectCache; 031import org.opencms.file.CmsFile; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsProperty; 034import org.opencms.file.CmsPropertyDefinition; 035import org.opencms.i18n.CmsEncoder; 036import org.opencms.main.CmsException; 037import org.opencms.main.CmsLog; 038import org.opencms.main.OpenCms; 039import org.opencms.util.CmsMacroResolver; 040import org.opencms.workplace.CmsWorkplace; 041import org.opencms.workplace.editors.Messages; 042 043import javax.servlet.jsp.JspException; 044import javax.servlet.jsp.PageContext; 045 046import org.apache.commons.logging.Log; 047 048/** 049 * Provider for the OpenCms default graphical "direct edit" buttons.<p> 050 * 051 * Since OpenCms version 6.2.3, 052 * this provider is configured as the standard direct edit provider in a common OpenCms installation.<p> 053 * 054 * This provider DOES NOT support {@link CmsDirectEditMode#MANUAL} mode.<p> 055 * 056 * @since 6.2.3 057 */ 058public class CmsDirectEditDefaultProvider extends A_CmsDirectEditProvider { 059 060 /** The log object for this class. */ 061 private static final Log LOG = CmsLog.getLog(CmsDirectEditDefaultProvider.class); 062 063 /** Indicates the permissions for the last element the was opened. */ 064 protected int m_lastPermissionMode; 065 066 /** The include file used by this provider. */ 067 private String m_headerInclude; 068 069 /** 070 * Returns the end HTML for a disabled direct edit button.<p> 071 * 072 * @return the end HTML for a disabled direct edit button 073 */ 074 public String endDirectEditDisabled() { 075 076 return "</div>\n<!-- EDIT BLOCK END (DISABLED) -->\n"; 077 } 078 079 /** 080 * Returns the end HTML for an enabled direct edit button.<p> 081 * 082 * @return the end HTML for an enabled direct edit button 083 */ 084 public String endDirectEditEnabled() { 085 086 return "</div>\n<!-- EDIT BLOCK END (ENABLED) -->\n"; 087 } 088 089 /** 090 * Returns the direct edit include HTML to insert in the page beginning.<p> t 091 * 092 * @param params the parameters for the direct edit includes 093 * 094 * @return the direct edit include HTML to insert in the page beginning 095 */ 096 public String getDirectEditIncludes(CmsDirectEditParams params) { 097 098 CmsMacroResolver resolver = prepareMacroResolverForIncludes(params); 099 return resolver.resolveMacros(m_headerInclude); 100 } 101 102 /** 103 * @see org.opencms.workplace.editors.directedit.A_CmsDirectEditProvider#init(org.opencms.file.CmsObject, org.opencms.workplace.editors.directedit.CmsDirectEditMode, java.lang.String) 104 */ 105 @Override 106 public void init(CmsObject cms, CmsDirectEditMode mode, String fileName) { 107 108 super.init(cms, mode, fileName); 109 110 // check if the selected include file is available in the cache 111 CmsMemoryObjectCache cache = CmsMemoryObjectCache.getInstance(); 112 m_headerInclude = (String)cache.getCachedObject(CmsDirectEditDefaultProvider.class, m_fileName); 113 114 if (m_headerInclude == null) { 115 // the file is not available in the cache 116 try { 117 CmsFile file = m_cms.readFile(m_fileName); 118 // create a String with the right encoding 119 m_headerInclude = getContentAsString(file); 120 // store this in the cache 121 cache.putCachedObject(CmsDirectEditDefaultProvider.class, m_fileName, m_headerInclude); 122 123 } catch (CmsException e) { 124 // this should better not happen 125 m_headerInclude = ""; 126 LOG.error(Messages.get().getBundle().key(Messages.LOG_DIRECT_EDIT_NO_HEADER_1, fileName), e); 127 } 128 } 129 } 130 131 /** 132 * @see org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider#insertDirectEditEnd(javax.servlet.jsp.PageContext) 133 */ 134 public void insertDirectEditEnd(PageContext context) throws JspException { 135 136 String content; 137 switch (m_lastPermissionMode) { 138 139 case 1: // disabled 140 content = endDirectEditDisabled(); 141 break; 142 case 2: // enabled 143 content = endDirectEditEnabled(); 144 break; 145 default: // inactive or undefined 146 content = null; 147 } 148 m_lastPermissionMode = 0; 149 print(context, content); 150 } 151 152 /** 153 * @see org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider#insertDirectEditIncludes(javax.servlet.jsp.PageContext, org.opencms.workplace.editors.directedit.CmsDirectEditParams) 154 */ 155 public void insertDirectEditIncludes(PageContext context, CmsDirectEditParams params) throws JspException { 156 157 print(context, getDirectEditIncludes(params)); 158 } 159 160 /** 161 * @see org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider#insertDirectEditStart(javax.servlet.jsp.PageContext, org.opencms.workplace.editors.directedit.CmsDirectEditParams) 162 */ 163 public boolean insertDirectEditStart(PageContext context, CmsDirectEditParams params) throws JspException { 164 165 String content; 166 // check the direct edit permissions of the current user 167 CmsDirectEditResourceInfo resourceInfo = getResourceInfo(params, params.getResourceName()); 168 // check the permission mode 169 m_lastPermissionMode = resourceInfo.getPermissions().getPermission(); 170 switch (m_lastPermissionMode) { 171 case 1: // disabled 172 content = startDirectEditDisabled(params, resourceInfo); 173 break; 174 case 2: // enabled 175 content = startDirectEditEnabled(params, resourceInfo); 176 break; 177 default: // inactive or undefined 178 content = null; 179 } 180 print(context, content); 181 return content != null; 182 } 183 184 /** 185 * Returns <code>false</code> because the default provider does not support manual button placement.<p> 186 * 187 * @see org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider#isManual(org.opencms.workplace.editors.directedit.CmsDirectEditMode) 188 */ 189 @Override 190 public boolean isManual(CmsDirectEditMode mode) { 191 192 return false; 193 } 194 195 /** 196 * @see org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider#newInstance() 197 */ 198 public I_CmsDirectEditProvider newInstance() { 199 200 CmsDirectEditDefaultProvider result = new CmsDirectEditDefaultProvider(); 201 result.m_configurationParameters = m_configurationParameters; 202 return result; 203 } 204 205 /** 206 * Returns the start HTML for a disabled direct edit button.<p> 207 * 208 * @param params the direct edit parameters 209 * @param resourceInfo contains information about the resource to edit 210 * 211 * @return the start HTML for a disabled direct edit button 212 */ 213 public String startDirectEditDisabled(CmsDirectEditParams params, CmsDirectEditResourceInfo resourceInfo) { 214 215 String editId = getNextDirectEditId(); 216 StringBuffer result = new StringBuffer(256); 217 218 result.append("<!-- EDIT BLOCK START (DISABLED): "); 219 result.append(params.m_resourceName); 220 result.append(" ["); 221 result.append(resourceInfo.getResource().getState()); 222 result.append("] "); 223 if (!resourceInfo.getLock().isUnlocked()) { 224 result.append(" locked "); 225 result.append(resourceInfo.getLock().getProject().getName()); 226 } 227 result.append(" -->\n"); 228 229 result.append("<script >\n"); 230 result.append("registerButtonOcms(\"").append(editId).append("\");\n"); 231 result.append("</script>\n"); 232 result.append("<div class=\"ocms_de_bt\" id=\"buttons_").append(editId).append("\">\n"); 233 result.append("<span onmouseover=\"activateOcms(\'").append(editId).append( 234 "\');\" onmouseout=\"deactivateOcms(\'").append(editId).append("\');\">\n"); 235 result.append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" id=\"table_").append(editId).append( 236 "\"><tr>\n"); 237 result.append("<td class=\"ocms_de\"><span class=\"ocms_disabled\">"); 238 if (m_editButtonStyle == 1) { 239 result.append("<span class=\"ocms_combobutton\" style=\"background-image: url(\'").append( 240 CmsWorkplace.getSkinUri()).append("buttons/directedit_in.png\');\"> ").append( 241 m_messages.key(Messages.GUI_EDITOR_FRONTEND_BUTTON_LOCKED_0)).append("</span>"); 242 } else if (m_editButtonStyle == 2) { 243 result.append("<span class=\"ocms_combobutton\" style=\"padding-left: 4px;\">").append( 244 m_messages.key(Messages.GUI_EDITOR_FRONTEND_BUTTON_LOCKED_0)).append("</span>"); 245 } else { 246 result.append("<img border=\"0\" src=\"").append(CmsWorkplace.getSkinUri()).append( 247 "buttons/directedit_in.png\" title=\"").append( 248 m_messages.key(Messages.GUI_EDITOR_FRONTEND_BUTTON_LOCKED_0)).append("\" alt=\"\"/>"); 249 } 250 result.append("</span></td>\n"); 251 result.append("</tr></table>\n"); 252 result.append("</span>\n"); 253 result.append("</div>\n"); 254 result.append("<div id=\"").append(editId).append("\" class=\"ocms_de_norm\">\n"); 255 256 return result.toString(); 257 } 258 259 /** 260 * Returns the start HTML for an enabled direct edit button.<p> 261 * 262 * @param params the direct edit parameters 263 * @param resourceInfo contains information about the resource to edit 264 * 265 * @return the start HTML for an enabled direct edit button 266 */ 267 public String startDirectEditEnabled(CmsDirectEditParams params, CmsDirectEditResourceInfo resourceInfo) { 268 269 String editLocale = m_cms.getRequestContext().getLocale().toString(); 270 String editId = getNextDirectEditId(); 271 StringBuffer result = new StringBuffer(512); 272 273 String uri = m_cms.getRequestContext().getUri(); 274 275 String editLink = getLink(params.getLinkForEdit()); 276 String editNewLink = CmsEncoder.encode(params.getLinkForNew()); 277 278 result.append("<!-- EDIT BLOCK START (ENABLED): "); 279 result.append(params.m_resourceName); 280 result.append(" ["); 281 result.append(resourceInfo.getResource().getState()); 282 result.append("]"); 283 if (!resourceInfo.getLock().isUnlocked()) { 284 result.append(" locked "); 285 result.append(resourceInfo.getLock().getProject().getName()); 286 } 287 result.append(" -->\n"); 288 289 result.append("<script >\n"); 290 result.append("registerButtonOcms(\"").append(editId).append("\");\n"); 291 result.append("</script>\n"); 292 result.append("<div class=\"ocms_de_bt\" id=\"buttons_").append(editId).append("\">\n"); 293 result.append("<form name=\"form_").append(editId).append("\" id=\"form_").append(editId).append( 294 "\" method=\"post\" action=\"").append(editLink).append("\" class=\"ocms_nomargin\" target=\"_top\">\n"); 295 result.append("<input type=\"hidden\" name=\"resource\" value=\"").append(params.getResourceName()).append( 296 "\"/>\n"); 297 result.append("<input type=\"hidden\" name=\"directedit\" value=\"true\"/>\n"); 298 result.append("<input type=\"hidden\" name=\"elementlanguage\" value=\"").append(editLocale).append("\"/>\n"); 299 result.append("<input type=\"hidden\" name=\"elementname\" value=\"").append(params.getElement()).append( 300 "\"/>\n"); 301 result.append("<input type=\"hidden\" name=\"backlink\" value=\"").append(uri).append("\"/>\n"); 302 result.append("<input type=\"hidden\" name=\"newlink\"/>\n"); 303 result.append("<input type=\"hidden\" name=\"closelink\"/>\n"); 304 result.append("<input type=\"hidden\" name=\"redirect\" value=\"true\"/>\n"); 305 result.append("<input type=\"hidden\" name=\"editortitle\"/>\n"); 306 result.append("</form>\n"); 307 result.append("<table onmouseover=\"activateOcms(\'").append(editId).append( 308 "\');\" onmouseout=\"deactivateOcms(\'").append(editId).append("\');\""); 309 result.append(" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" id=\"table_").append(editId).append( 310 "\"><tr>\n"); 311 if (params.getButtonSelection().isShowEdit()) { 312 result.append("<td class=\"ocms_de\"><a href=\"#\" onclick=\"javascript:submitOcms(\'").append( 313 editId).append("\', \'").append(CmsDirectEditButtonSelection.VALUE_EDIT).append( 314 "\');\" class=\"ocms_button\"><span class=\"ocms_over\" onmouseover=\"className=\'ocms_over\'\" onmouseout=\"className=\'ocms_over\'\" onmousedown=\"className=\'ocms_push\'\" onmouseup=\"className=\'ocms_over\'\">"); 315 if (m_editButtonStyle == 1) { 316 result.append("<span id=\"bt_").append(editId).append( 317 "\" class=\"ocms_combobutton\" style=\"background-image: url(\'").append( 318 CmsWorkplace.getSkinUri()).append("buttons/directedit_cl.png\');\"> ").append( 319 m_messages.key(Messages.GUI_EDITOR_FRONTEND_BUTTON_EDIT_0)).append("</span>"); 320 } else if (m_editButtonStyle == 2) { 321 result.append("<span class=\"ocms_combobutton\" style=\"padding-left: 4px;\">").append( 322 m_messages.key(Messages.GUI_EDITOR_FRONTEND_BUTTON_EDIT_0)).append("</span>"); 323 } else { 324 result.append("<span id=\"bt_").append(editId).append( 325 "\" class=\"ocms_combobutton\" style=\"padding-left: 15px; padding-right: 1px; background-image: url(\'").append( 326 CmsWorkplace.getSkinUri()).append( 327 "buttons/directedit_cl.png\'); background-position: 0px 0px;\" title=\"").append( 328 m_messages.key(Messages.GUI_EDITOR_FRONTEND_BUTTON_EDIT_0)).append("\"> </span>"); 329 } 330 result.append("</span></a></td>\n"); 331 } 332 if (params.getButtonSelection().isShowDelete()) { 333 result.append("<td class=\"ocms_de\"><a href=\"#\" onclick=\"javascript:submitOcms(\'").append( 334 editId).append("\', \'").append(CmsDirectEditButtonSelection.VALUE_DELETE).append( 335 "\');\" class=\"ocms_button\"><span class=\"ocms_over\" onmouseover=\"className=\'ocms_over\'\" onmouseout=\"className=\'ocms_over\'\" onmousedown=\"className=\'ocms_push\'\" onmouseup=\"className=\'ocms_over\'\">"); 336 if (m_editButtonStyle == 1) { 337 result.append("<span id=\"del_").append(editId).append( 338 "\" class=\"ocms_combobutton\" style=\"background-image: url(\'").append( 339 CmsWorkplace.getSkinUri()).append("buttons/deletecontent.png\');\"> ").append( 340 m_messages.key(Messages.GUI_BUTTON_DELETE_0)).append("</span>"); 341 } else if (m_editButtonStyle == 2) { 342 result.append("<span class=\"ocms_combobutton\" style=\"padding-left: 4px;\">").append( 343 m_messages.key(Messages.GUI_BUTTON_DELETE_0)).append("</span>"); 344 } else { 345 result.append("<img border=\"0\" src=\"").append(CmsWorkplace.getSkinUri()).append( 346 "buttons/deletecontent.png\" title=\"").append(m_messages.key(Messages.GUI_BUTTON_DELETE_0)).append( 347 "\" alt=\"\"/>"); 348 } 349 result.append("</span></a></td>\n"); 350 } 351 if (params.getButtonSelection().isShowNew()) { 352 result.append("<td class=\"ocms_de\"><a href=\"#\" onclick=\"javascript:submitOcms(\'").append( 353 editId).append("\', \'").append(CmsDirectEditButtonSelection.VALUE_NEW).append("\', \'").append( 354 editNewLink).append( 355 "\');\" class=\"ocms_button\"><span class=\"ocms_over\" onmouseover=\"className=\'ocms_over\'\" onmouseout=\"className=\'ocms_over\'\" onmousedown=\"className=\'ocms_push\'\" onmouseup=\"className=\'ocms_over\'\">"); 356 if (m_editButtonStyle == 1) { 357 result.append("<span id=\"new_").append(editId).append( 358 "\" class=\"ocms_combobutton\" style=\"background-image: url(\'").append( 359 CmsWorkplace.getSkinUri()).append("buttons/new.png\');\"> ").append( 360 m_messages.key(Messages.GUI_BUTTON_NEW_0)).append("</span>"); 361 } else if (m_editButtonStyle == 2) { 362 result.append("<span class=\"ocms_combobutton\" style=\"padding-left: 4px;\">").append( 363 m_messages.key(Messages.GUI_BUTTON_NEW_0)).append("</span>"); 364 } else { 365 result.append("<img border=\"0\" src=\"").append(CmsWorkplace.getSkinUri()).append( 366 "buttons/new.png\" title=\"").append(m_messages.key(Messages.GUI_BUTTON_NEW_0)).append( 367 "\" alt=\"\"/>"); 368 } 369 result.append("</span></a></td>"); 370 } 371 result.append("</tr></table>\n"); 372 result.append("</div>\n"); 373 result.append("<div id=\"").append(editId).append("\" class=\"ocms_de_norm\">"); 374 return result.toString(); 375 } 376 377 /** 378 * Helper method to convert the content of a resource to a string.<p> 379 * 380 * @param file the file 381 * @return the file content as a string 382 * 383 * @throws CmsException if something goes wrong 384 */ 385 protected String getContentAsString(CmsFile file) throws CmsException { 386 387 CmsProperty p = m_cms.readPropertyObject(file, CmsPropertyDefinition.PROPERTY_CONTENT_ENCODING, true); 388 String e = p.getValue(); 389 if (e == null) { 390 e = OpenCms.getSystemInfo().getDefaultEncoding(); 391 } 392 return CmsEncoder.createString(file.getContents(), e); 393 } 394 395 /** 396 * Prepares the macro resolver which is used to process the included text file.<p> 397 * 398 * @param params the direct edit parameters 399 * 400 * @return the macro resolver 401 */ 402 protected CmsMacroResolver prepareMacroResolverForIncludes(CmsDirectEditParams params) { 403 404 String closeLink = getLink(params.getLinkForClose()); 405 String deleteLink = getLink(params.getLinkForDelete()); 406 String titleForNew = m_messages.key(Messages.GUI_EDITOR_TITLE_NEW_0); 407 String skinUri = CmsWorkplace.getSkinUri(); 408 // resolve macros in include header 409 CmsMacroResolver resolver = CmsMacroResolver.newInstance(); 410 resolver.addMacro("closeLink", closeLink); 411 resolver.addMacro("deleteLink", deleteLink); 412 resolver.addMacro("titleForNew", titleForNew); 413 resolver.addMacro("skinUri", skinUri); 414 return resolver; 415 } 416}