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.updatexml; 029 030import org.opencms.file.CmsFile; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.file.CmsResourceFilter; 034import org.opencms.file.types.CmsResourceTypeXmlContent; 035import org.opencms.file.types.CmsResourceTypeXmlPage; 036import org.opencms.lock.CmsLock; 037import org.opencms.main.CmsException; 038import org.opencms.main.CmsLog; 039import org.opencms.report.A_CmsReportThread; 040import org.opencms.report.I_CmsReport; 041import org.opencms.util.CmsStringUtil; 042 043import java.util.ArrayList; 044import java.util.Iterator; 045import java.util.List; 046 047import org.apache.commons.logging.Log; 048 049/** 050 * Converting xml contents according to new schema. 051 * <p> 052 * 053 * @since 7.0.5 054 */ 055public class CmsUpdateXmlThread extends A_CmsReportThread { 056 057 /** The log object for this class. */ 058 private static final Log LOG = CmsLog.getLog(CmsUpdateXmlThread.class); 059 060 /** Current CmsObject. */ 061 private CmsObject m_cmsObject; 062 063 /** Number of errors while updating. */ 064 private int m_errorUpdate; 065 066 /** Number of locked files during updating. */ 067 private int m_lockedFiles; 068 069 /** Settings. */ 070 private CmsUpdateXmlSettings m_settings; 071 072 /** 073 * Creates a replace html tag Thread.<p> 074 * 075 * @param cms the current cms context. 076 * 077 * @param settings the settings needed to perform the operation. 078 */ 079 public CmsUpdateXmlThread(CmsObject cms, CmsUpdateXmlSettings settings) { 080 081 super(cms, Messages.get().getBundle().key(Messages.GUI_UPDATEXML_THREAD_NAME_0)); 082 initHtmlReport(cms.getRequestContext().getLocale()); 083 m_cmsObject = cms; 084 m_settings = settings; 085 } 086 087 /** 088 * @see org.opencms.report.A_CmsReportThread#getReportUpdate() 089 */ 090 @Override 091 public String getReportUpdate() { 092 093 return getReport().getReportUpdate(); 094 } 095 096 /** 097 * @see java.lang.Runnable#run() 098 */ 099 @Override 100 public void run() { 101 102 I_CmsReport report = getReport(); 103 report.println( 104 Messages.get().container(Messages.RPT_UPDATEXML_BEGIN_UPDATE_THREAD_0), 105 I_CmsReport.FORMAT_HEADLINE); 106 try { 107 // update xml contents 108 updateXmlContents(report, m_settings.getVfsFolder(), m_settings.getIncludeSubFolders(), m_cmsObject); 109 } catch (Throwable f) { 110 m_errorUpdate += 1; 111 report.println(Messages.get().container(Messages.RPT_UPDATETXML_UPDATE_ERROR_0)); 112 if (LOG.isErrorEnabled()) { 113 LOG.error(f.toString()); 114 } 115 } 116 117 // append runtime statistics to report 118 getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_STAT_0)); 119 getReport().println( 120 org.opencms.report.Messages.get().container( 121 org.opencms.report.Messages.RPT_STAT_DURATION_1, 122 getReport().formatRuntime())); 123 getReport().println( 124 Messages.get().container(Messages.RPT_UPDATEXML_END_UPDATE_THREAD_0), 125 I_CmsReport.FORMAT_HEADLINE); 126 } 127 128 /** 129 * Locks the current resource.<p> 130 * 131 * @param cms the current CmsObject 132 * @param cmsResource the resource to lock 133 * @param report the report 134 * 135 * @throws CmsException if some goes wrong 136 */ 137 private boolean lockResource(CmsObject cms, CmsResource cmsResource, I_CmsReport report) throws CmsException { 138 139 CmsLock lock = cms.getLock(getCms().getSitePath(cmsResource)); 140 // check the lock 141 if ((lock != null) 142 && lock.isOwnedBy(getCms().getRequestContext().getCurrentUser()) 143 && lock.isOwnedInProjectBy( 144 getCms().getRequestContext().getCurrentUser(), 145 getCms().getRequestContext().getCurrentProject())) { 146 // prove is current lock from current user in current project 147 return true; 148 } else if ((lock != null) 149 && !lock.isUnlocked() 150 && !lock.isOwnedBy(getCms().getRequestContext().getCurrentUser())) { 151 // the resource is not locked by the current user, so can not lock it 152 m_lockedFiles += 1; 153 return false; 154 } else if ((lock != null) 155 && !lock.isUnlocked() 156 && lock.isOwnedBy(getCms().getRequestContext().getCurrentUser()) 157 && !lock.isOwnedInProjectBy( 158 getCms().getRequestContext().getCurrentUser(), 159 getCms().getRequestContext().getCurrentProject())) { 160 // prove is current lock from current user but not in current project 161 // file is locked by current user but not in current project 162 // change the lock 163 cms.changeLock(getCms().getSitePath(cmsResource)); 164 } else if ((lock != null) && lock.isUnlocked()) { 165 // lock resource from current user in current project 166 cms.lockResource(getCms().getSitePath(cmsResource)); 167 } 168 lock = cms.getLock(getCms().getSitePath(cmsResource)); 169 if ((lock != null) 170 && lock.isOwnedBy(getCms().getRequestContext().getCurrentUser()) 171 && !lock.isOwnedInProjectBy( 172 getCms().getRequestContext().getCurrentUser(), 173 getCms().getRequestContext().getCurrentProject())) { 174 // resource could not be locked 175 m_lockedFiles += 1; 176 177 return false; 178 } 179 // resource is locked successfully 180 return true; 181 } 182 183 /** 184 * The method to update xml contents.<p> 185 * 186 * @param report I_CmsReport 187 * @param resourcePath Path to update xml contents in 188 * @param inclSubFolder true, if also resources in subfolders in the vfs folder shall be updated, otherwise false 189 * @param cmsObject Current CmsObject 190 */ 191 @SuppressWarnings("unchecked") 192 private void updateXmlContents( 193 I_CmsReport report, 194 String resourcePath, 195 boolean inclSubFolder, 196 CmsObject cmsObject) { 197 198 // write parameters to report 199 report.println(Messages.get().container(Messages.RPT_UPDATEXML_BEGIN_UPDATE_0), I_CmsReport.FORMAT_NOTE); 200 report.println(Messages.get().container(Messages.RPT_UPDATEXML_PARAMETERS_0), I_CmsReport.FORMAT_HEADLINE); 201 report.println( 202 Messages.get().container(Messages.RPT_UPDATEXML_PARAMETERS_RESOURCE_PATH_1, resourcePath), 203 I_CmsReport.FORMAT_NOTE); 204 report.println( 205 Messages.get().container( 206 Messages.RPT_UPDATEXML_PARAMETERS_INC_SUBFOLDERS_1, 207 Boolean.valueOf(inclSubFolder).toString()), 208 I_CmsReport.FORMAT_NOTE); 209 210 // check for valid parameters (vfs folder) 211 if (CmsStringUtil.isEmpty(resourcePath)) { 212 report.println(Messages.get().container(Messages.RPT_UPDATEXML_NO_VFS_FOLDER_0), I_CmsReport.FORMAT_ERROR); 213 return; 214 } 215 216 // read all files in the vfs folder 217 report.println(Messages.get().container(Messages.RPT_UPDATEXML_START_SEARCHING_0), I_CmsReport.FORMAT_HEADLINE); 218 List<CmsResource> allFiles = null; 219 try { 220 allFiles = cmsObject.readResources(resourcePath, CmsResourceFilter.DEFAULT, inclSubFolder); 221 } catch (CmsException e) { 222 m_errorUpdate += 1; 223 report.println(Messages.get().container(Messages.RPT_UPDATEXML_SEARCH_ERROR_0), I_CmsReport.FORMAT_ERROR); 224 if (LOG.isErrorEnabled()) { 225 LOG.error(e.getMessageContainer(), e); 226 } 227 report.println(Messages.get().container(Messages.RPT_UPDATEXML_END_UPDATE_0), I_CmsReport.FORMAT_NOTE); 228 return; 229 } 230 231 // get the files to update 232 List<CmsResource> files2Update = new ArrayList<CmsResource>(); 233 Iterator<CmsResource> iter = allFiles.iterator(); 234 while (iter.hasNext()) { 235 CmsResource cmsResource = iter.next(); 236 // only update Xml contents 237 if (cmsResource.isFile() 238 && (CmsResourceTypeXmlContent.isXmlContent(cmsResource) 239 || CmsResourceTypeXmlPage.isXmlPage(cmsResource))) { 240 files2Update.add(cmsResource); 241 } 242 } 243 244 // number of files to update 245 int nrOfFiles = files2Update.size(); 246 report.println( 247 Messages.get().container(Messages.RPT_UPDATEXML_FILES_TO_UPDATE_1, Integer.valueOf(nrOfFiles).toString()), 248 I_CmsReport.FORMAT_NOTE); 249 // the file counter 250 int fileCounter = 0; 251 // update the files 252 if (nrOfFiles > 0) { 253 // report entry 254 report.println( 255 Messages.get().container(Messages.RPT_UPDATEXML_START_UPDATING_0), 256 I_CmsReport.FORMAT_HEADLINE); 257 // loop over all files 258 iter = files2Update.iterator(); 259 while (iter.hasNext()) { 260 CmsResource cmsResource = iter.next(); 261 fileCounter += 1; 262 // report entries 263 report.print( 264 org.opencms.report.Messages.get().container( 265 org.opencms.report.Messages.RPT_SUCCESSION_2, 266 String.valueOf(fileCounter), 267 String.valueOf(nrOfFiles)), 268 I_CmsReport.FORMAT_NOTE); 269 report.print(Messages.get().container(Messages.RPT_UPDATEXML_CURRENT_FILE_0), I_CmsReport.FORMAT_NOTE); 270 report.print( 271 org.opencms.report.Messages.get().container( 272 org.opencms.report.Messages.RPT_ARGUMENT_1, 273 report.removeSiteRoot(cmsResource.getRootPath()))); 274 report.print( 275 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0), 276 I_CmsReport.FORMAT_DEFAULT); 277 278 // get current lock from file 279 try { 280 // try to lock the resource 281 if (!lockResource(cmsObject, cmsResource, report)) { 282 report.println( 283 Messages.get().container( 284 Messages.RPT_UPDATEXML_LOCKED_FILE_0, 285 cmsObject.getSitePath(cmsResource)), 286 I_CmsReport.FORMAT_ERROR); 287 continue; 288 } 289 } catch (CmsException e) { 290 report.println( 291 Messages.get().container( 292 Messages.RPT_UPDATEXML_LOCKED_FILE_0, 293 cmsObject.getSitePath(cmsResource)), 294 I_CmsReport.FORMAT_ERROR); 295 if (LOG.isErrorEnabled()) { 296 LOG.error(e.getMessageContainer(), e); 297 } 298 continue; 299 } 300 301 // write the resource 302 try { 303 // do not change the date last modified 304 long lastModified = cmsResource.getDateLastModified(); 305 CmsFile cmsFile = cmsObject.readFile(cmsResource); 306 cmsFile.setDateLastModified(lastModified); 307 cmsObject.writeFile(cmsFile); 308 } catch (Exception e) { 309 m_errorUpdate += 1; 310 report.println( 311 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_FAILED_0), 312 I_CmsReport.FORMAT_ERROR); 313 if (LOG.isErrorEnabled()) { 314 LOG.error(e.toString()); 315 } 316 continue; 317 } 318 319 // unlock the resource 320 try { 321 cmsObject.unlockResource(cmsObject.getSitePath(cmsResource)); 322 } catch (CmsException e) { 323 m_errorUpdate += 1; 324 report.println( 325 Messages.get().container(Messages.RPT_UPDATEXML_UNLOCK_FILE_0), 326 I_CmsReport.FORMAT_WARNING); 327 if (LOG.isErrorEnabled()) { 328 LOG.error(e.getMessageContainer(), e); 329 } 330 continue; 331 } 332 // successfully updated 333 report.println( 334 org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0), 335 I_CmsReport.FORMAT_OK); 336 } 337 } else { 338 // no files to update 339 report.println(Messages.get().container(Messages.RPT_UPDATEXML_NO_FILES_FOUND_0), I_CmsReport.FORMAT_NOTE); 340 } 341 342 // the results are written in the report 343 report.println(Messages.get().container(Messages.RPT_UPDATEXML_RESULT_0), I_CmsReport.FORMAT_HEADLINE); 344 report.println( 345 Messages.get().container(Messages.RPT_UPDATEXML_FILES_TO_UPDATE_1, Integer.valueOf(nrOfFiles).toString()), 346 I_CmsReport.FORMAT_NOTE); 347 report.println( 348 Messages.get().container( 349 Messages.RPT_UPDATEXML_UPDATE_NUMBER_ERRORS_1, 350 Integer.valueOf(m_errorUpdate).toString()), 351 I_CmsReport.FORMAT_NOTE); 352 report.println( 353 Messages.get().container(Messages.RPT_UPDATEXML_LOCKED_FILES_1, Integer.valueOf(m_lockedFiles).toString()), 354 I_CmsReport.FORMAT_NOTE); 355 if (m_lockedFiles > 0) { 356 report.println(Messages.get().container(Messages.RPT_UPDATEXML_UPDATE_FAILED_0), I_CmsReport.FORMAT_ERROR); 357 } else { 358 report.println(Messages.get().container(Messages.RPT_UPDATEXML_UPDATE_SUCCESS_0), I_CmsReport.FORMAT_OK); 359 } 360 report.println(Messages.get().container(Messages.RPT_UPDATEXML_END_UPDATE_0), I_CmsReport.FORMAT_NOTE); 361 } 362}