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.v7.event.FieldEvents.TextChangeEvent; 056import com.vaadin.server.AbstractErrorMessage.ContentMode; 057import com.vaadin.server.UserError; 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 m_editId = editId; 100 m_editProperty = editProperty; 101 m_fileTable = fileTable; 102 m_context = context; 103 } 104 105 /** 106 * Cancels the edit process. Unlocks the resource if required.<p> 107 * 108 * @see org.opencms.ui.components.I_CmsFilePropertyEditHandler#cancel() 109 */ 110 public void cancel() { 111 112 if (m_lockActionRecord.getChange() == LockChange.locked) { 113 CmsObject cms = A_CmsUI.getCmsObject(); 114 try { 115 CmsResource res = cms.readResource(m_editId); 116 cms.unlockResource(res); 117 } catch (CmsException e) { 118 LOG.warn("Failed to unlock resource " + m_editId.toString(), e); 119 } 120 } 121 CmsAppWorkplaceUi.get().enableGlobalShortcuts(); 122 } 123 124 /** 125 * @see org.opencms.ui.components.I_CmsFilePropertyEditHandler#save(java.lang.String) 126 */ 127 public void save(String value) { 128 129 try { 130 CmsObject cms = A_CmsUI.getCmsObject(); 131 CmsResource res = cms.readResource(m_editId); 132 try { 133 if (CmsResourceTableProperty.PROPERTY_RESOURCE_NAME.equals(m_editProperty)) { 134 String sourcePath = cms.getSitePath(res); 135 cms.renameResource( 136 sourcePath, 137 CmsStringUtil.joinPaths(CmsResource.getParentFolder(sourcePath), value)); 138 } else if (m_editProperty.isEditProperty()) { 139 140 CmsProperty prop = new CmsProperty(m_editProperty.getEditPropertyId(), value, null); 141 cms.writePropertyObject(cms.getSitePath(res), prop); 142 } 143 } finally { 144 if (m_lockActionRecord.getChange() == LockChange.locked) { 145 CmsResource updatedRes = cms.readResource(res.getStructureId(), CmsResourceFilter.ALL); 146 try { 147 cms.unlockResource(updatedRes); 148 } catch (CmsLockException e) { 149 LOG.warn(e.getLocalizedMessage(), e); 150 } 151 } 152 CmsAppWorkplaceUi.get().enableGlobalShortcuts(); 153 m_fileTable.clearSelection(); 154 } 155 m_context.finish(Collections.singletonList(m_editId)); 156 } catch (CmsException e) { 157 LOG.error("Exception while saving changed " + m_editProperty + " to resource " + m_editId, e); 158 m_context.error(e); 159 } 160 161 } 162 163 /** 164 * @see org.opencms.ui.components.I_CmsFilePropertyEditHandler#start() 165 */ 166 public void start() { 167 168 CmsObject cms = A_CmsUI.getCmsObject(); 169 try { 170 CmsResource res = cms.readResource(m_editId); 171 m_lockActionRecord = CmsLockUtil.ensureLock(cms, res); 172 CmsAppWorkplaceUi.get().disableGlobalShortcuts(); 173 m_fileTable.startEdit(m_editId, m_editProperty, this); 174 } catch (CmsException e) { 175 CmsErrorDialog.showErrorDialog(e); 176 LOG.debug(e.getLocalizedMessage(), e); 177 } 178 } 179 180 /** 181 * @see com.vaadin.event.FieldEvents.TextChangeListener#textChange(com.vaadin.event.FieldEvents.TextChangeEvent) 182 */ 183 public void textChange(TextChangeEvent event) { 184 185 TextField tf = (TextField)event.getSource(); 186 try { 187 validate(event.getText()); 188 tf.setComponentError(null); 189 } catch (InvalidValueException e) { 190 tf.setComponentError(new UserError(e.getHtmlMessage(), ContentMode.HTML, null)); 191 } 192 } 193 194 /** 195 * @see com.vaadin.data.Validator#validate(java.lang.Object) 196 */ 197 public void validate(Object value) throws InvalidValueException { 198 199 if ((m_editProperty == CmsResourceTableProperty.PROPERTY_RESOURCE_NAME) && (value instanceof String)) { 200 try { 201 String newName = (String)value; 202 CmsResource.checkResourceName(newName); 203 CmsObject cms = A_CmsUI.getCmsObject(); 204 CmsResource res = cms.readResource(m_editId); 205 if (!res.getName().equals(newName)) { 206 String sourcePath = cms.getSitePath(res); 207 if (cms.existsResource(CmsStringUtil.joinPaths(CmsResource.getParentFolder(sourcePath), newName))) { 208 throw new InvalidValueException("The selected filename already exists."); 209 } 210 } 211 } catch (CmsIllegalArgumentException e) { 212 throw new InvalidValueException(e.getLocalizedMessage(A_CmsUI.get().getLocale())); 213 } catch (CmsException e) { 214 LOG.warn("Error while validating new filename", e); 215 throw new InvalidValueException(e.getLocalizedMessage(A_CmsUI.get().getLocale())); 216 } 217 } 218 } 219}