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.dialogs; 029 030import org.opencms.file.CmsFile; 031import org.opencms.file.CmsObject; 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.CmsLog; 040import org.opencms.main.OpenCms; 041import org.opencms.ui.A_CmsUI; 042import org.opencms.ui.CmsVaadinUtils; 043import org.opencms.ui.I_CmsDialogContext; 044import org.opencms.ui.components.CmsBasicDialog; 045import org.opencms.ui.components.CmsDateField; 046import org.opencms.ui.components.CmsOkCancelActionHandler; 047import org.opencms.util.CmsUUID; 048import org.opencms.xml.content.CmsXmlContent; 049 050import java.time.LocalDateTime; 051import java.util.ArrayList; 052import java.util.Date; 053import java.util.Iterator; 054import java.util.List; 055 056import org.apache.commons.logging.Log; 057 058import com.google.common.collect.Lists; 059import com.vaadin.ui.Button; 060import com.vaadin.ui.Button.ClickEvent; 061import com.vaadin.ui.Button.ClickListener; 062import com.vaadin.ui.CheckBox; 063 064/** 065 * Dialog used to change resource modification times.<p> 066 */ 067public class CmsTouchDialog extends CmsBasicDialog { 068 069 /** Logger for this class. */ 070 private static final Log LOG = CmsLog.getLog(CmsTouchDialog.class); 071 072 /** Serial version id. */ 073 private static final long serialVersionUID = 1L; 074 075 /** The dialog context. */ 076 protected I_CmsDialogContext m_context; 077 078 /** The Cancel button. */ 079 private Button m_cancelButton; 080 081 /** The date selection field. */ 082 private CmsDateField m_dateField; 083 084 /** Check box to enable/disable modification of children. */ 085 private CheckBox m_modifySubresourcesField; 086 087 /** The OK button. */ 088 private Button m_okButton; 089 090 /** Checkbox to enable/disable rewriting of contents. */ 091 private CheckBox m_rewriteContentField; 092 093 /** 094 * Creates a new instance.<p> 095 * 096 * @param context the dialog context 097 */ 098 public CmsTouchDialog(I_CmsDialogContext context) { 099 100 m_context = context; 101 boolean hasFolders = false; 102 103 for (CmsResource resource : context.getResources()) { 104 if (resource.isFolder()) { 105 hasFolders = true; 106 break; 107 } 108 } 109 110 CmsVaadinUtils.readAndLocalizeDesign( 111 this, 112 OpenCms.getWorkplaceManager().getMessages(A_CmsUI.get().getLocale()), 113 null); 114 m_modifySubresourcesField.setVisible(hasFolders); 115 116 m_cancelButton.addClickListener(new ClickListener() { 117 118 private static final long serialVersionUID = 1L; 119 120 public void buttonClick(ClickEvent event) { 121 122 cancel(); 123 } 124 125 }); 126 127 m_okButton.addClickListener(new ClickListener() { 128 129 private static final long serialVersionUID = 1L; 130 131 public void buttonClick(ClickEvent event) { 132 133 submit(); 134 } 135 }); 136 m_dateField.setValue(LocalDateTime.now()); 137 displayResourceInfo(m_context.getResources()); 138 setActionHandler(new CmsOkCancelActionHandler() { 139 140 private static final long serialVersionUID = 1L; 141 142 @Override 143 protected void cancel() { 144 145 CmsTouchDialog.this.cancel(); 146 } 147 148 @Override 149 protected void ok() { 150 151 submit(); 152 } 153 }); 154 } 155 156 /** 157 * Touches the selected files.<p> 158 * 159 * @throws CmsException if something goes wrong 160 */ 161 protected void touchFiles() throws CmsException { 162 163 Date touchDate = m_dateField.getDate(); 164 boolean validDate = touchDate != null; 165 long touchTime = touchDate != null ? touchDate.getTime() : 0; 166 boolean recursive = m_modifySubresourcesField.getValue().booleanValue(); 167 boolean rewriteContent = m_rewriteContentField.getValue().booleanValue(); 168 List<CmsUUID> changedIds = Lists.newArrayList(); 169 for (CmsResource resource : m_context.getResources()) { 170 CmsLockActionRecord actionRecord = null; 171 try { 172 actionRecord = CmsLockUtil.ensureLock(m_context.getCms(), resource); 173 touchSingleResource( 174 m_context.getCms().getSitePath(resource), 175 touchTime, 176 recursive, 177 validDate, 178 rewriteContent); 179 changedIds.add(resource.getStructureId()); 180 } finally { 181 if ((actionRecord != null) && (actionRecord.getChange() == LockChange.locked)) { 182 try { 183 m_context.getCms().unlockResource(resource); 184 } catch (CmsLockException e) { 185 LOG.warn(e.getLocalizedMessage(), e); 186 } 187 } 188 189 } 190 191 } 192 m_context.finish(changedIds); 193 194 } 195 196 /** 197 * Cancels the dialog.<p> 198 */ 199 void cancel() { 200 201 m_context.finish(new ArrayList<CmsUUID>()); 202 } 203 204 /** 205 * Submits the dialog.<p> 206 */ 207 void submit() { 208 209 try { 210 touchFiles(); 211 } catch (Exception e) { 212 m_context.error(e); 213 } 214 } 215 216 /** 217 * Rewrites the content of the given file.<p> 218 * 219 * @param resource the resource to rewrite the content for 220 * 221 * @throws CmsException if something goes wrong 222 */ 223 private void hardTouch(CmsResource resource) throws CmsException { 224 225 CmsFile file = m_context.getCms().readFile(resource); 226 CmsObject cms = OpenCms.initCmsObject(m_context.getCms()); 227 cms.getRequestContext().setAttribute(CmsXmlContent.AUTO_CORRECTION_ATTRIBUTE, Boolean.TRUE); 228 file.setContents(file.getContents()); 229 cms.writeFile(file); 230 } 231 232 /** 233 * Performs a touch operation for a single resource.<p> 234 * 235 * @param resourceName the resource name of the resource to touch 236 * @param timeStamp the new time stamp 237 * @param recursive the flag if the touch operation is recursive 238 * @param correctDate the flag if the new time stamp is a correct date 239 * @param touchContent if the content has to be rewritten 240 * 241 * @throws CmsException if touching the resource fails 242 */ 243 private void touchSingleResource( 244 String resourceName, 245 long timeStamp, 246 boolean recursive, 247 boolean correctDate, 248 boolean touchContent) 249 throws CmsException { 250 251 CmsObject cms = m_context.getCms(); 252 CmsResource sourceRes = cms.readResource(resourceName, CmsResourceFilter.ALL); 253 if (!correctDate) { 254 // no date value entered, use current resource modification date 255 timeStamp = sourceRes.getDateLastModified(); 256 } 257 258 if (touchContent) { 259 if (sourceRes.isFile()) { 260 hardTouch(sourceRes); 261 } else if (recursive) { 262 Iterator<CmsResource> it = cms.readResources(resourceName, CmsResourceFilter.ALL, true).iterator(); 263 while (it.hasNext()) { 264 CmsResource subRes = it.next(); 265 if (subRes.isFile()) { 266 hardTouch(subRes); 267 } 268 } 269 } 270 } 271 272 cms.setDateLastModified(resourceName, timeStamp, recursive); 273 274 } 275}