/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * For further information about Alkacon Software GmbH, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.workplace.tools.content.updatexml; import org.opencms.file.CmsFile; import org.opencms.file.CmsObject; import org.opencms.file.CmsResource; import org.opencms.file.CmsResourceFilter; import org.opencms.file.types.CmsResourceTypeXmlContent; import org.opencms.file.types.CmsResourceTypeXmlPage; import org.opencms.lock.CmsLock; import org.opencms.main.CmsException; import org.opencms.main.CmsLog; import org.opencms.report.A_CmsReportThread; import org.opencms.report.I_CmsReport; import org.opencms.util.CmsStringUtil; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; /** * Converting xml contents according to new schema. * <p> * * @since 7.0.5 */ public class CmsUpdateXmlThread extends A_CmsReportThread { /** The log object for this class. */ private static final Log LOG = CmsLog.getLog(CmsUpdateXmlThread.class); /** Current CmsObject. */ private CmsObject m_cmsObject; /** Number of errors while updating. */ private int m_errorUpdate; /** Number of locked files during updating. */ private int m_lockedFiles; /** Settings. */ private CmsUpdateXmlSettings m_settings; /** * Creates a replace html tag Thread.<p> * * @param cms the current cms context. * * @param settings the settings needed to perform the operation. */ public CmsUpdateXmlThread(CmsObject cms, CmsUpdateXmlSettings settings) { super(cms, Messages.get().getBundle().key(Messages.GUI_UPDATEXML_THREAD_NAME_0)); initHtmlReport(cms.getRequestContext().getLocale()); m_cmsObject = cms; m_settings = settings; } /** * @see org.opencms.report.A_CmsReportThread#getReportUpdate() */ @Override public String getReportUpdate() { return getReport().getReportUpdate(); } /** * @see java.lang.Runnable#run() */ @Override public void run() { I_CmsReport report = getReport(); report.println( Messages.get().container(Messages.RPT_UPDATEXML_BEGIN_UPDATE_THREAD_0), I_CmsReport.FORMAT_HEADLINE); try { // update xml contents updateXmlContents(report, m_settings.getVfsFolder(), m_settings.getIncludeSubFolders(), m_cmsObject); } catch (Throwable f) { m_errorUpdate += 1; report.println(Messages.get().container(Messages.RPT_UPDATETXML_UPDATE_ERROR_0)); if (LOG.isErrorEnabled()) { LOG.error(f.toString()); } } // append runtime statistics to report getReport().print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_STAT_0)); getReport().println( org.opencms.report.Messages.get().container( org.opencms.report.Messages.RPT_STAT_DURATION_1, getReport().formatRuntime())); getReport().println( Messages.get().container(Messages.RPT_UPDATEXML_END_UPDATE_THREAD_0), I_CmsReport.FORMAT_HEADLINE); } /** * Locks the current resource.<p> * * @param cms the current CmsObject * @param cmsResource the resource to lock * @param report the report * * @throws CmsException if some goes wrong */ private boolean lockResource(CmsObject cms, CmsResource cmsResource, I_CmsReport report) throws CmsException { CmsLock lock = cms.getLock(getCms().getSitePath(cmsResource)); // check the lock if ((lock != null) && lock.isOwnedBy(getCms().getRequestContext().getCurrentUser()) && lock.isOwnedInProjectBy( getCms().getRequestContext().getCurrentUser(), getCms().getRequestContext().getCurrentProject())) { // prove is current lock from current user in current project return true; } else if ((lock != null) && !lock.isUnlocked() && !lock.isOwnedBy(getCms().getRequestContext().getCurrentUser())) { // the resource is not locked by the current user, so can not lock it m_lockedFiles += 1; return false; } else if ((lock != null) && !lock.isUnlocked() && lock.isOwnedBy(getCms().getRequestContext().getCurrentUser()) && !lock.isOwnedInProjectBy( getCms().getRequestContext().getCurrentUser(), getCms().getRequestContext().getCurrentProject())) { // prove is current lock from current user but not in current project // file is locked by current user but not in current project // change the lock cms.changeLock(getCms().getSitePath(cmsResource)); } else if ((lock != null) && lock.isUnlocked()) { // lock resource from current user in current project cms.lockResource(getCms().getSitePath(cmsResource)); } lock = cms.getLock(getCms().getSitePath(cmsResource)); if ((lock != null) && lock.isOwnedBy(getCms().getRequestContext().getCurrentUser()) && !lock.isOwnedInProjectBy( getCms().getRequestContext().getCurrentUser(), getCms().getRequestContext().getCurrentProject())) { // resource could not be locked m_lockedFiles += 1; return false; } // resource is locked successfully return true; } /** * The method to update xml contents.<p> * * @param report I_CmsReport * @param resourcePath Path to update xml contents in * @param inclSubFolder true, if also resources in subfolders in the vfs folder shall be updated, otherwise false * @param cmsObject Current CmsObject */ @SuppressWarnings("unchecked") private void updateXmlContents(I_CmsReport report, String resourcePath, boolean inclSubFolder, CmsObject cmsObject) { // write parameters to report report.println(Messages.get().container(Messages.RPT_UPDATEXML_BEGIN_UPDATE_0), I_CmsReport.FORMAT_NOTE); report.println(Messages.get().container(Messages.RPT_UPDATEXML_PARAMETERS_0), I_CmsReport.FORMAT_HEADLINE); report.println( Messages.get().container(Messages.RPT_UPDATEXML_PARAMETERS_RESOURCE_PATH_1, resourcePath), I_CmsReport.FORMAT_NOTE); report.println(Messages.get().container( Messages.RPT_UPDATEXML_PARAMETERS_INC_SUBFOLDERS_1, new Boolean(inclSubFolder).toString()), I_CmsReport.FORMAT_NOTE); // check for valid parameters (vfs folder) if (CmsStringUtil.isEmpty(resourcePath)) { report.println(Messages.get().container(Messages.RPT_UPDATEXML_NO_VFS_FOLDER_0), I_CmsReport.FORMAT_ERROR); return; } // read all files in the vfs folder report.println(Messages.get().container(Messages.RPT_UPDATEXML_START_SEARCHING_0), I_CmsReport.FORMAT_HEADLINE); List<CmsResource> allFiles = null; try { allFiles = cmsObject.readResources(resourcePath, CmsResourceFilter.DEFAULT, inclSubFolder); } catch (CmsException e) { m_errorUpdate += 1; report.println(Messages.get().container(Messages.RPT_UPDATEXML_SEARCH_ERROR_0), I_CmsReport.FORMAT_ERROR); if (LOG.isErrorEnabled()) { LOG.error(e.getMessageContainer(), e); } report.println(Messages.get().container(Messages.RPT_UPDATEXML_END_UPDATE_0), I_CmsReport.FORMAT_NOTE); return; } // get the files to update List<CmsResource> files2Update = new ArrayList<CmsResource>(); Iterator<CmsResource> iter = allFiles.iterator(); while (iter.hasNext()) { CmsResource cmsResource = iter.next(); // only update Xml contents if (cmsResource.isFile() && (CmsResourceTypeXmlContent.isXmlContent(cmsResource) || CmsResourceTypeXmlPage.isXmlPage(cmsResource))) { files2Update.add(cmsResource); } } // number of files to update int nrOfFiles = files2Update.size(); report.println(Messages.get().container( Messages.RPT_UPDATEXML_FILES_TO_UPDATE_1, new Integer(nrOfFiles).toString()), I_CmsReport.FORMAT_NOTE); // the file counter int fileCounter = 0; // update the files if (nrOfFiles > 0) { // report entry report.println( Messages.get().container(Messages.RPT_UPDATEXML_START_UPDATING_0), I_CmsReport.FORMAT_HEADLINE); // loop over all files iter = files2Update.iterator(); while (iter.hasNext()) { CmsResource cmsResource = iter.next(); fileCounter += 1; // report entries report.print(org.opencms.report.Messages.get().container( org.opencms.report.Messages.RPT_SUCCESSION_2, String.valueOf(fileCounter), String.valueOf(nrOfFiles)), I_CmsReport.FORMAT_NOTE); report.print(Messages.get().container(Messages.RPT_UPDATEXML_CURRENT_FILE_0), I_CmsReport.FORMAT_NOTE); report.print(org.opencms.report.Messages.get().container( org.opencms.report.Messages.RPT_ARGUMENT_1, report.removeSiteRoot(cmsResource.getRootPath()))); report.print( org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0), I_CmsReport.FORMAT_DEFAULT); // get current lock from file try { // try to lock the resource if (!lockResource(cmsObject, cmsResource, report)) { report.println(Messages.get().container( Messages.RPT_UPDATEXML_LOCKED_FILE_0, cmsObject.getSitePath(cmsResource)), I_CmsReport.FORMAT_ERROR); continue; } } catch (CmsException e) { report.println(Messages.get().container( Messages.RPT_UPDATEXML_LOCKED_FILE_0, cmsObject.getSitePath(cmsResource)), I_CmsReport.FORMAT_ERROR); if (LOG.isErrorEnabled()) { LOG.error(e.getMessageContainer(), e); } continue; } // write the resource try { // do not change the date last modified long lastModified = cmsResource.getDateLastModified(); CmsFile cmsFile = cmsObject.readFile(cmsResource); cmsFile.setDateLastModified(lastModified); cmsObject.writeFile(cmsFile); } catch (Exception e) { m_errorUpdate += 1; report.println( org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_FAILED_0), I_CmsReport.FORMAT_ERROR); if (LOG.isErrorEnabled()) { LOG.error(e.toString()); } continue; } // unlock the resource try { cmsObject.unlockResource(cmsObject.getSitePath(cmsResource)); } catch (CmsException e) { m_errorUpdate += 1; report.println( Messages.get().container(Messages.RPT_UPDATEXML_UNLOCK_FILE_0), I_CmsReport.FORMAT_WARNING); if (LOG.isErrorEnabled()) { LOG.error(e.getMessageContainer(), e); } continue; } // successfully updated report.println( org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0), I_CmsReport.FORMAT_OK); } } else { // no files to update report.println(Messages.get().container(Messages.RPT_UPDATEXML_NO_FILES_FOUND_0), I_CmsReport.FORMAT_NOTE); } // the results are written in the report report.println(Messages.get().container(Messages.RPT_UPDATEXML_RESULT_0), I_CmsReport.FORMAT_HEADLINE); report.println(Messages.get().container( Messages.RPT_UPDATEXML_FILES_TO_UPDATE_1, new Integer(nrOfFiles).toString()), I_CmsReport.FORMAT_NOTE); report.println(Messages.get().container( Messages.RPT_UPDATEXML_UPDATE_NUMBER_ERRORS_1, new Integer(m_errorUpdate).toString()), I_CmsReport.FORMAT_NOTE); report.println(Messages.get().container( Messages.RPT_UPDATEXML_LOCKED_FILES_1, new Integer(m_lockedFiles).toString()), I_CmsReport.FORMAT_NOTE); if (m_lockedFiles > 0) { report.println(Messages.get().container(Messages.RPT_UPDATEXML_UPDATE_FAILED_0), I_CmsReport.FORMAT_ERROR); } else { report.println(Messages.get().container(Messages.RPT_UPDATEXML_UPDATE_SUCCESS_0), I_CmsReport.FORMAT_OK); } report.println(Messages.get().container(Messages.RPT_UPDATEXML_END_UPDATE_0), I_CmsReport.FORMAT_NOTE); } }