001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://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 * @param cms the CMS context 320 */ 321 protected void purgeFile(String rfsFilePath, String vfsName, CmsObject cms) { 322 323 File rfsFile = new File(rfsFilePath); 324 325 // first delete the base file 326 deleteFile(rfsFile, vfsName); 327 deleteStaticExportPublishedResource(rfsFile, vfsName, cms); 328 // now delete the file parameter variations 329 // get the parent folder 330 File parent = rfsFile.getParentFile(); 331 if (parent != null) { 332 // list all files in the parent folder that are variations of the base file 333 File[] paramVariants = parent.listFiles(new PrefixFileFilter(rfsFile)); 334 if (paramVariants != null) { 335 for (int v = 0; v < paramVariants.length; v++) { 336 deleteFile(paramVariants[v], vfsName); 337 deleteStaticExportPublishedResource(paramVariants[v], vfsName, cms); 338 } 339 } 340 } 341 } 342 343 /** 344 * Scrub a single file or folder.<p> 345 * 346 * @param cms an export cms object 347 * @param res the resource to check 348 * @param scrubbedFolders the list of already scrubbed folders 349 * @param scrubbedFiles the list of already scrubbed files 350 */ 351 protected void scrubResource( 352 CmsObject cms, 353 CmsPublishedResource res, 354 Set<String> scrubbedFolders, 355 Set<String> scrubbedFiles) { 356 357 long timer = System.currentTimeMillis(); 358 if (LOG.isDebugEnabled()) { 359 LOG.debug(Messages.get().getBundle().key(Messages.LOG_SCRUB_EXPORT_START_RESOURCE_1, res.getRootPath())); 360 } 361 try { 362 // ensure all siblings are scrubbed if the resource has one 363 String resPath = cms.getRequestContext().removeSiteRoot(res.getRootPath()); 364 List<String> siblings = getSiblingsList(cms, resPath); 365 366 for (String vfsName : siblings) { 367 368 // get the link name for the published file 369 String rfsName = OpenCms.getStaticExportManager().getRfsName(cms, vfsName); 370 if (LOG.isDebugEnabled()) { 371 LOG.debug(Messages.get().getBundle().key(Messages.LOG_CHECKING_STATIC_EXPORT_2, vfsName, rfsName)); 372 } 373 if (rfsName.startsWith(OpenCms.getStaticExportManager().getRfsPrefix(vfsName)) 374 && (!scrubbedFiles.contains(rfsName)) 375 && (!scrubbedFolders.contains(CmsResource.getFolderPath(rfsName)))) { 376 377 if (res.isFolder()) { 378 if (res.getState().isDeleted()) { 379 String exportFolderName = CmsFileUtil.normalizePath( 380 OpenCms.getStaticExportManager().getExportPath(vfsName) 381 + rfsName.substring( 382 OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 383 try { 384 File exportFolder = new File(exportFolderName); 385 // check if export folder exists, if so delete it 386 if (exportFolder.exists() && exportFolder.canWrite()) { 387 CmsFileUtil.purgeDirectory(exportFolder); 388 // write log message 389 if (LOG.isInfoEnabled()) { 390 LOG.info( 391 Messages.get().getBundle().key( 392 Messages.LOG_FOLDER_DELETED_1, 393 exportFolderName)); 394 } 395 scrubbedFolders.add(rfsName); 396 continue; 397 } 398 } catch (Throwable t) { 399 // ignore, nothing to do about this 400 if (LOG.isWarnEnabled()) { 401 LOG.warn( 402 Messages.get().getBundle().key( 403 Messages.LOG_FOLDER_DELETION_FAILED_2, 404 vfsName, 405 exportFolderName)); 406 } 407 } 408 } 409 } else { 410 // check if the file is the default file of the folder 411 try { 412 CmsResource defaultFile = cms.readDefaultFile(CmsResource.getFolderPath(vfsName)); 413 if (defaultFile != null) { 414 String defaultfilePath = cms.getRequestContext().removeSiteRoot( 415 defaultFile.getRootPath()); 416 if (vfsName.equals(defaultfilePath)) { 417 // this is the default file, remove it additionally if present 418 String rfsNameDefault = CmsResource.getFolderPath(rfsName) 419 + CmsStaticExportManager.EXPORT_DEFAULT_FILE; 420 String rfsExportFileName = CmsFileUtil.normalizePath( 421 OpenCms.getStaticExportManager().getExportPath(vfsName) 422 + rfsNameDefault.substring( 423 OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 424 425 purgeFile(rfsExportFileName, vfsName, cms); 426 } 427 } 428 } catch (CmsException e) { 429 // failed to determine default file 430 } 431 } 432 433 // add index_export.html or the index.html to the folder name 434 rfsName = OpenCms.getStaticExportManager().addDefaultFileNameToFolder(rfsName, res.isFolder()); 435 if (LOG.isDebugEnabled()) { 436 LOG.debug(Messages.get().getBundle().key(Messages.LOG_RFSNAME_1, rfsName)); 437 } 438 String rfsExportFileName = CmsFileUtil.normalizePath( 439 OpenCms.getStaticExportManager().getExportPath(vfsName) 440 + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 441 if (LOG.isDebugEnabled()) { 442 LOG.debug(Messages.get().getBundle().key(Messages.LOG_EXPORT_RFSNAME_1, rfsName)); 443 } 444 // purge related files 445 List<File> relFilesToPurge = getRelatedFilesToPurge(rfsExportFileName, vfsName); 446 purgeFiles(relFilesToPurge, vfsName, scrubbedFiles, cms); 447 448 if (!res.isFolder()) { 449 I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(res.getType()); 450 I_CmsResourceLoader resLoader = OpenCms.getResourceManager().getLoader(resType.getLoaderId()); 451 if ((resLoader instanceof CmsXmlContentLoader) 452 && !(resLoader instanceof CmsXmlContainerPageLoader)) { 453 454 // only execute for XML content that are no container pages 455 List<File> detailPageFiles = getDetailPageFiles(cms, res, vfsName); 456 purgeFiles(detailPageFiles, vfsName, scrubbedFiles, cms); 457 if (LOG.isDebugEnabled()) { 458 LOG.debug(Messages.get().getBundle().key(Messages.LOG_PURGED_DETAILPAGES_0)); 459 } 460 List<File> referencingContainerPages = getContainerPagesToPurge(cms, res.getStructureId()); 461 purgeFiles(referencingContainerPages, vfsName, scrubbedFiles, cms); 462 if (LOG.isDebugEnabled()) { 463 LOG.debug(Messages.get().getBundle().key(Messages.LOG_PURGED_CONTAINERPAGES_0)); 464 } 465 } 466 } 467 // purge the file itself 468 purgeFile(rfsExportFileName, vfsName, cms); 469 scrubbedFiles.add(rfsName); 470 } 471 } 472 } catch (Throwable e) { 473 LOG.error(e.getLocalizedMessage(), e); 474 } 475 if (LOG.isDebugEnabled()) { 476 LOG.debug( 477 Messages.get().getBundle().key( 478 Messages.LOG_SCRUB_EXPORT_FINISH_RESOURCE_2, 479 res.getRootPath(), 480 (System.currentTimeMillis() - timer) + "")); 481 } 482 } 483 484 /** 485 * Deletes the given file from the RFS, with error handling and logging.<p> 486 * 487 * If the parent folder of the file is empty after deletion, the parent folder 488 * is deleted also.<p> 489 * 490 * @param file the file to delete 491 * @param vfsName the VFS name of the file (required for logging) 492 */ 493 private void deleteFile(File file, String vfsName) { 494 495 try { 496 if (file.exists() && file.canWrite()) { 497 file.delete(); 498 // write log message 499 if (LOG.isInfoEnabled()) { 500 LOG.info(Messages.get().getBundle().key(Messages.LOG_FILE_DELETED_1, getRfsName(file, vfsName))); 501 } 502 // delete the parent folder if it is empty (don't do this recursive) 503 File parent = new File(file.getParent()); 504 if (parent.listFiles().length == 0) { 505 if (parent.canWrite()) { 506 parent.delete(); 507 if (LOG.isInfoEnabled()) { 508 LOG.info( 509 Messages.get().getBundle().key(Messages.LOG_FILE_DELETED_1, getRfsName(file, vfsName))); 510 } 511 } 512 } 513 } 514 } catch (Throwable t) { 515 // ignore, nothing to do about this 516 if (LOG.isWarnEnabled()) { 517 LOG.warn( 518 Messages.get().getBundle().key(Messages.LOG_FILE_DELETION_FAILED_1, getRfsName(file, vfsName)), 519 t); 520 } 521 } 522 } 523 524 /** 525 * Deletes the RFS file entry in the CMS_STATICEXPORT_LINKS table.<p> 526 * 527 * @param file the file to delete 528 * @param vfsName the VFS name of the file (required for logging) 529 * @param cms the current CMS context 530 */ 531 private void deleteStaticExportPublishedResource(File file, String vfsName, CmsObject cms) { 532 533 CmsStaticExportManager manager = OpenCms.getStaticExportManager(); 534 String rfsName = getRfsName(file, vfsName); 535 String rfsExportFileName = rfsName.substring(manager.getRfsPrefix(vfsName).length()); 536 try { 537 cms.deleteStaticExportPublishedResource( 538 rfsExportFileName, 539 CmsStaticExportManager.EXPORT_LINK_WITH_PARAMETER, 540 null); 541 } catch (CmsException e) { 542 if (LOG.isInfoEnabled()) { 543 LOG.info(Messages.get().getBundle().key(Messages.LOG_PURGED_RFSFILE_1, rfsExportFileName)); 544 } 545 } 546 } 547 548 /** 549 * Gets the exported container pages that should be purged when the content with the given id is published.<p> 550 * 551 * @param cms the current CMS context 552 * @param targetId the structure id of the published content 553 * 554 * @return the list of files to purge 555 */ 556 private List<File> getContainerPagesToPurge(CmsObject cms, CmsUUID targetId) { 557 558 try { 559 List<File> purgePages = new ArrayList<File>(); 560 List<CmsRelation> relations = cms.readRelations(CmsRelationFilter.relationsToStructureId(targetId)); 561 for (CmsRelation relation : relations) { 562 CmsResource source = null; 563 try { 564 source = relation.getSource(cms, CmsResourceFilter.ALL); 565 } catch (CmsPermissionViolationException e) { 566 // export user can't read the file 567 continue; 568 } 569 if (CmsResourceTypeXmlContainerPage.isContainerPage(source)) { 570 571 // purge pages directly containing the content 572 573 String vfsName = source.getRootPath(); 574 String rfsName = OpenCms.getStaticExportManager().getRfsName(cms, vfsName); 575 String exportPath = CmsFileUtil.normalizePath( 576 OpenCms.getStaticExportManager().getExportPath(vfsName)); 577 String rfsExportFileName = exportPath 578 + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length()); 579 File file = new File(rfsExportFileName); 580 purgePages.add(file); 581 } else if (targetId.equals(source.getStructureId()) 582 && OpenCms.getResourceManager().getResourceType(source.getTypeId()).getTypeName().equals( 583 CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME)) { 584 LOG.warn( 585 Messages.get().getBundle().key( 586 Messages.LOG_WARN_ELEMENT_GROUP_REFERENCES_SELF_1, 587 source.getRootPath())); 588 } else 589 if (OpenCms.getResourceManager().getResourceType(source.getTypeId()).getTypeName().equals( 590 CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME)) { 591 // purge pages containing group containers containing the content 592 593 purgePages.addAll(getContainerPagesToPurge(cms, source.getStructureId())); 594 } 595 } 596 return purgePages; 597 } catch (CmsException e) { 598 LOG.error(e.getLocalizedMessage(), e); 599 return Collections.emptyList(); 600 } 601 } 602 603 /** 604 * Gets the exported detail page files which need to be purged.<p> 605 * 606 * @param cms the current cms context 607 * @param res the published resource 608 * @param vfsName the vfs name 609 * 610 * @return the list of files to be purged 611 */ 612 private List<File> getDetailPageFiles(CmsObject cms, CmsPublishedResource res, String vfsName) { 613 614 List<File> files = new ArrayList<File>(); 615 try { 616 if ((OpenCms.getRunLevel() < OpenCms.RUNLEVEL_4_SERVLET_ACCESS)) { 617 // Accessing the ADE manager during setup may not work. 618 // also folders can not be displayed in detail pages 619 return files; 620 } 621 List<String> urlNames = cms.getAllUrlNames(res.getStructureId()); 622 Collection<String> detailpages = OpenCms.getADEManager().getDetailPageHandler().getAllDetailPages( 623 cms, 624 res.getType()); 625 for (String urlName : urlNames) { 626 for (String detailPage : detailpages) { 627 String rfsName = CmsStringUtil.joinPaths( 628 OpenCms.getStaticExportManager().getRfsName(cms, detailPage), 629 urlName, 630 CmsStaticExportManager.DEFAULT_FILE); 631 String rfsExportFileName = CmsFileUtil.normalizePath( 632 OpenCms.getStaticExportManager().getExportPath(vfsName) 633 + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 634 File file = new File(rfsExportFileName); 635 if (file.exists() && !files.contains(file)) { 636 files.add(file); 637 } 638 } 639 } 640 } catch (CmsException e) { 641 LOG.error(e.getLocalizedMessage(), e); 642 } 643 return files; 644 645 } 646 647 /** 648 * Returns a list of files which are referenced by a container page.<p> 649 * 650 * @param cms the current cms object 651 * @param res the originally resource to purge (the container page) 652 * @param vfsName the vfs name of the originally resource to purge 653 */ 654 // private List<File> getRelatedSitemapFiles(CmsObject cms, CmsPublishedResource res, String vfsName) { 655 // 656 // List<File> files = new ArrayList<File>(); 657 // try { 658 // if (res.getType() == CmsResourceTypeXmlContainerPage.getContainerPageTypeId()) { 659 // List<CmsInternalSitemapEntry> entries = OpenCms.getSitemapManager().getEntriesForStructureId( 660 // cms, 661 // res.getStructureId()); 662 // for (CmsInternalSitemapEntry entry : entries) { 663 // String rfsName = OpenCms.getStaticExportManager().getRfsName(cms, entry.getRootPath()); 664 // // add index_export.html or the index.html to the folder name 665 // rfsName = OpenCms.getStaticExportManager().addDefaultFileNameToFolder(rfsName, res.isFolder()); 666 // // get 667 // String rfsExportFileName = CmsFileUtil.normalizePath(OpenCms.getStaticExportManager().getExportPath( 668 // vfsName) 669 // + rfsName.substring(OpenCms.getStaticExportManager().getRfsPrefix(vfsName).length())); 670 // File file = new File(rfsExportFileName); 671 // if (file.exists() && !files.contains(file)) { 672 // files.add(file); 673 // } 674 // } 675 // } 676 // } catch (CmsException e) { 677 // LOG.error(e.getLocalizedMessage(), e); 678 // } 679 // return files; 680 // } 681 682 /** 683 * Returns the export file name starting from the OpenCms webapp folder.<p> 684 * 685 * @param file the file to delete 686 * @param vfsName the VFS name of the file, the root path! 687 * 688 * @return the export file name starting from the OpenCms webapp folder 689 */ 690 private String getRfsName(File file, String vfsName) { 691 692 CmsStaticExportManager manager = OpenCms.getStaticExportManager(); 693 String filePath = file.getAbsolutePath(); 694 String result = CmsFileUtil.normalizePath( 695 manager.getRfsPrefix(vfsName) 696 + filePath.substring(OpenCms.getStaticExportManager().getExportPath(vfsName).length())); 697 return CmsStringUtil.substitute(result, new String(new char[] {File.separatorChar}), "/"); 698 } 699 700 /** 701 * Purges a list of files from the rfs.<p> 702 * 703 * @param files the list of files to purge 704 * @param vfsName the vfs name of the originally file to purge 705 * @param scrubbedFiles the list which stores all the scrubbed files 706 * @param cms the CMS context 707 */ 708 private void purgeFiles(List<File> files, String vfsName, Set<String> scrubbedFiles, CmsObject cms) { 709 710 for (File file : files) { 711 purgeFile(file.getAbsolutePath(), vfsName, cms); 712 String rfsName = CmsFileUtil.normalizePath( 713 OpenCms.getStaticExportManager().getRfsPrefix(vfsName) 714 + "/" 715 + file.getAbsolutePath().substring( 716 OpenCms.getStaticExportManager().getExportPath(vfsName).length())); 717 rfsName = CmsStringUtil.substitute(rfsName, new String(new char[] {File.separatorChar}), "/"); 718 scrubbedFiles.add(rfsName); 719 } 720 } 721}