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.ui.contextmenu; 029 030import org.opencms.file.CmsObject; 031import org.opencms.file.CmsProperty; 032import org.opencms.file.CmsResource; 033import org.opencms.file.CmsResourceFilter; 034import org.opencms.lock.CmsLockActionRecord; 035import org.opencms.lock.CmsLockActionRecord.LockChange; 036import org.opencms.lock.CmsLockException; 037import org.opencms.lock.CmsLockUtil; 038import org.opencms.main.CmsException; 039import org.opencms.main.CmsIllegalArgumentException; 040import org.opencms.main.CmsLog; 041import org.opencms.ui.A_CmsUI; 042import org.opencms.ui.I_CmsDialogContext; 043import org.opencms.ui.apps.CmsAppWorkplaceUi; 044import org.opencms.ui.components.CmsErrorDialog; 045import org.opencms.ui.components.CmsFileTable; 046import org.opencms.ui.components.CmsResourceTableProperty; 047import org.opencms.ui.components.I_CmsFilePropertyEditHandler; 048import org.opencms.util.CmsStringUtil; 049import org.opencms.util.CmsUUID; 050 051import java.util.Collections; 052 053import org.apache.commons.logging.Log; 054 055import com.vaadin.server.AbstractErrorMessage.ContentMode; 056import com.vaadin.server.UserError; 057import com.vaadin.v7.event.FieldEvents.TextChangeEvent; 058import com.vaadin.v7.ui.TextField; 059 060/** 061 * Handles inline editing within the file table.<p> 062 */ 063public class CmsContextMenuEditHandler implements I_CmsFilePropertyEditHandler { 064 065 /** Logger instance for this class. */ 066 private static final Log LOG = CmsLog.getLog(CmsContextMenuEditHandler.class); 067 068 /** The serial version id. */ 069 private static final long serialVersionUID = -9160838301862765592L; 070 071 /** The dialog context. */ 072 private I_CmsDialogContext m_context; 073 074 /** The edited content structure id. */ 075 private CmsUUID m_editId; 076 077 /** The edited property. */ 078 private CmsResourceTableProperty m_editProperty; 079 080 /** The file table. */ 081 private CmsFileTable m_fileTable; 082 083 /** The lock action record. */ 084 private CmsLockActionRecord m_lockActionRecord; 085 086 /** 087 * Constructor.<p> 088 * 089 * @param editId the content structure id 090 * @param editProperty the property to edit 091 * @param fileTable the file table 092 * @param context the dialog context 093 */ 094 public CmsContextMenuEditHandler( 095 CmsUUID editId, 096 CmsResourceTableProperty editProperty, 097 CmsFileTable fileTable, 098 I_CmsDialogContext context) { 099 100 m_editId = editId; 101 m_editProperty = editProperty; 102 m_fileTable = fileTable; 103 m_context = context; 104 } 105 106 /** 107 * Cancels the edit process. Unlocks the resource if required.<p> 108 * 109 * @see org.opencms.ui.components.I_CmsFilePropertyEditHandler#cancel() 110 */ 111 public void cancel() { 112 113 if (m_lockActionRecord.getChange() == LockChange.locked) { 114 CmsObject cms = A_CmsUI.getCmsObject(); 115 try { 116 CmsResource res = cms.readResource(m_editId, CmsResourceFilter.IGNORE_EXPIRATION); 117 cms.unlockResource(res); 118 } catch (CmsException e) { 119 LOG.warn("Failed to unlock resource " + m_editId.toString(), e); 120 } 121 } 122 CmsAppWorkplaceUi.get().enableGlobalShortcuts(); 123 } 124 125 /** 126 * @see org.opencms.ui.components.I_CmsFilePropertyEditHandler#save(java.lang.String) 127 */ 128 public void save(String value) { 129 130 try { 131 CmsObject cms = A_CmsUI.getCmsObject(); 132 CmsResource res = cms.readResource(m_editId, CmsResourceFilter.IGNORE_EXPIRATION); 133 try { 134 if (CmsResourceTableProperty.PROPERTY_RESOURCE_NAME.equals(m_editProperty)) { 135 String sourcePath = cms.getSitePath(res); 136 cms.renameResource( 137 sourcePath, 138 CmsStringUtil.joinPaths(CmsResource.getParentFolder(sourcePath), value)); 139 } else if (m_editProperty.isEditProperty()) { 140 141 CmsProperty prop = new CmsProperty(m_editProperty.getEditPropertyId(), value, null); 142 cms.writePropertyObject(cms.getSitePath(res), prop); 143 } 144 } finally { 145 if (m_lockActionRecord.getChange() == LockChange.locked) { 146 CmsResource updatedRes = cms.readResource(res.getStructureId(), CmsResourceFilter.ALL); 147 try { 148 cms.unlockResource(updatedRes); 149 } catch (CmsLockException e) { 150 LOG.warn(e.getLocalizedMessage(), e); 151 } 152 } 153 CmsAppWorkplaceUi.get().enableGlobalShortcuts(); 154 m_fileTable.clearSelection(); 155 } 156 m_context.finish(Collections.singletonList(m_editId)); 157 } catch (CmsException e) { 158 LOG.error("Exception while saving changed " + m_editProperty + " to resource " + m_editId, e); 159 m_context.error(e); 160 } 161 162 } 163 164 /** 165 * @see org.opencms.ui.components.I_CmsFilePropertyEditHandler#start() 166 */ 167 public void start() { 168 169 CmsObject cms = A_CmsUI.getCmsObject(); 170 try { 171 CmsResource res = cms.readResource(m_editId, CmsResourceFilter.IGNORE_EXPIRATION); 172 m_lockActionRecord = CmsLockUtil.ensureLock(cms, res); 173 CmsAppWorkplaceUi.get().disableGlobalShortcuts(); 174 m_fileTable.startEdit(m_editId, m_editProperty, this); 175 } catch (CmsException e) { 176 CmsErrorDialog.showErrorDialog(e); 177 LOG.debug(e.getLocalizedMessage(), e); 178 } 179 } 180 181 /** 182 * @see com.vaadin.event.FieldEvents.TextChangeListener#textChange(com.vaadin.event.FieldEvents.TextChangeEvent) 183 */ 184 public void textChange(TextChangeEvent event) { 185 186 TextField tf = (TextField)event.getSource(); 187 try { 188 validate(event.getText()); 189 tf.setComponentError(null); 190 } catch (InvalidValueException e) { 191 tf.setComponentError(new UserError(e.getHtmlMessage(), ContentMode.HTML, null)); 192 } 193 } 194 195 /** 196 * @see com.vaadin.data.Validator#validate(java.lang.Object) 197 */ 198 public void validate(Object value) throws InvalidValueException { 199 200 if ((m_editProperty == CmsResourceTableProperty.PROPERTY_RESOURCE_NAME) && (value instanceof String)) { 201 try { 202 String newName = (String)value; 203 CmsResource.checkResourceName(newName); 204 CmsObject cms = A_CmsUI.getCmsObject(); 205 CmsResource res = cms.readResource(m_editId, CmsResourceFilter.IGNORE_EXPIRATION); 206 if (!res.getName().equals(newName)) { 207 String sourcePath = cms.getSitePath(res); 208 if (cms.existsResource( 209 CmsStringUtil.joinPaths(CmsResource.getParentFolder(sourcePath), newName), 210 CmsResourceFilter.IGNORE_EXPIRATION)) { 211 throw new InvalidValueException("The selected filename already exists."); 212 } 213 } 214 } catch (CmsIllegalArgumentException e) { 215 throw new InvalidValueException(e.getLocalizedMessage(A_CmsUI.get().getLocale())); 216 } catch (CmsException e) { 217 LOG.warn("Error while validating new filename", e); 218 throw new InvalidValueException(e.getLocalizedMessage(A_CmsUI.get().getLocale())); 219 } 220 } 221 } 222}