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.staticexport; 029 030import org.opencms.db.CmsPublishedResource; 031import org.opencms.file.CmsObject; 032import org.opencms.file.CmsResource; 033import org.opencms.file.CmsResourceFilter; 034import org.opencms.file.CmsVfsResourceNotFoundException; 035import org.opencms.file.types.CmsResourceTypeXmlContainerPage; 036import org.opencms.file.types.I_CmsResourceType; 037import org.opencms.loader.CmsXmlContainerPageLoader; 038import org.opencms.loader.CmsXmlContentLoader; 039import org.opencms.loader.I_CmsResourceLoader; 040import org.opencms.main.CmsException; 041import org.opencms.main.CmsLog; 042import org.opencms.main.OpenCms; 043import org.opencms.relations.CmsRelation; 044import org.opencms.relations.CmsRelationFilter; 045import org.opencms.report.I_CmsReport; 046import org.opencms.security.CmsPermissionViolationException; 047import org.opencms.security.CmsSecurityException; 048import org.opencms.util.CmsFileUtil; 049import org.opencms.util.CmsStringUtil; 050import org.opencms.util.CmsUUID; 051 052import java.io.File; 053import java.io.FileFilter; 054import java.util.ArrayList; 055import java.util.Collection; 056import java.util.Collections; 057import java.util.HashSet; 058import java.util.Iterator; 059import java.util.List; 060import java.util.Set; 061 062import org.apache.commons.logging.Log; 063 064/** 065 * Abstract base implementation for the <code>{@link I_CmsStaticExportHandler}</code> interface.<p> 066 * 067 * This class provides several util methods to be used by static export handlers. 068 * 069 * @since 6.1.7 070 * 071 * @see I_CmsStaticExportHandler 072 * 073 */ 074public abstract class A_CmsStaticExportHandler implements I_CmsStaticExportHandler { 075 076 /** 077 * Implements the file filter used to remove variants with parameters of a base file.<p> 078 */ 079 private static class PrefixFileFilter implements FileFilter { 080 081 /** The extension. */ 082 private String m_baseExtension; 083 084 /** The base file. */ 085 private String m_baseName; 086 087 /** 088 * Creates a new instance of PrefixFileFilter.<p> 089 * 090 * @param baseFile the base file to compare with. 091 */ 092 public PrefixFileFilter(File baseFile) { 093 094 String fileName = baseFile.getName(); 095 m_baseExtension = CmsFileUtil.getExtension(fileName); 096 m_baseName = fileName + "_"; 097 } 098 099 /** 100 * Accepts the given file if its name starts with the name of of the base file (without extension) 101 * and ends with the extension.<p> 102 * 103 * @see java.io.FileFilter#accept(java.io.File) 104 */ 105 public boolean accept(File f) { 106 107 return f.getName().startsWith(m_baseName) && f.getName().endsWith(m_baseExtension); 108 } 109 } 110 111 /** The log object for this class. */ 112 private static final Log LOG = CmsLog.getLog(A_CmsStaticExportHandler.class); 113 114 /** Indicates if this content handler is busy. */ 115 protected boolean m_busy; 116 117 /** 118 * @see org.opencms.staticexport.I_CmsStaticExportHandler#isBusy() 119 */ 120 public boolean isBusy() { 121 122 return m_busy; 123 } 124 125 /** 126 * @see org.opencms.staticexport.I_CmsStaticExportHandler#performEventPublishProject(org.opencms.util.CmsUUID, org.opencms.report.I_CmsReport) 127 */ 128 public abstract void performEventPublishProject(CmsUUID publishHistoryId, I_CmsReport report); 129 130 /** 131 * Scrubs all files from the export folder that might have been changed, 132 * so that the export is newly created after the next request to the resource.<p> 133 * 134 * @param publishHistoryId id of the last published project 135 * 136 * @return the list of {@link CmsPublishedResource} objects to export 137 */ 138 public List<CmsPublishedResource> scrubExportFolders(CmsUUID publishHistoryId) { 139 140 if (LOG.isDebugEnabled()) { 141 LOG.debug(Messages.get().getBundle().key(Messages.LOG_SCRUBBING_EXPORT_FOLDERS_1, publishHistoryId)); 142 } 143 144 Set<String> scrubbedFolders = new HashSet<String>(); 145 Set<String> scrubbedFiles = new HashSet<String>(); 146 147 // get a export user cms context 148 CmsObject cms; 149 try { 150 // this will always use the root site 151 cms = OpenCms.initCmsObject(OpenCms.getDefaultUsers().getUserExport()); 152 } catch (CmsException e) { 153 // this should never happen 154 LOG.error(Messages.get().getBundle().key(Messages.LOG_INIT_FAILED_0), e); 155 return Collections.emptyList(); 156 } 157 158 List<CmsPublishedResource> publishedResources; 159 try { 160 publishedResources = cms.readPublishedResources(publishHistoryId); 161 } catch (CmsException e) { 162 LOG.error( 163 Messages.get().getBundle().key(Messages.LOG_READING_CHANGED_RESOURCES_FAILED_1, publishHistoryId), 164 e); 165 return Collections.emptyList(); 166 } 167 168 publishedResources = addMovedLinkSources(cms, publishedResources); 169 170 // now iterate the actual resources to be exported 171 Iterator<CmsPublishedResource> itPubRes = publishedResources.iterator(); 172 while (itPubRes.hasNext()) { 173 CmsPublishedResource res = itPubRes.next(); 174 if (res.getState().isUnchanged()) { 175 // unchanged resources don't need to be deleted 176 continue; 177 } 178 179 scrubResource(cms, res, scrubbedFolders, scrubbedFiles); 180 } 181 return publishedResources; 182 } 183 184 /** 185 * Add the link sources of moved resources to the list of published resources.<p> 186 * 187 * @param cms the cms context 188 * @param publishedResources the published resources 189 * 190 * @return the list of published resources included the link sources of moved resources 191 */ 192 protected List<CmsPublishedResource> addMovedLinkSources( 193 CmsObject cms, 194 List<CmsPublishedResource> publishedResources) { 195 196 long timer = System.currentTimeMillis(); 197 if (LOG.isDebugEnabled()) { 198 LOG.debug(Messages.get().getBundle().key(Messages.LOG_SCRUB_EXPORT_START_MOVED_SOURCES_0)); 199 } 200 publishedResources = new ArrayList<CmsPublishedResource>(publishedResources); 201 Set<String> pubResources = new HashSet<String>(publishedResources.size()); 202 // this is needed since the CmsPublishedResource#equals(Object) method just compares ids and not paths 203 // and with moved files you have 2 entries with the same id and different paths... 204 for (CmsPublishedResource pubRes : publishedResources) { 205 pubResources.add(pubRes.getRootPath()); 206 } 207 boolean modified = true; 208 // until no more resources are added 209 while (modified) { 210 modified = false; 211 Iterator<CmsPublishedResource> itPrePubRes = new ArrayList<CmsPublishedResource>( 212 publishedResources).iterator(); 213 while (itPrePubRes.hasNext()) { 214 CmsPublishedResource res = itPrePubRes.next(); 215 if (res.getMovedState() != CmsPublishedResource.STATE_MOVED_DESTINATION) { 216 // handle only resources that are destination of move operations 217 continue; 218 } 219 List<CmsRelation> relations = null; 220 try { 221 // get all link sources to this resource 222 relations = cms.getRelationsForResource( 223 cms.getRequestContext().removeSiteRoot(res.getRootPath()), 224 CmsRelationFilter.SOURCES); 225 } catch (CmsException e) { 226 // should never happen 227 if (LOG.isErrorEnabled()) { 228 LOG.error(e.getLocalizedMessage(), e); 229 } 230 } 231 if ((relations == null) || relations.isEmpty()) { 232 // continue with next resource if no link sources found 233 continue; 234 } 235 Iterator<CmsRelation> itRelations = relations.iterator(); 236 while (itRelations.hasNext()) { 237 CmsRelation relation = itRelations.next(); 238 CmsPublishedResource source = null; 239 try { 240 // get the link source 241 source = new CmsPublishedResource(relation.getSource(cms, CmsResourceFilter.ALL)); 242 } catch (CmsException e) { 243 // should never happen 244 if (LOG.isWarnEnabled()) { 245 LOG.warn(e.getLocalizedMessage()); 246 } 247 } 248 if ((source == null) || pubResources.contains(source.getRootPath())) { 249 // continue if the link source could not been retrieved or if the list already contains it 250 continue; 251 } 252 // add it, and set the modified flag to give it another round 253 modified = true; 254 pubResources.add(source.getRootPath()); 255 publishedResources.add(source); 256 } 257 } 258 } 259 if (LOG.isDebugEnabled()) { 260 LOG.debug( 261 Messages.get().getBundle().key( 262 Messages.LOG_SCRUB_EXPORT_FINISH_MOVED_SOURCES_1, 263 (System.currentTimeMillis() - timer) + "")); 264 } 265 return publishedResources; 266 } 267 268 /** 269 * Returns a list of related files to purge.<p> 270 * 271 * @param exportFileName the previous exported rfs filename (already purged) 272 * @param vfsName the vfs name of the resource (to be used to compute more sofisticated sets of related files to purge 273 * 274 * @return a list of related files to purge 275 */ 276 protected abstract List<File> getRelatedFilesToPurge(String exportFileName, String vfsName); 277 278 /** 279 * Returns a list containing the root paths of all siblings of a resource.<p> 280 * 281 * @param cms the export user context 282 * @param resPath the path of the resource to get the siblings for 283 * 284 * @return a list containing the root paths of all siblings of a resource 285 */ 286 protected List<String> getSiblingsList(CmsObject cms, String resPath) { 287 288 List<String> siblings = new ArrayList<String>(); 289 try { 290 List<CmsResource> li = cms.readSiblings(resPath, CmsResourceFilter.ALL); 291 for (int i = 0, l = li.size(); i < l; i++) { 292 String vfsName = (li.get(i)).getRootPath(); 293 siblings.add(vfsName); 294 } 295 } catch (CmsVfsResourceNotFoundException e) { 296 // resource not found, probably because the export user has no read permission on the resource, ignore 297 } catch (CmsSecurityException e) { 298 // security exception, probably because the export user has no read permission on the resource, ignore 299 } catch (CmsException e) { 300 // ignore, nothing to do about this 301 if (LOG.isWarnEnabled()) { 302 LOG.warn(Messages.get().getBundle().key(Messages.LOG_FETCHING_SIBLINGS_FAILED_1, resPath), e); 303 } 304 } 305 if (!siblings.contains(resPath)) { 306 // always add the resource itself, this has to be done because if the resource was 307 // deleted during publishing, the sibling lookup above will produce no results 308 siblings.add(resPath); 309 } 310 return siblings; 311 } 312 313 /** 314 * Deletes the given file from the RFS if it exists, 315 * also deletes all parameter variations of the file.<p> 316 * 317 * @param rfsFilePath the path of the RFS file to delete 318 * @param vfsName the VFS name of the file to delete (required for logging) 319 */ 320 protected void purgeFile(String rfsFilePath, String vfsName) { 321 322 File rfsFile = new File(rfsFilePath); 323 324 // first delete the base file 325 deleteFile(rfsFile, vfsName); 326 327 // now delete the file parameter variations 328 // get the parent folder 329 File parent = rfsFile.getParentFile(); 330 if (parent != null) { 331 // list all files in the parent folder that are variations of the base file 332 File[] paramVariants = parent.listFiles(new PrefixFileFilter(rfsFile)); 333 if (paramVariants != null) { 334 for (int v = 0; v < paramVariants.length; v++) { 335 deleteFile(paramVariants[v], vfsName); 336 } 337 } 338 } 339 } 340 341 /** 342 * Scrub a single file or folder.<p> 343 * 344 * @param cms an export cms object 345 * @param res the resource to check 346 * @param scrubbedFolders the list of already scrubbed folders 347 * @param scrubbedFiles the list of already scrubbed files 348 */ 349 protected void scrubResource( 350 CmsObject cms, 351 CmsPublishedResource res, 352 Set<String> scrubbedFolders, 353 Set<String> scrubbedFiles) { 354 355 long timer = System.currentTimeMillis(); 356 if (LOG.isDebugEnabled()) { 357 LOG.debug(Messages.get().getBundle().key(Messages.LOG_SCRUB_EXPORT_START_RESOURCE_1, res.getRootPath())); 358 } 359 try { 360 // ensure all siblings are scrubbed if the resource has one 361 String resPath = cms.getRequestContext().removeSiteRoot(res.getRootPath()); 362 List<String> siblings = getSiblingsList(cms, resPath); 363 364 for (String vfsName : siblings) { 365 366 // get the link name for the published file 367 String rfsName = OpenCms.getStaticExportManager().getRfsName(cms, vfsName); 368 if (LOG.isDebugEnabled()) { 369 LOG.debug(Messages.get().getBundle().key(Messages.LOG_CHECKING_STATIC_EXPORT_2, vfsName, rfsName)); 370 } 371 if (rfsName.startsWith(OpenCms.getStaticExportManager().getRfsPrefix(vfsName)) 372 && (!scrubbedFiles.contains(rfsName)) 373 && (!scrubbedFolders.contains(CmsResource.getFolderPath(rfsName)))) { 374 375 if (res.isFolder()) { 376 if (res.getState().isDeleted()) { 377 String exportFolderName = CmsFileUtil.normalizePath( 378 OpenCms.getStaticExportManager().getExportPath(vfsName) 379 + rfsName.substring( 380 OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 381 try { 382 File exportFolder = new File(exportFolderName); 383 // check if export folder exists, if so delete it 384 if (exportFolder.exists() && exportFolder.canWrite()) { 385 CmsFileUtil.purgeDirectory(exportFolder); 386 // write log message 387 if (LOG.isInfoEnabled()) { 388 LOG.info( 389 Messages.get().getBundle().key( 390 Messages.LOG_FOLDER_DELETED_1, 391 exportFolderName)); 392 } 393 scrubbedFolders.add(rfsName); 394 continue; 395 } 396 } catch (Throwable t) { 397 // ignore, nothing to do about this 398 if (LOG.isWarnEnabled()) { 399 LOG.warn( 400 Messages.get().getBundle().key( 401 Messages.LOG_FOLDER_DELETION_FAILED_2, 402 vfsName, 403 exportFolderName)); 404 } 405 } 406 } 407 } else { 408 // check if the file is the default file of the folder 409 try { 410 CmsResource defaultFile = cms.readDefaultFile(CmsResource.getFolderPath(vfsName)); 411 if (defaultFile != null) { 412 String defaultfilePath = cms.getRequestContext().removeSiteRoot( 413 defaultFile.getRootPath()); 414 if (vfsName.equals(defaultfilePath)) { 415 // this is the default file, remove it additionally if present 416 String rfsNameDefault = CmsResource.getFolderPath(rfsName) 417 + CmsStaticExportManager.EXPORT_DEFAULT_FILE; 418 String rfsExportFileName = CmsFileUtil.normalizePath( 419 OpenCms.getStaticExportManager().getExportPath(vfsName) 420 + rfsNameDefault.substring( 421 OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 422 423 purgeFile(rfsExportFileName, vfsName); 424 } 425 } 426 } catch (CmsException e) { 427 // failed to determine default file 428 } 429 } 430 431 // add index_export.html or the index.html to the folder name 432 rfsName = OpenCms.getStaticExportManager().addDefaultFileNameToFolder(rfsName, res.isFolder()); 433 if (LOG.isDebugEnabled()) { 434 LOG.debug(Messages.get().getBundle().key(Messages.LOG_RFSNAME_1, rfsName)); 435 } 436 String rfsExportFileName = CmsFileUtil.normalizePath( 437 OpenCms.getStaticExportManager().getExportPath(vfsName) 438 + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 439 if (LOG.isDebugEnabled()) { 440 LOG.debug(Messages.get().getBundle().key(Messages.LOG_EXPORT_RFSNAME_1, rfsName)); 441 } 442 // purge related files 443 List<File> relFilesToPurge = getRelatedFilesToPurge(rfsExportFileName, vfsName); 444 purgeFiles(relFilesToPurge, vfsName, scrubbedFiles); 445 446 if (!res.isFolder()) { 447 I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(res.getType()); 448 I_CmsResourceLoader resLoader = OpenCms.getResourceManager().getLoader(resType.getLoaderId()); 449 if ((resLoader instanceof CmsXmlContentLoader) 450 && !(resLoader instanceof CmsXmlContainerPageLoader)) { 451 452 // only execute for XML content that are no container pages 453 List<File> detailPageFiles = getDetailPageFiles(cms, res, vfsName); 454 purgeFiles(detailPageFiles, vfsName, scrubbedFiles); 455 if (LOG.isDebugEnabled()) { 456 LOG.debug(Messages.get().getBundle().key(Messages.LOG_PURGED_DETAILPAGES_0)); 457 } 458 List<File> referencingContainerPages = getContainerPagesToPurge(cms, res.getStructureId()); 459 purgeFiles(referencingContainerPages, vfsName, scrubbedFiles); 460 if (LOG.isDebugEnabled()) { 461 LOG.debug(Messages.get().getBundle().key(Messages.LOG_PURGED_CONTAINERPAGES_0)); 462 } 463 } 464 } 465 // purge the file itself 466 purgeFile(rfsExportFileName, vfsName); 467 scrubbedFiles.add(rfsName); 468 } 469 } 470 } catch (Throwable e) { 471 LOG.error(e.getLocalizedMessage(), e); 472 } 473 if (LOG.isDebugEnabled()) { 474 LOG.debug( 475 Messages.get().getBundle().key( 476 Messages.LOG_SCRUB_EXPORT_FINISH_RESOURCE_2, 477 res.getRootPath(), 478 (System.currentTimeMillis() - timer) + "")); 479 } 480 } 481 482 /** 483 * Deletes the given file from the RFS, with error handling and logging.<p> 484 * 485 * If the parent folder of the file is empty after deletion, the parent folder 486 * is deleted also.<p> 487 * 488 * @param file the file to delete 489 * @param vfsName the VFS name of the file (required for logging) 490 */ 491 private void deleteFile(File file, String vfsName) { 492 493 try { 494 if (file.exists() && file.canWrite()) { 495 file.delete(); 496 // write log message 497 if (LOG.isInfoEnabled()) { 498 LOG.info(Messages.get().getBundle().key(Messages.LOG_FILE_DELETED_1, getRfsName(file, vfsName))); 499 } 500 // delete the parent folder if it is empty (don't do this recursive) 501 File parent = new File(file.getParent()); 502 if (parent.listFiles().length == 0) { 503 if (parent.canWrite()) { 504 parent.delete(); 505 if (LOG.isInfoEnabled()) { 506 LOG.info( 507 Messages.get().getBundle().key(Messages.LOG_FILE_DELETED_1, getRfsName(file, vfsName))); 508 } 509 } 510 } 511 } 512 } catch (Throwable t) { 513 // ignore, nothing to do about this 514 if (LOG.isWarnEnabled()) { 515 LOG.warn( 516 Messages.get().getBundle().key(Messages.LOG_FILE_DELETION_FAILED_1, getRfsName(file, vfsName)), 517 t); 518 } 519 } 520 } 521 522 /** 523 * Gets the exported container pages that should be purged when the content with the given id is published.<p> 524 * 525 * @param cms the current CMS context 526 * @param targetId the structure id of the published content 527 * 528 * @return the list of files to purge 529 */ 530 private List<File> getContainerPagesToPurge(CmsObject cms, CmsUUID targetId) { 531 532 try { 533 List<File> purgePages = new ArrayList<File>(); 534 List<CmsRelation> relations = cms.readRelations(CmsRelationFilter.relationsToStructureId(targetId)); 535 for (CmsRelation relation : relations) { 536 CmsResource source = null; 537 try { 538 source = relation.getSource(cms, CmsResourceFilter.ALL); 539 } catch (CmsPermissionViolationException e) { 540 // export user can't read the file 541 continue; 542 } 543 if (CmsResourceTypeXmlContainerPage.isContainerPage(source)) { 544 545 // purge pages directly containing the content 546 547 String vfsName = source.getRootPath(); 548 String rfsName = OpenCms.getStaticExportManager().getRfsName(cms, vfsName); 549 String exportPath = CmsFileUtil.normalizePath( 550 OpenCms.getStaticExportManager().getExportPath(vfsName)); 551 String rfsExportFileName = exportPath 552 + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length()); 553 File file = new File(rfsExportFileName); 554 purgePages.add(file); 555 } else if (targetId.equals(source.getStructureId()) 556 && OpenCms.getResourceManager().getResourceType(source.getTypeId()).getTypeName().equals( 557 CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME)) { 558 LOG.warn( 559 Messages.get().getBundle().key( 560 Messages.LOG_WARN_ELEMENT_GROUP_REFERENCES_SELF_1, 561 source.getRootPath())); 562 } else if (OpenCms.getResourceManager().getResourceType(source.getTypeId()).getTypeName().equals( 563 CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME)) { 564 // purge pages containing group containers containing the content 565 566 purgePages.addAll(getContainerPagesToPurge(cms, source.getStructureId())); 567 } 568 } 569 return purgePages; 570 } catch (CmsException e) { 571 LOG.error(e.getLocalizedMessage(), e); 572 return Collections.emptyList(); 573 } 574 } 575 576 /** 577 * Gets the exported detail page files which need to be purged.<p> 578 * 579 * @param cms the current cms context 580 * @param res the published resource 581 * @param vfsName the vfs name 582 * 583 * @return the list of files to be purged 584 */ 585 private List<File> getDetailPageFiles(CmsObject cms, CmsPublishedResource res, String vfsName) { 586 587 List<File> files = new ArrayList<File>(); 588 try { 589 if ((OpenCms.getRunLevel() < OpenCms.RUNLEVEL_4_SERVLET_ACCESS)) { 590 // Accessing the ADE manager during setup may not work. 591 // also folders can not be displayed in detail pages 592 return files; 593 } 594 List<String> urlNames = cms.getAllUrlNames(res.getStructureId()); 595 Collection<String> detailpages = OpenCms.getADEManager().getDetailPageHandler().getAllDetailPages( 596 cms, 597 res.getType()); 598 for (String urlName : urlNames) { 599 for (String detailPage : detailpages) { 600 String rfsName = CmsStringUtil.joinPaths( 601 OpenCms.getStaticExportManager().getRfsName(cms, detailPage), 602 urlName, 603 CmsStaticExportManager.DEFAULT_FILE); 604 String rfsExportFileName = CmsFileUtil.normalizePath( 605 OpenCms.getStaticExportManager().getExportPath(vfsName) 606 + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 607 File file = new File(rfsExportFileName); 608 if (file.exists() && !files.contains(file)) { 609 files.add(file); 610 } 611 } 612 } 613 } catch (CmsException e) { 614 LOG.error(e.getLocalizedMessage(), e); 615 } 616 return files; 617 618 } 619 620 /** 621 * Returns a list of files which are referenced by a container page.<p> 622 * 623 * @param cms the current cms object 624 * @param res the originally resource to purge (the container page) 625 * @param vfsName the vfs name of the originally resource to purge 626 */ 627 // private List<File> getRelatedSitemapFiles(CmsObject cms, CmsPublishedResource res, String vfsName) { 628 // 629 // List<File> files = new ArrayList<File>(); 630 // try { 631 // if (res.getType() == CmsResourceTypeXmlContainerPage.getContainerPageTypeId()) { 632 // List<CmsInternalSitemapEntry> entries = OpenCms.getSitemapManager().getEntriesForStructureId( 633 // cms, 634 // res.getStructureId()); 635 // for (CmsInternalSitemapEntry entry : entries) { 636 // String rfsName = OpenCms.getStaticExportManager().getRfsName(cms, entry.getRootPath()); 637 // // add index_export.html or the index.html to the folder name 638 // rfsName = OpenCms.getStaticExportManager().addDefaultFileNameToFolder(rfsName, res.isFolder()); 639 // // get 640 // String rfsExportFileName = CmsFileUtil.normalizePath(OpenCms.getStaticExportManager().getExportPath( 641 // vfsName) 642 // + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 643 // File file = new File(rfsExportFileName); 644 // if (file.exists() && !files.contains(file)) { 645 // files.add(file); 646 // } 647 // } 648 // } 649 // } catch (CmsException e) { 650 // LOG.error(e.getLocalizedMessage(), e); 651 // } 652 // return files; 653 // } 654 655 /** 656 * Returns the export file name starting from the OpenCms webapp folder.<p> 657 * 658 * @param file the file to delete 659 * @param vfsName the VFS name of the file, the root path! 660 * 661 * @return the export file name starting from the OpenCms webapp folder 662 */ 663 private String getRfsName(File file, String vfsName) { 664 665 CmsStaticExportManager manager = OpenCms.getStaticExportManager(); 666 String filePath = file.getAbsolutePath(); 667 String result = CmsFileUtil.normalizePath( 668 manager.getRfsPrefix(vfsName) 669 + filePath.substring(OpenCms.getStaticExportManager().getExportPath(vfsName).length())); 670 return CmsStringUtil.substitute(result, new String(new char[] {File.separatorChar}), "/"); 671 } 672 673 /** 674 * Purges a list of files from the rfs.<p> 675 * 676 * @param files the list of files to purge 677 * @param vfsName the vfs name of the originally file to purge 678 * @param scrubbedFiles the list which stores all the scrubbed files 679 */ 680 private void purgeFiles(List<File> files, String vfsName, Set<String> scrubbedFiles) { 681 682 for (File file : files) { 683 purgeFile(file.getAbsolutePath(), vfsName); 684 String rfsName = CmsFileUtil.normalizePath( 685 OpenCms.getStaticExportManager().getRfsPrefix(vfsName) 686 + "/" 687 + file.getAbsolutePath().substring( 688 OpenCms.getStaticExportManager().getExportPath(vfsName).length())); 689 rfsName = CmsStringUtil.substitute(rfsName, new String(new char[] {File.separatorChar}), "/"); 690 scrubbedFiles.add(rfsName); 691 } 692 } 693}