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.workplace.tools.content; 029 030import org.opencms.file.CmsProperty; 031import org.opencms.file.CmsPropertyDefinition; 032import org.opencms.file.CmsResource; 033import org.opencms.file.CmsVfsException; 034import org.opencms.i18n.CmsMessages; 035import org.opencms.jsp.CmsJspActionElement; 036import org.opencms.lock.CmsLock; 037import org.opencms.main.CmsException; 038import org.opencms.main.OpenCms; 039import org.opencms.workplace.CmsDialog; 040import org.opencms.workplace.CmsWorkplace; 041import org.opencms.workplace.CmsWorkplaceSettings; 042 043import java.util.ArrayList; 044import java.util.Collections; 045import java.util.Iterator; 046import java.util.List; 047 048import javax.servlet.http.HttpServletRequest; 049import javax.servlet.http.HttpServletResponse; 050import javax.servlet.jsp.JspException; 051import javax.servlet.jsp.PageContext; 052 053/** 054 * Provides methods for the delete property definition dialog.<p> 055 * 056 * @since 6.0.0 057 */ 058public class CmsPropertyDelete extends CmsDialog { 059 060 /** Value for the action: delete cascade. */ 061 public static final int ACTION_DELETE_CASCADE = 100; 062 063 /** Request parameter value for the action: delete cascade. */ 064 public static final String DIALOG_DELETE_CASCADE = "deletecascade"; 065 066 /** The dialog type. */ 067 public static final String DIALOG_TYPE = "propertydelete"; 068 069 /** Request parameter name for the property name. */ 070 public static final String PARAM_PROPERTYNAME = "propertyname"; 071 072 private String m_paramPropertyName; 073 074 /** 075 * Public constructor with JSP action element.<p> 076 * 077 * @param jsp an initialized JSP action element 078 */ 079 public CmsPropertyDelete(CmsJspActionElement jsp) { 080 081 super(jsp); 082 } 083 084 /** 085 * Public constructor with JSP variables.<p> 086 * 087 * @param context the JSP page context 088 * @param req the JSP request 089 * @param res the JSP response 090 */ 091 public CmsPropertyDelete(PageContext context, HttpServletRequest req, HttpServletResponse res) { 092 093 this(new CmsJspActionElement(context, req, res)); 094 } 095 096 /** 097 * Deletes the property definition.<p> 098 * 099 * @throws JspException if problems including sub-elements occur 100 */ 101 public void actionDelete() throws JspException { 102 103 // save initialized instance of this class in request attribute for included sub-elements 104 getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, this); 105 try { 106 getCms().deletePropertyDefinition(getParamPropertyName()); 107 // close the dialog 108 actionCloseDialog(); 109 } catch (Throwable e) { 110 // error while deleting property definition, show error dialog 111 includeErrorpage(this, e); 112 } 113 } 114 115 /** 116 * Deletes the property definition by cascading the properties on resources.<p> 117 * 118 * @throws JspException if problems including sub-elements occur 119 */ 120 public void actionDeleteCascade() throws JspException { 121 122 // save initialized instance of this class in request attribute for included sub-elements 123 getJsp().getRequest().setAttribute(SESSION_WORKPLACE_CLASS, this); 124 try { 125 // list of all resources containing this propertydefinition 126 List resourcesWithProperty = getCms().readResourcesWithProperty(getParamPropertyName()); 127 // list of all resources locked by another user, containing this propertydefinition 128 List resourcesLockedByOtherUser = getResourcesLockedByOtherUser(resourcesWithProperty); 129 // do the following operations only if all of the resources are not locked by another user 130 if (resourcesLockedByOtherUser.isEmpty()) { 131 // save the site root 132 String storedSiteRoot = getCms().getRequestContext().getSiteRoot(); 133 try { 134 // change to the root site 135 getCms().getRequestContext().setSiteRoot("/"); 136 137 Iterator i = resourcesWithProperty.iterator(); 138 while (i.hasNext()) { 139 CmsResource resource = (CmsResource)i.next(); 140 // read the property object 141 CmsProperty property = getCms().readPropertyObject( 142 resource.getRootPath(), 143 getParamPropertyName(), 144 false); 145 // try to delete the property if it is not the NULL PROPERTY 146 // if the property is the NULL PROPERTY, it only had a shared 147 // value which was deleted at a sibling which was already processed 148 if (!property.isNullProperty()) { 149 CmsLock lock = getCms().getLock(resource); 150 if (lock.isUnlocked()) { 151 // lock the resource for the current (Admin) user 152 getCms().lockResource(resource.getRootPath()); 153 } 154 property.setStructureValue(CmsProperty.DELETE_VALUE); 155 property.setResourceValue(CmsProperty.DELETE_VALUE); 156 // write the property with the null value to the resource and cascade it from the definition 157 getCms().writePropertyObject(resource.getRootPath(), property); 158 // unlock the resource 159 getCms().unlockResource(resource.getRootPath()); 160 } 161 } 162 // delete the property definition at last 163 getCms().deletePropertyDefinition(getParamPropertyName()); 164 } finally { 165 // restore the siteroot 166 getCms().getRequestContext().setSiteRoot(storedSiteRoot); 167 // close the dialog 168 actionCloseDialog(); 169 } 170 } else { 171 172 StringBuffer reason = new StringBuffer(); 173 reason.append(dialogWhiteBoxStart()); 174 reason.append(buildResourceList(resourcesLockedByOtherUser, true)); 175 reason.append(dialogWhiteBoxEnd()); 176 throw new CmsVfsException( 177 Messages.get().container(Messages.ERR_DEL_PROP_RESOURCES_LOCKED_1, reason.toString())); 178 } 179 } catch (Throwable e) { 180 // error while deleting property definition, show error dialog 181 includeErrorpage(this, e); 182 } 183 } 184 185 /** 186 * Builds a HTML list of Resources that use the specified property.<p> 187 * 188 * @throws CmsException if operation was not successful 189 * 190 * @return the HTML String for the Resource list 191 */ 192 public String buildResourceList() throws CmsException { 193 194 List resourcesWithProperty = getCms().readResourcesWithProperty(getParamPropertyName()); 195 196 return buildResourceList(resourcesWithProperty, false); 197 } 198 199 /** 200 * Builds a HTML list of Resources.<p> 201 * 202 * Columns: Type, Name, Uri, Value of the property, locked by(optional).<p> 203 * 204 * @param resourceList a list of resources 205 * @param lockInfo a boolean to decide if the locked info should be shown or not 206 * @throws CmsException if operation was not successful 207 * 208 * @return the HTML String for the Resource list 209 */ 210 public String buildResourceList(List resourceList, boolean lockInfo) throws CmsException { 211 212 // reverse the resource list 213 Collections.reverse(resourceList); 214 CmsMessages messages = Messages.get().getBundle(getLocale()); 215 StringBuffer result = new StringBuffer(); 216 result.append("<table border=\"0\" width=\"100%\" cellpadding=\"1\" cellspacing=\"1\">\n"); 217 result.append("<tr>\n"); 218 // Type 219 result.append("\t<td style=\"width:5%;\" class=\"textbold\">"); 220 result.append(messages.key(Messages.GUI_INPUT_TYPE_0)); 221 result.append("</td>\n"); 222 // Uri 223 result.append("\t<td style=\"width:40%;\" class=\"textbold\">"); 224 result.append(messages.key(Messages.GUI_INPUT_ADRESS_0)); 225 result.append("</td>\n"); 226 // Name 227 result.append("\t<td style=\"width:25%;\" class=\"textbold\">"); 228 result.append(messages.key(Messages.GUI_INPUT_TITLE_0)); 229 result.append("</td>\n"); 230 if (!lockInfo) { 231 // Property value 232 result.append("\t<td style=\"width:30%;\" class=\"textbold\">"); 233 result.append(messages.key(Messages.GUI_INPUT_PROPERTYVALUE_0)); 234 result.append("</td>\n"); 235 } 236 if (lockInfo) { 237 // Property value 238 result.append("\t<td style=\"width:30%;\" class=\"textbold\">"); 239 result.append(messages.key(Messages.GUI_EXPLORER_LOCKEDBY_0)); 240 result.append("</td>\n"); 241 result.append("</tr>\n"); 242 } 243 result.append("</tr>\n"); 244 result.append("<tr><td colspan=\"4\"><span style=\"height: 6px;\"> </span></td></tr>\n"); 245 246 String storedSiteRoot = getCms().getRequestContext().getSiteRoot(); 247 try { 248 getCms().getRequestContext().setSiteRoot("/"); 249 Iterator i = resourceList.iterator(); 250 while (i.hasNext()) { 251 CmsResource resource = (CmsResource)i.next(); 252 String filetype = OpenCms.getResourceManager().getResourceType(resource.getTypeId()).getTypeName(); 253 result.append("<tr>\n"); 254 // file type 255 result.append("\t<td>"); 256 result.append("<img src=\""); 257 result.append(getSkinUri()); 258 result.append(CmsWorkplace.RES_PATH_FILETYPES); 259 result.append(filetype); 260 result.append(".gif\">"); 261 result.append("</td>\n"); 262 // file address 263 result.append("\t<td>"); 264 result.append(resource.getRootPath()); 265 result.append("</td>\n"); 266 // title 267 result.append("\t<td>"); 268 result.append(getJsp().property(CmsPropertyDefinition.PROPERTY_TITLE, resource.getRootPath(), "")); 269 result.append("</td>\n"); 270 // current value of the property 271 if (!lockInfo) { 272 result.append("\t<td>"); 273 result.append(getJsp().property(getParamPropertyName(), resource.getRootPath())); 274 result.append("</td>\n"); 275 } 276 // locked by user 277 if (lockInfo) { 278 CmsLock lock = getCms().getLock(resource); 279 result.append("\t<td>"); 280 result.append(getCms().readUser(lock.getUserId()).getName()); 281 result.append("</td>\n"); 282 } 283 result.append("</tr>\n"); 284 } 285 result.append("</table>\n"); 286 } finally { 287 getCms().getRequestContext().setSiteRoot(storedSiteRoot); 288 } 289 290 return result.toString(); 291 } 292 293 /** 294 * Builds the html for the property definition select box.<p> 295 * 296 * @param attributes optional attributes for the <select> tag 297 * @return the html for the property definition select box 298 */ 299 public String buildSelectProperty(String attributes) { 300 301 return CmsPropertyChange.buildSelectProperty( 302 getCms(), 303 Messages.get().getBundle(getLocale()).key(Messages.GUI_PLEASE_SELECT_0), 304 attributes, 305 ""); 306 } 307 308 /** 309 * Returns the value of the propertyname parameter.<p> 310 * 311 * @return the value of the propertyname parameter 312 */ 313 public String getParamPropertyName() { 314 315 return m_paramPropertyName; 316 } 317 318 /** 319 * Sets the value of the propertyname parameter.<p> 320 * 321 * @param paramPropertyName the value of the propertyname parameter 322 */ 323 public void setParamPropertyName(String paramPropertyName) { 324 325 m_paramPropertyName = paramPropertyName; 326 } 327 328 /** 329 * @see org.opencms.workplace.CmsWorkplace#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest) 330 */ 331 @Override 332 protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) { 333 334 // fill the parameter values in the get/set methods 335 fillParamValues(request); 336 // set the dialog type 337 setParamDialogtype(DIALOG_TYPE); 338 // set the action for the JSP switch 339 if (DIALOG_OK.equals(getParamAction())) { 340 setAction(ACTION_OK); 341 setParamTitle(Messages.get().getBundle(getLocale()).key(Messages.GUI_TITLE_PROPERTYDELETE_0) 342 + ": " 343 + getParamPropertyName()); 344 } else if (DIALOG_CANCEL.equals(getParamAction())) { 345 setAction(ACTION_CANCEL); 346 } else if (DIALOG_DELETE_CASCADE.equals(getParamAction())) { 347 setAction(ACTION_DELETE_CASCADE); 348 } else { 349 setAction(ACTION_DEFAULT); 350 // build title for change property value dialog 351 setParamTitle(Messages.get().getBundle(getLocale()).key(Messages.GUI_TITLE_PROPERTYDELETE_0)); 352 } 353 } 354 355 /** 356 * Returns a list of resources that are locked by another user as the current user.<p> 357 * 358 * @param resourceList the list of all (mixed) resources 359 * 360 * @return a list of resources that are locked by another user as the current user 361 * @throws CmsException if the getLock operation fails 362 */ 363 private List getResourcesLockedByOtherUser(List resourceList) throws CmsException { 364 365 List lockedResourcesByOtherUser = new ArrayList(); 366 Iterator i = resourceList.iterator(); 367 while (i.hasNext()) { 368 CmsResource resource = (CmsResource)i.next(); 369 // get the lock state for the resource 370 CmsLock lock = getCms().getLock(resource); 371 // add this resource to the list if this is locked by another user 372 if (!lock.isUnlocked() && !lock.isOwnedBy(getCms().getRequestContext().getCurrentUser())) { 373 lockedResourcesByOtherUser.add(resource); 374 } 375 } 376 377 return lockedResourcesByOtherUser; 378 } 379}