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.gwt; 029 030import org.opencms.ade.containerpage.CmsDetailOnlyContainerUtil; 031import org.opencms.ade.galleries.CmsPreviewService; 032import org.opencms.configuration.CmsConfigurationException; 033import org.opencms.file.CmsFile; 034import org.opencms.file.CmsObject; 035import org.opencms.file.CmsProject; 036import org.opencms.file.CmsProperty; 037import org.opencms.file.CmsPropertyDefinition; 038import org.opencms.file.CmsResource; 039import org.opencms.file.CmsResource.CmsResourceUndoMode; 040import org.opencms.file.CmsResourceFilter; 041import org.opencms.file.CmsUser; 042import org.opencms.file.CmsVfsResourceNotFoundException; 043import org.opencms.file.history.CmsHistoryProject; 044import org.opencms.file.history.I_CmsHistoryResource; 045import org.opencms.file.types.CmsResourceTypeBinary; 046import org.opencms.file.types.CmsResourceTypeImage; 047import org.opencms.file.types.CmsResourceTypePlain; 048import org.opencms.file.types.CmsResourceTypePointer; 049import org.opencms.file.types.CmsResourceTypeXmlContainerPage; 050import org.opencms.file.types.CmsResourceTypeXmlContent; 051import org.opencms.file.types.CmsResourceTypeXmlPage; 052import org.opencms.gwt.shared.CmsBrokenLinkBean; 053import org.opencms.gwt.shared.CmsClientDateBean; 054import org.opencms.gwt.shared.CmsDataViewConstants; 055import org.opencms.gwt.shared.CmsDeleteResourceBean; 056import org.opencms.gwt.shared.CmsExternalLinkInfoBean; 057import org.opencms.gwt.shared.CmsGwtConstants; 058import org.opencms.gwt.shared.CmsHistoryResourceBean; 059import org.opencms.gwt.shared.CmsHistoryResourceCollection; 060import org.opencms.gwt.shared.CmsHistoryVersion; 061import org.opencms.gwt.shared.CmsHistoryVersion.OfflineOnline; 062import org.opencms.gwt.shared.CmsListInfoBean; 063import org.opencms.gwt.shared.CmsListInfoBean.LockIcon; 064import org.opencms.gwt.shared.CmsLockReportInfo; 065import org.opencms.gwt.shared.CmsPrepareEditResponse; 066import org.opencms.gwt.shared.CmsPreviewInfo; 067import org.opencms.gwt.shared.CmsQuickLaunchData; 068import org.opencms.gwt.shared.CmsQuickLaunchParams; 069import org.opencms.gwt.shared.CmsRenameInfoBean; 070import org.opencms.gwt.shared.CmsReplaceInfo; 071import org.opencms.gwt.shared.CmsResourceStatusBean; 072import org.opencms.gwt.shared.CmsRestoreInfoBean; 073import org.opencms.gwt.shared.CmsVfsEntryBean; 074import org.opencms.gwt.shared.alias.CmsAliasBean; 075import org.opencms.gwt.shared.property.CmsPropertiesBean; 076import org.opencms.gwt.shared.property.CmsPropertyChangeSet; 077import org.opencms.gwt.shared.rpc.I_CmsVfsService; 078import org.opencms.i18n.CmsLocaleManager; 079import org.opencms.i18n.CmsMessageContainer; 080import org.opencms.i18n.CmsMessages; 081import org.opencms.json.JSONObject; 082import org.opencms.loader.CmsImageScaler; 083import org.opencms.loader.CmsLoaderException; 084import org.opencms.lock.CmsLock; 085import org.opencms.lock.CmsLockType; 086import org.opencms.main.CmsException; 087import org.opencms.main.CmsIllegalArgumentException; 088import org.opencms.main.CmsLog; 089import org.opencms.main.OpenCms; 090import org.opencms.relations.CmsRelation; 091import org.opencms.relations.CmsRelationFilter; 092import org.opencms.ui.components.CmsResourceIcon; 093import org.opencms.util.CmsDateUtil; 094import org.opencms.util.CmsMacroResolver; 095import org.opencms.util.CmsRequestUtil; 096import org.opencms.util.CmsStringUtil; 097import org.opencms.util.CmsUUID; 098import org.opencms.widgets.dataview.I_CmsDataView; 099import org.opencms.widgets.dataview.I_CmsDataViewItem; 100import org.opencms.workplace.comparison.CmsHistoryListUtil; 101import org.opencms.workplace.explorer.CmsExplorerTypeSettings; 102import org.opencms.workplace.explorer.CmsResourceUtil; 103import org.opencms.xml.containerpage.CmsXmlContainerPageFactory; 104import org.opencms.xml.content.CmsXmlContentFactory; 105import org.opencms.xml.content.CmsXmlContentProperty; 106import org.opencms.xml.page.CmsXmlPageFactory; 107 108import java.text.DateFormat; 109import java.util.ArrayList; 110import java.util.Collections; 111import java.util.Date; 112import java.util.HashMap; 113import java.util.HashSet; 114import java.util.LinkedHashMap; 115import java.util.List; 116import java.util.Locale; 117import java.util.Map; 118import java.util.Set; 119 120import org.apache.commons.collections.CollectionUtils; 121import org.apache.commons.logging.Log; 122 123import com.google.common.collect.HashMultimap; 124import com.google.common.collect.Lists; 125import com.google.common.collect.Multimap; 126 127/** 128 * A service class for reading the VFS tree.<p> 129 * 130 * @since 8.0.0 131 */ 132public class CmsVfsService extends CmsGwtService implements I_CmsVfsService { 133 134 /** The static log object for this class. */ 135 private static final Log LOG = CmsLog.getLog(CmsVfsService.class); 136 137 /** The allowed preview mime types. Checked for binary content only. */ 138 private static Set<String> m_previewMimeTypes = new HashSet<String>(); 139 140 /** Serialization id. */ 141 private static final long serialVersionUID = -383483666952834348L; 142 143 /** A helper object containing the implementations of the alias-related service methods. */ 144 private CmsAliasHelper m_aliasHelper = new CmsAliasHelper(); 145 146 /** Initialize the preview mime types. */ 147 static { 148 CollectionUtils.addAll( 149 m_previewMimeTypes, 150 (new String[] { 151 "application/msword", 152 "application/pdf", 153 "application/excel", 154 "application/mspowerpoint", 155 "application/zip"})); 156 } 157 158 /** 159 * Adds the lock state information to the resource info bean.<p> 160 * 161 * @param cms the CMS context 162 * @param resource the resource to get the page info for 163 * @param resourceInfo the resource info to add the lock state to 164 * 165 * @return the resource info bean 166 * 167 * @throws CmsException if something else goes wrong 168 */ 169 public static CmsListInfoBean addLockInfo(CmsObject cms, CmsResource resource, CmsListInfoBean resourceInfo) 170 throws CmsException { 171 172 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 173 CmsResourceUtil resourceUtil = new CmsResourceUtil(cms, resource); 174 CmsLock lock = resourceUtil.getLock(); 175 LockIcon icon = LockIcon.NONE; 176 String iconTitle = null; 177 CmsLockType lockType = lock.getType(); 178 if (!lock.isOwnedBy(cms.getRequestContext().getCurrentUser())) { 179 if ((lockType == CmsLockType.EXCLUSIVE) 180 || (lockType == CmsLockType.INHERITED) 181 || (lockType == CmsLockType.TEMPORARY)) { 182 icon = LockIcon.CLOSED; 183 } else if ((lockType == CmsLockType.SHARED_EXCLUSIVE) || (lockType == CmsLockType.SHARED_INHERITED)) { 184 icon = LockIcon.SHARED_CLOSED; 185 } 186 } else { 187 if ((lockType == CmsLockType.EXCLUSIVE) 188 || (lockType == CmsLockType.INHERITED) 189 || (lockType == CmsLockType.TEMPORARY)) { 190 icon = LockIcon.OPEN; 191 } else if ((lockType == CmsLockType.SHARED_EXCLUSIVE) || (lockType == CmsLockType.SHARED_INHERITED)) { 192 icon = LockIcon.SHARED_OPEN; 193 } 194 } 195 if ((lock.getUserId() != null) && !lock.getUserId().isNullUUID()) { 196 CmsUser lockOwner = cms.readUser(lock.getUserId()); 197 iconTitle = Messages.get().getBundle(locale).key(Messages.GUI_LOCKED_BY_1, lockOwner.getFullName()); 198 resourceInfo.addAdditionalInfo( 199 Messages.get().getBundle(locale).key(Messages.GUI_LOCKED_OWNER_0), 200 lockOwner.getFullName()); 201 } 202 resourceInfo.setLockIcon(icon); 203 resourceInfo.setLockIconTitle(iconTitle); 204 if (icon != LockIcon.NONE) { 205 resourceInfo.setTitle(resourceInfo.getTitle() + " (" + iconTitle + ")"); 206 } 207 return resourceInfo; 208 } 209 210 /** 211 * Formats a date given the current user's workplace locale.<p> 212 * 213 * @param cms the current CMS context 214 * @param date the date to format 215 * 216 * @return the formatted date 217 */ 218 public static String formatDateTime(CmsObject cms, long date) { 219 220 return CmsDateUtil.getDateTime( 221 new Date(date), 222 DateFormat.MEDIUM, 223 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 224 } 225 226 /** 227 * Returns the no preview reason if there is any.<p> 228 * 229 * @param cms the current cms context 230 * @param resource the resource to check 231 * 232 * @return the no preview reason if there is any 233 */ 234 public static String getNoPreviewReason(CmsObject cms, CmsResource resource) { 235 236 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 237 String noPreviewReason = null; 238 if (resource.getState().isDeleted() && !(resource instanceof I_CmsHistoryResource)) { 239 noPreviewReason = Messages.get().getBundle(locale).key(Messages.GUI_NO_PREVIEW_DELETED_0); 240 } else if (resource.isFolder()) { 241 noPreviewReason = Messages.get().getBundle(locale).key(Messages.GUI_NO_PREVIEW_FOLDER_0); 242 } else { 243 String siteRoot = OpenCms.getSiteManager().getSiteRoot(resource.getRootPath()); 244 // previewing only resources that are in the same site or don't have a site root at all 245 if ((siteRoot != null) && !siteRoot.equals(cms.getRequestContext().getSiteRoot())) { 246 noPreviewReason = Messages.get().getBundle(locale).key(Messages.GUI_NO_PREVIEW_OTHER_SITE_0); 247 } else if (resource.getTypeId() == CmsResourceTypeBinary.getStaticTypeId()) { 248 String mimeType = OpenCms.getResourceManager().getMimeType(resource.getName(), null, "empty"); 249 if (!m_previewMimeTypes.contains(mimeType)) { 250 noPreviewReason = Messages.get().getBundle(locale).key(Messages.GUI_NO_PREVIEW_WRONG_MIME_TYPE_0); 251 } 252 } 253 } 254 return noPreviewReason; 255 } 256 257 /** 258 * Gets page information of a resource.<p> 259 * 260 * @param cms the CMS context 261 * @param res the resource 262 * 263 * @return gets the page information for the given resource 264 * 265 * @throws CmsException if the resource info can not be read 266 */ 267 public static CmsListInfoBean getPageInfo(CmsObject cms, CmsResource res) throws CmsException { 268 269 CmsListInfoBean result = new CmsListInfoBean(); 270 addPageInfo(cms, res, result); 271 return result; 272 } 273 274 /** 275 * Returns a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget} including the lock state.<p> 276 * 277 * @param cms the CMS context 278 * @param resource the resource to get the page info for 279 * 280 * @return a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget}.<p> 281 * 282 * @throws CmsLoaderException if the resource type could not be found 283 * @throws CmsException if something else goes wrong 284 */ 285 public static CmsListInfoBean getPageInfoWithLock(CmsObject cms, CmsResource resource) 286 throws CmsLoaderException, CmsException { 287 288 CmsListInfoBean result = getPageInfo(cms, resource); 289 addLockInfo(cms, resource, result); 290 return result; 291 } 292 293 /** 294 * Processes a file path, which may have macros in it, so it can be opened by the XML content editor.<p> 295 * 296 * @param cms the current CMS context 297 * @param res the resource for which the context menu option has been selected 298 * @param pathWithMacros the file path which may contain macros 299 * 300 * @return the processed file path 301 */ 302 public static String prepareFileNameForEditor(CmsObject cms, CmsResource res, String pathWithMacros) { 303 304 String subsite = OpenCms.getADEManager().getSubSiteRoot(cms, res.getRootPath()); 305 CmsMacroResolver resolver = new CmsMacroResolver(); 306 if (subsite != null) { 307 resolver.addMacro("subsite", cms.getRequestContext().removeSiteRoot(subsite)); 308 } 309 resolver.addMacro("file", cms.getSitePath(res)); 310 String path = resolver.resolveMacros(pathWithMacros).replaceAll("/+", "/"); 311 return path; 312 } 313 314 /** 315 * Gets page information of a resource and adds it to the given list info bean.<p> 316 * 317 * @param cms the CMS context 318 * @param resource the resource 319 * @param listInfo the list info bean to add the information to 320 * 321 * @return the list info bean 322 * 323 * @throws CmsException if the resource info can not be read 324 */ 325 protected static CmsListInfoBean addPageInfo(CmsObject cms, CmsResource resource, CmsListInfoBean listInfo) 326 throws CmsException { 327 328 listInfo.setResourceState(resource.getState()); 329 330 String title = cms.readPropertyObject( 331 resource, 332 CmsPropertyDefinition.PROPERTY_TITLE, 333 false, 334 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).getValue(); 335 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(title)) { 336 listInfo.setTitle(title); 337 } else { 338 listInfo.setTitle(resource.getName()); 339 } 340 listInfo.setSubTitle(cms.getSitePath(resource)); 341 listInfo.setIsFolder(Boolean.valueOf(resource.isFolder())); 342 String resTypeName = OpenCms.getResourceManager().getResourceType(resource).getTypeName(); 343 CmsExplorerTypeSettings cmsExplorerTypeSettings = OpenCms.getWorkplaceManager().getExplorerTypeSetting( 344 resTypeName); 345 if (null == cmsExplorerTypeSettings) { 346 CmsMessageContainer errMsg = Messages.get().container( 347 Messages.ERR_EXPLORER_TYPE_SETTINGS_FOR_RESOURCE_TYPE_NOT_FOUND_3, 348 resource.getRootPath(), 349 resTypeName, 350 Integer.valueOf(resource.getTypeId())); 351 throw new CmsConfigurationException(errMsg); 352 } 353 String key = cmsExplorerTypeSettings.getKey(); 354 Locale currentLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 355 CmsMessages messages = OpenCms.getWorkplaceManager().getMessages(currentLocale); 356 String resTypeNiceName = messages.key(key); 357 listInfo.addAdditionalInfo( 358 messages.key(org.opencms.workplace.commons.Messages.GUI_LABEL_TYPE_0), 359 resTypeNiceName); 360 listInfo.setResourceType(resTypeName); 361 listInfo.setBigIconClasses( 362 CmsIconUtil.getIconClasses(CmsIconUtil.getDisplayType(cms, resource), resource.getName(), false)); 363 // set the default file and detail type info 364 String detailType = CmsResourceIcon.getDefaultFileOrDetailType(cms, resource); 365 if (detailType != null) { 366 listInfo.setSmallIconClasses(CmsIconUtil.getIconClasses(detailType, null, true)); 367 } 368 return listInfo; 369 } 370 371 /** 372 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#createNewExternalLink(java.lang.String, java.lang.String, java.lang.String, java.lang.String) 373 */ 374 public void createNewExternalLink(String title, String link, String resourceName, String parentFolderPath) 375 throws CmsRpcException { 376 377 CmsObject cms = getCmsObject(); 378 try { 379 CmsProperty titleProp = new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, title, null); 380 @SuppressWarnings("deprecation") 381 CmsResource resource = cms.createResource( 382 CmsStringUtil.joinPaths(parentFolderPath, resourceName), 383 CmsResourceTypePointer.getStaticTypeId(), 384 new byte[0], 385 Collections.singletonList(titleProp)); 386 CmsFile file = cms.readFile(resource); 387 file.setContents(link.getBytes(CmsLocaleManager.getResourceEncoding(cms, resource))); 388 cms.writeFile(file); 389 tryUnlock(resource); 390 // update the offline search indices 391 OpenCms.getSearchManager().updateOfflineIndexes(); 392 } catch (Exception e) { 393 error(e); 394 } 395 } 396 397 /** 398 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#createPropertyDefinition(java.lang.String) 399 */ 400 public void createPropertyDefinition(String name) throws CmsRpcException { 401 402 CmsObject cms = getCmsObject(); 403 try { 404 cms.createPropertyDefinition(name.trim()); 405 } catch (Exception e) { 406 error(e); 407 } 408 409 } 410 411 /** 412 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#deleteResource(org.opencms.util.CmsUUID) 413 */ 414 public void deleteResource(CmsUUID structureId) throws CmsRpcException { 415 416 try { 417 CmsObject cms = getCmsObject(); 418 CmsResource res = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 419 deleteResource(res); 420 } catch (Throwable e) { 421 error(e); 422 } 423 } 424 425 /** 426 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#deleteResource(java.lang.String) 427 */ 428 public void deleteResource(String sitePath) throws CmsRpcException { 429 430 try { 431 CmsResource res = getCmsObject().readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION); 432 deleteResource(res); 433 } catch (Throwable e) { 434 error(e); 435 } 436 } 437 438 /** 439 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#forceUnlock(org.opencms.util.CmsUUID) 440 */ 441 public void forceUnlock(CmsUUID structureId) throws CmsRpcException { 442 443 try { 444 CmsResource resource = getCmsObject().readResource(structureId, CmsResourceFilter.ALL); 445 // get the current lock 446 CmsLock currentLock = getCmsObject().getLock(resource); 447 // check if the resource is locked at all 448 if (currentLock.getEditionLock().isUnlocked() && currentLock.getSystemLock().isUnlocked()) { 449 getCmsObject().lockResourceTemporary(resource); 450 } else { 451 getCmsObject().changeLock(resource); 452 } 453 getCmsObject().unlockResource(resource); 454 } catch (Throwable e) { 455 error(e); 456 } 457 } 458 459 /** 460 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getAliasesForPage(org.opencms.util.CmsUUID) 461 */ 462 public List<CmsAliasBean> getAliasesForPage(CmsUUID uuid) throws CmsRpcException { 463 464 try { 465 return m_aliasHelper.getAliasesForPage(uuid); 466 } catch (Throwable e) { 467 error(e); 468 return null; 469 } 470 } 471 472 /** 473 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getBrokenLinks(org.opencms.util.CmsUUID) 474 */ 475 public CmsDeleteResourceBean getBrokenLinks(CmsUUID structureId) throws CmsRpcException { 476 477 try { 478 CmsResource entryResource = getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 479 480 return getBrokenLinks(entryResource); 481 } catch (Throwable e) { 482 error(e); 483 return null; // will never be reached 484 } 485 } 486 487 /** 488 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getBrokenLinks(java.lang.String) 489 */ 490 public CmsDeleteResourceBean getBrokenLinks(String sitePath) throws CmsRpcException { 491 492 try { 493 CmsResource entryResource = getCmsObject().readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION); 494 495 return getBrokenLinks(entryResource); 496 } catch (Throwable e) { 497 error(e); 498 return null; // will never be reached 499 } 500 } 501 502 /** 503 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getChildren(java.lang.String) 504 */ 505 public List<CmsVfsEntryBean> getChildren(String path) throws CmsRpcException { 506 507 try { 508 CmsObject cms = getCmsObject(); 509 List<CmsResource> resources = new ArrayList<CmsResource>(); 510 resources.addAll(cms.getResourcesInFolder(path, CmsResourceFilter.DEFAULT)); 511 List<CmsVfsEntryBean> result = makeEntryBeans(resources, false); 512 return result; 513 } catch (Throwable e) { 514 error(e); 515 } 516 return null; 517 } 518 519 /** 520 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getDataViewThumbnail(java.lang.String, java.lang.String) 521 */ 522 public String getDataViewThumbnail(String config, String id) throws CmsRpcException { 523 524 try { 525 JSONObject obj = new JSONObject(config); 526 String className = obj.optString(CmsDataViewConstants.CONFIG_VIEW_CLASS); 527 String classArg = obj.optString(CmsDataViewConstants.CONFIG_VIEW_ARG); 528 I_CmsDataView data = (I_CmsDataView)(Class.forName(className).newInstance()); 529 data.initialize(getCmsObject(), classArg, OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject())); 530 I_CmsDataViewItem item = data.getItemById(id); 531 if (item == null) { 532 LOG.warn("no dataview item found for id: " + id + " (config=" + config + ")"); 533 return null; 534 } 535 return item.getImage(); 536 } catch (Exception e) { 537 error(e); 538 return null; 539 } 540 } 541 542 /** 543 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getDefaultProperties(java.util.List) 544 */ 545 public Map<CmsUUID, Map<String, CmsXmlContentProperty>> getDefaultProperties(List<CmsUUID> structureIds) 546 throws CmsRpcException { 547 548 try { 549 CmsPropertyEditorHelper helper = new CmsPropertyEditorHelper(getCmsObject()); 550 return helper.getDefaultProperties(structureIds); 551 } catch (Throwable e) { 552 error(e); 553 return null; 554 } 555 } 556 557 /** 558 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getDefinedProperties() 559 */ 560 public ArrayList<String> getDefinedProperties() throws CmsRpcException { 561 562 CmsObject cms = getCmsObject(); 563 try { 564 List<CmsPropertyDefinition> definitions = cms.readAllPropertyDefinitions(); 565 ArrayList<String> result = new ArrayList<String>(); 566 for (CmsPropertyDefinition def : definitions) { 567 result.add(def.getName()); 568 } 569 return result; 570 } catch (Exception e) { 571 error(e); 572 return null; 573 } 574 } 575 576 /** 577 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getFileReplaceInfo(org.opencms.util.CmsUUID) 578 */ 579 public CmsReplaceInfo getFileReplaceInfo(CmsUUID structureId) throws CmsRpcException { 580 581 CmsReplaceInfo result = null; 582 try { 583 CmsObject cms = getCmsObject(); 584 CmsResource res = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 585 CmsListInfoBean fileInfo = getPageInfo(res); 586 boolean isLockable = cms.getLock(res).isLockableBy(cms.getRequestContext().getCurrentUser()); 587 long maxFileSize = OpenCms.getWorkplaceManager().getFileBytesMaxUploadSize(cms); 588 result = new CmsReplaceInfo(fileInfo, cms.getSitePath(res), isLockable, maxFileSize); 589 } catch (Throwable e) { 590 error(e); 591 } 592 return result; 593 } 594 595 /** 596 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getHistoryPreviewInfo(org.opencms.util.CmsUUID, java.lang.String, org.opencms.gwt.shared.CmsHistoryVersion) 597 */ 598 public CmsPreviewInfo getHistoryPreviewInfo(CmsUUID structureId, String locale, CmsHistoryVersion versionBean) 599 throws CmsRpcException { 600 601 try { 602 CmsObject cms = getCmsObject(); 603 CmsResource previewResource = null; 604 if (versionBean.getVersionNumber() != null) { 605 previewResource = (CmsResource)(cms.readResource( 606 structureId, 607 versionBean.getVersionNumber().intValue())); 608 } else if (versionBean.isOffline()) { 609 previewResource = cms.readResource(structureId, CmsResourceFilter.ALL); 610 } else if (versionBean.isOnline()) { 611 CmsProject online = cms.readProject(CmsProject.ONLINE_PROJECT_ID); 612 cms = OpenCms.initCmsObject(cms); 613 cms.getRequestContext().setCurrentProject(online); 614 previewResource = cms.readResource(structureId, CmsResourceFilter.ALL); 615 } 616 CmsFile previewFile = cms.readFile(previewResource); 617 return getPreviewInfo(cms, previewFile, CmsLocaleManager.getLocale(locale)); 618 } catch (Exception e) { 619 error(e); 620 return null; // return statement will never be reached 621 } 622 } 623 624 /** 625 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getLockReportInfo(org.opencms.util.CmsUUID) 626 */ 627 public CmsLockReportInfo getLockReportInfo(CmsUUID structureId) throws CmsRpcException { 628 629 CmsLockReportInfo result = null; 630 CmsObject cms = getCmsObject(); 631 try { 632 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL); 633 List<CmsListInfoBean> lockedInfos = new ArrayList<CmsListInfoBean>(); 634 List<CmsResource> lockedResources = cms.getBlockingLockedResources(resource); 635 if (lockedResources != null) { 636 for (CmsResource lockedResource : lockedResources) { 637 lockedInfos.add(getPageInfoWithLock(cms, lockedResource)); 638 } 639 } 640 result = new CmsLockReportInfo(getPageInfoWithLock(cms, resource), lockedInfos); 641 } catch (Throwable e) { 642 error(e); 643 } 644 return result; 645 } 646 647 /** 648 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPageInfo(org.opencms.util.CmsUUID) 649 */ 650 public CmsListInfoBean getPageInfo(CmsUUID structureId) throws CmsRpcException { 651 652 try { 653 CmsResource res = getCmsObject().readResource(structureId, CmsResourceFilter.ALL); 654 return getPageInfo(res); 655 } catch (Throwable e) { 656 error(e); 657 return null; // will never be reached 658 } 659 } 660 661 /** 662 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPageInfo(java.lang.String) 663 */ 664 public CmsListInfoBean getPageInfo(String vfsPath) throws CmsRpcException { 665 666 try { 667 CmsResource res = getCmsObject().readResource(vfsPath, CmsResourceFilter.IGNORE_EXPIRATION); 668 return getPageInfo(res); 669 } catch (Throwable e) { 670 error(e); 671 return null; // will never be reached 672 } 673 } 674 675 /** 676 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPreviewInfo(org.opencms.util.CmsUUID, java.lang.String) 677 */ 678 public CmsPreviewInfo getPreviewInfo(CmsUUID structureId, String locale) throws CmsRpcException { 679 680 CmsPreviewInfo result = null; 681 try { 682 result = getPreviewInfo( 683 getCmsObject(), 684 getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION), 685 CmsLocaleManager.getLocale(locale)); 686 } catch (Exception e) { 687 error(e); 688 } 689 return result; 690 691 } 692 693 /** 694 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPreviewInfo(java.lang.String, java.lang.String) 695 */ 696 public CmsPreviewInfo getPreviewInfo(String sitePath, String locale) throws CmsRpcException { 697 698 CmsPreviewInfo result = null; 699 try { 700 result = getPreviewInfo( 701 getCmsObject(), 702 getCmsObject().readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION), 703 CmsLocaleManager.getLocale(locale)); 704 } catch (Exception e) { 705 error(e); 706 } 707 return result; 708 } 709 710 /** 711 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getRenameInfo(org.opencms.util.CmsUUID) 712 */ 713 public CmsRenameInfoBean getRenameInfo(CmsUUID structureId) throws CmsRpcException { 714 715 try { 716 CmsObject cms = getCmsObject(); 717 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 718 CmsListInfoBean listInfo = getPageInfo(resource); 719 String sitePath = cms.getSitePath(resource); 720 return new CmsRenameInfoBean(sitePath, structureId, listInfo); 721 } catch (Throwable e) { 722 error(e); 723 return null; 724 } 725 } 726 727 /** 728 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getResourceHistory(org.opencms.util.CmsUUID) 729 */ 730 public CmsHistoryResourceCollection getResourceHistory(CmsUUID structureId) throws CmsRpcException { 731 732 try { 733 CmsHistoryResourceCollection result = getResourceHistoryInternal(structureId); 734 CmsListInfoBean info = getPageInfo(structureId); 735 result.setContentInfo(info); 736 return result; 737 738 } catch (Exception e) { 739 error(e); 740 return null; // return statement will never be reached 741 } 742 } 743 744 /** 745 * Internal version of getResourceHistory.<p> 746 * 747 * @param structureId the structure id of the resource 748 * 749 * @return the resource history 750 * 751 * @throws CmsException if something goes wrong 752 */ 753 public CmsHistoryResourceCollection getResourceHistoryInternal(CmsUUID structureId) throws CmsException { 754 755 CmsHistoryResourceCollection result = new CmsHistoryResourceCollection(); 756 CmsObject cms = getCmsObject(); 757 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL); 758 List<I_CmsHistoryResource> versions = cms.readAllAvailableVersions(resource); 759 if (!resource.getState().isUnchanged()) { 760 result.add(createHistoryResourceBean(cms, resource, true, -1)); 761 } 762 int maxVersion = 0; 763 764 if (versions.isEmpty()) { 765 try { 766 CmsProject online = cms.readProject(CmsProject.ONLINE_PROJECT_ID); 767 CmsObject onlineCms = OpenCms.initCmsObject(cms); 768 onlineCms.getRequestContext().setCurrentProject(online); 769 CmsResource onlineResource = onlineCms.readResource(structureId, CmsResourceFilter.ALL); 770 CmsHistoryResourceBean onlineResBean = createHistoryResourceBean(onlineCms, onlineResource, false, 0); 771 result.add(onlineResBean); 772 } catch (CmsVfsResourceNotFoundException e) { 773 LOG.info(e.getLocalizedMessage(), e); 774 } catch (Exception e) { 775 LOG.error(e.getLocalizedMessage(), e); 776 } 777 } else { 778 for (I_CmsHistoryResource historyRes : versions) { 779 maxVersion = Math.max(maxVersion, historyRes.getVersion()); 780 } 781 for (I_CmsHistoryResource historyRes : versions) { 782 CmsHistoryResourceBean historyBean = createHistoryResourceBean( 783 cms, 784 (CmsResource)historyRes, 785 false, 786 maxVersion); 787 result.add(historyBean); 788 } 789 } 790 return result; 791 } 792 793 /** 794 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getResourceStatus(org.opencms.util.CmsUUID, java.lang.String, boolean, org.opencms.util.CmsUUID, java.util.Map) 795 */ 796 public CmsResourceStatusBean getResourceStatus( 797 CmsUUID structureId, 798 String contentLocale, 799 boolean includeTargets, 800 CmsUUID detailContentId, 801 Map<String, String> context) 802 throws CmsRpcException { 803 804 if (context == null) { 805 context = new HashMap<>(); 806 } 807 try { 808 CmsObject cms = getCmsObject(); 809 CmsDefaultResourceStatusProvider provider = new CmsDefaultResourceStatusProvider(); 810 return provider.getResourceStatus( 811 getRequest(), 812 cms, 813 structureId, 814 contentLocale, 815 includeTargets, 816 detailContentId, 817 detailContentId != null ? Collections.singletonList(detailContentId) : null, 818 context); 819 } catch (Throwable e) { 820 error(e); 821 return null; 822 } 823 } 824 825 /** 826 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getRestoreInfo(org.opencms.util.CmsUUID) 827 */ 828 public CmsRestoreInfoBean getRestoreInfo(CmsUUID structureId) throws CmsRpcException { 829 830 try { 831 CmsObject cms = getCmsObject(); 832 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 833 CmsListInfoBean listInfo = getPageInfo(resource); 834 CmsRestoreInfoBean result = new CmsRestoreInfoBean(); 835 result.setListInfoBean(listInfo); 836 837 CmsObject onlineCms = OpenCms.initCmsObject(cms); 838 CmsProject onlineProject = cms.readProject(CmsProject.ONLINE_PROJECT_NAME); 839 onlineCms.getRequestContext().setCurrentProject(onlineProject); 840 CmsResource onlineResource = onlineCms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 841 result.setOnlinePath(onlineResource.getRootPath()); 842 result.setOfflinePath(resource.getRootPath()); 843 844 String offlineDate = formatDateTime(resource.getDateLastModified()); 845 String onlineDate = formatDateTime(onlineResource.getDateLastModified()); 846 result.setOfflineDate(offlineDate); 847 result.setOnlineDate(onlineDate); 848 result.setStructureId(structureId); 849 850 CmsObject offlineRootCms = OpenCms.initCmsObject(cms); 851 offlineRootCms.getRequestContext().setSiteRoot(""); 852 CmsObject onlineRootCms = OpenCms.initCmsObject(onlineCms); 853 onlineRootCms.getRequestContext().setSiteRoot(""); 854 String parent = CmsResource.getParentFolder(onlineResource.getRootPath()); 855 boolean canUndoMove = offlineRootCms.existsResource(parent, CmsResourceFilter.IGNORE_EXPIRATION); 856 857 result.setCanUndoMove(canUndoMove); 858 859 return result; 860 } catch (Throwable e) { 861 error(e); 862 return null; 863 } 864 } 865 866 /** 867 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getRootEntries() 868 */ 869 public List<CmsVfsEntryBean> getRootEntries() throws CmsRpcException { 870 871 try { 872 CmsObject cms = getCmsObject(); 873 List<CmsResource> roots = new ArrayList<CmsResource>(); 874 roots.add(cms.readResource("/", CmsResourceFilter.IGNORE_EXPIRATION)); 875 return makeEntryBeans(roots, true); 876 } catch (CmsException e) { 877 error(e); 878 } 879 return null; 880 } 881 882 /** 883 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getSitePath(org.opencms.util.CmsUUID) 884 */ 885 public String getSitePath(CmsUUID structureId) { 886 887 try { 888 CmsResource resource = getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 889 return getCmsObject().getSitePath(resource); 890 } catch (CmsException e) { 891 if (LOG.isWarnEnabled()) { 892 LOG.warn(e.getMessageContainer(), e); 893 } 894 } 895 return null; 896 } 897 898 /** 899 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#loadLinkInfo(org.opencms.util.CmsUUID) 900 */ 901 public CmsExternalLinkInfoBean loadLinkInfo(CmsUUID structureId) throws CmsRpcException { 902 903 CmsExternalLinkInfoBean info = new CmsExternalLinkInfoBean(); 904 CmsObject cms = getCmsObject(); 905 try { 906 CmsResource linkResource = cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 907 addPageInfo(cms, linkResource, info); 908 CmsFile linkFile = cms.readFile(linkResource); 909 OpenCms.getLocaleManager(); 910 String link = new String(linkFile.getContents(), CmsLocaleManager.getResourceEncoding(cms, linkResource)); 911 info.setLink(link); 912 info.setSitePath(cms.getSitePath(linkResource)); 913 } catch (Exception e) { 914 error(e); 915 } 916 return info; 917 } 918 919 /** 920 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#loadPropertyData(org.opencms.util.CmsUUID) 921 */ 922 public CmsPropertiesBean loadPropertyData(CmsUUID id) throws CmsRpcException { 923 924 CmsObject cms = getCmsObject(); 925 try { 926 CmsPropertyEditorHelper helper = new CmsPropertyEditorHelper(cms); 927 return helper.loadPropertyData(id); 928 } catch (Throwable e) { 929 error(e); 930 } 931 return null; 932 } 933 934 /** 935 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#loadQuickLaunchItems(org.opencms.gwt.shared.CmsQuickLaunchParams) 936 */ 937 public List<CmsQuickLaunchData> loadQuickLaunchItems(CmsQuickLaunchParams params) throws CmsRpcException { 938 939 try { 940 return CmsQuickLaunchProvider.getQuickLaunchData(getCmsObject(), getRequest().getSession(), params); 941 } catch (Exception e) { 942 error(e); 943 return null; 944 } 945 } 946 947 /** 948 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#prepareEdit(org.opencms.util.CmsUUID, java.lang.String) 949 */ 950 public CmsPrepareEditResponse prepareEdit(CmsUUID currentPageId, String pathWithMacros) throws CmsRpcException { 951 952 try { 953 CmsObject cms = getCmsObject(); 954 CmsResource resource = null; 955 if (cms.existsResource(pathWithMacros, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)) { 956 resource = cms.readResource(pathWithMacros, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 957 } else { 958 CmsResource currentPage = cms.readResource(currentPageId, CmsResourceFilter.IGNORE_EXPIRATION); 959 String path = prepareFileNameForEditor(cms, currentPage, pathWithMacros); 960 resource = cms.readResource(path, CmsResourceFilter.IGNORE_EXPIRATION); 961 } 962 ensureLock(resource); 963 CmsPrepareEditResponse result = new CmsPrepareEditResponse(); 964 result.setRootPath(resource.getRootPath()); 965 result.setSitePath(cms.getSitePath(resource)); 966 result.setStructureId(resource.getStructureId()); 967 return result; 968 } catch (Throwable e) { 969 error(e); 970 } 971 return null; 972 } 973 974 /** 975 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#renameResource(org.opencms.util.CmsUUID, java.lang.String) 976 */ 977 public String renameResource(CmsUUID structureId, String newName) throws CmsRpcException { 978 979 try { 980 return renameResourceInternal(structureId, newName); 981 } catch (Throwable e) { 982 error(e); 983 return null; 984 } 985 } 986 987 /** 988 * Internal implementation for renaming a resource.<p> 989 * 990 * @param structureId the structure id of the resource to rename 991 * @param newName the new resource name 992 * @return either null if the rename was successful, or an error message 993 * 994 * @throws CmsException if something goes wrong 995 */ 996 public String renameResourceInternal(CmsUUID structureId, String newName) throws CmsException { 997 998 newName = newName.trim(); 999 CmsObject rootCms = OpenCms.initCmsObject(getCmsObject()); 1000 rootCms.getRequestContext().setSiteRoot(""); 1001 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(rootCms); 1002 try { 1003 CmsResource.checkResourceName(newName); 1004 } catch (CmsIllegalArgumentException e) { 1005 return e.getLocalizedMessage(locale); 1006 } 1007 CmsResource resource = rootCms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1008 String oldPath = resource.getRootPath(); 1009 String parentPath = CmsResource.getParentFolder(oldPath); 1010 String newPath = CmsStringUtil.joinPaths(parentPath, newName); 1011 try { 1012 ensureLock(resource); 1013 rootCms.moveResource(oldPath, newPath); 1014 resource = rootCms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1015 } catch (CmsException e) { 1016 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(rootCms)); 1017 } 1018 tryUnlock(resource); 1019 return null; 1020 } 1021 1022 /** 1023 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#restoreResource(org.opencms.util.CmsUUID, int) 1024 */ 1025 public void restoreResource(CmsUUID structureId, int version) throws CmsRpcException { 1026 1027 CmsObject cms = getCmsObject(); 1028 try { 1029 ensureLock(structureId); 1030 cms.restoreResourceVersion(structureId, version); 1031 try { 1032 CmsResource res = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1033 cms.unlockResource(res); 1034 } catch (Exception e) { 1035 LOG.error(e.getLocalizedMessage(), e); 1036 } 1037 1038 } catch (Exception e) { 1039 error(e); 1040 return; // return stmt will never be reached 1041 } 1042 1043 } 1044 1045 /** 1046 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#saveAliases(org.opencms.util.CmsUUID, java.util.List) 1047 */ 1048 public void saveAliases(CmsUUID structureId, List<CmsAliasBean> aliasBeans) throws CmsRpcException { 1049 1050 try { 1051 m_aliasHelper.saveAliases(structureId, aliasBeans); 1052 } catch (Throwable e) { 1053 error(e); 1054 } 1055 } 1056 1057 /** 1058 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#saveExternalLink(org.opencms.util.CmsUUID, java.lang.String, java.lang.String, java.lang.String) 1059 */ 1060 public void saveExternalLink(CmsUUID structureId, String title, String link, String fileName) 1061 throws CmsRpcException { 1062 1063 try { 1064 CmsObject cms = getCmsObject(); 1065 CmsResource res = cms.readResource(structureId); 1066 ensureLock(res); 1067 CmsFile file = cms.readFile(res); 1068 String oldLink = new String(file.getContents(), CmsLocaleManager.getResourceEncoding(cms, res)); 1069 if (!oldLink.equals(link)) { 1070 file.setContents(link.getBytes(CmsLocaleManager.getResourceEncoding(cms, res))); 1071 cms.writeFile(file); 1072 } 1073 CmsProperty titleProp = cms.readPropertyObject(res, CmsPropertyDefinition.PROPERTY_TITLE, false); 1074 if (titleProp.isNullProperty()) { 1075 titleProp = new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, title, null); 1076 cms.writePropertyObject(cms.getSitePath(res), titleProp); 1077 } else if (!titleProp.getValue().equals(title)) { 1078 titleProp.setStructureValue(title); 1079 cms.writePropertyObject(cms.getSitePath(res), titleProp); 1080 } 1081 if (!res.getName().equals(fileName)) { 1082 String oldSitePath = cms.getSitePath(res); 1083 String newSitePath = CmsStringUtil.joinPaths(CmsResource.getParentFolder(oldSitePath), fileName); 1084 getCmsObject().renameResource(oldSitePath, newSitePath); 1085 } 1086 tryUnlock(res); 1087 // update the offline search indices 1088 OpenCms.getSearchManager().updateOfflineIndexes(); 1089 } catch (Exception e) { 1090 error(e); 1091 } 1092 } 1093 1094 /** 1095 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#saveProperties(org.opencms.gwt.shared.property.CmsPropertyChangeSet) 1096 */ 1097 public void saveProperties(CmsPropertyChangeSet changes) throws CmsRpcException { 1098 1099 String origSiteRoot = getCmsObject().getRequestContext().getSiteRoot(); 1100 try { 1101 getCmsObject().getRequestContext().setSiteRoot(""); 1102 CmsPropertyEditorHelper helper = new CmsPropertyEditorHelper(getCmsObject()); 1103 helper.saveProperties(changes); 1104 } catch (Throwable t) { 1105 error(t); 1106 } finally { 1107 getCmsObject().getRequestContext().setSiteRoot(origSiteRoot); 1108 } 1109 } 1110 1111 /** 1112 * Sets the current cms context.<p> 1113 * 1114 * @param cms the current cms context to set 1115 */ 1116 @Override 1117 public synchronized void setCms(CmsObject cms) { 1118 1119 super.setCms(cms); 1120 m_aliasHelper.setCms(cms); 1121 } 1122 1123 /** 1124 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#substituteLinkForRootPath(java.lang.String, java.lang.String) 1125 */ 1126 public String substituteLinkForRootPath(String currentSiteRoot, String rootPath) throws CmsRpcException { 1127 1128 String result = null; 1129 try { 1130 CmsObject cms = OpenCms.initCmsObject(getCmsObject()); 1131 cms.getRequestContext().setSiteRoot(currentSiteRoot); 1132 result = OpenCms.getLinkManager().substituteLinkForRootPath(cms, rootPath); 1133 } catch (CmsException e) { 1134 error(e); 1135 } 1136 return result; 1137 } 1138 1139 /** 1140 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#syncDeleteResource(org.opencms.util.CmsUUID) 1141 */ 1142 public void syncDeleteResource(CmsUUID structureId) throws CmsRpcException { 1143 1144 deleteResource(structureId); 1145 } 1146 1147 /** 1148 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#undelete(org.opencms.util.CmsUUID) 1149 */ 1150 public void undelete(CmsUUID structureId) throws CmsRpcException { 1151 1152 try { 1153 CmsObject cms = OpenCms.initCmsObject(getCmsObject()); 1154 cms.getRequestContext().setSiteRoot(""); 1155 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL); 1156 ensureLock(resource); 1157 cms.undeleteResource(resource.getRootPath(), true); 1158 } catch (Exception e) { 1159 error(e); 1160 } 1161 } 1162 1163 /** 1164 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#undoChanges(org.opencms.util.CmsUUID, boolean) 1165 */ 1166 public void undoChanges(CmsUUID structureId, boolean undoMove) throws CmsRpcException { 1167 1168 try { 1169 CmsObject cms = getCmsObject(); 1170 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1171 ensureLock(resource); 1172 CmsResourceUndoMode mode = undoMove ? CmsResource.UNDO_MOVE_CONTENT : CmsResource.UNDO_CONTENT; 1173 String path = cms.getSitePath(resource); 1174 cms.undoChanges(path, mode); 1175 try { 1176 resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1177 path = cms.getSitePath(resource); 1178 cms.unlockResource(path); 1179 } catch (CmsException e) { 1180 LOG.info("Could not unlock resource after undoing changes: " + e.getLocalizedMessage(), e); 1181 } 1182 } catch (Throwable e) { 1183 error(e); 1184 } 1185 } 1186 1187 /** 1188 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#validateAliases(org.opencms.util.CmsUUID, java.util.Map) 1189 */ 1190 public Map<String, String> validateAliases(CmsUUID uuid, Map<String, String> aliasPaths) throws CmsRpcException { 1191 1192 try { 1193 return m_aliasHelper.validateAliases(uuid, aliasPaths); 1194 } catch (Throwable e) { 1195 error(e); 1196 } 1197 return null; 1198 1199 } 1200 1201 /** 1202 * Creates a "broken link" bean based on a resource.<p> 1203 * 1204 * @param resource the resource 1205 * 1206 * @return the "broken link" bean with the data from the resource 1207 * 1208 * @throws CmsException if something goes wrong 1209 */ 1210 protected CmsBrokenLinkBean createSitemapBrokenLinkBean(CmsResource resource) throws CmsException { 1211 1212 CmsObject cms = getCmsObject(); 1213 CmsProperty titleProp = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, true); 1214 String typeName = OpenCms.getResourceManager().getResourceType(resource).getTypeName(); 1215 String defaultTitle = ""; 1216 String title = titleProp.getValue(defaultTitle); 1217 String path = cms.getSitePath(resource); 1218 String subtitle = path; 1219 1220 CmsBrokenLinkBean result = new CmsBrokenLinkBean(resource.getStructureId(), title, subtitle, typeName); 1221 1222 return result; 1223 } 1224 1225 /** 1226 * Helper method for creating a VFS entry bean from a resource.<p> 1227 * 1228 * @param resource the resource whose data should be stored in the bean 1229 * @param root true if the resource is a root resource 1230 * 1231 * @return the data bean representing the resource 1232 * 1233 * @throws CmsException if something goes wrong 1234 */ 1235 protected CmsVfsEntryBean makeEntryBean(CmsResource resource, boolean root) throws CmsException { 1236 1237 CmsObject cms = getCmsObject(); 1238 boolean isFolder = resource.isFolder(); 1239 String name = root ? "/" : resource.getName(); 1240 String path = cms.getSitePath(resource); 1241 boolean hasChildren = false; 1242 if (isFolder) { 1243 List<CmsResource> children = cms.getResourcesInFolder( 1244 cms.getRequestContext().getSitePath(resource), 1245 CmsResourceFilter.DEFAULT); 1246 if (!children.isEmpty()) { 1247 hasChildren = true; 1248 } 1249 } 1250 String resourceType = OpenCms.getResourceManager().getResourceType(resource.getTypeId()).getTypeName(); 1251 1252 return new CmsVfsEntryBean(path, name, resourceType, isFolder, hasChildren); 1253 } 1254 1255 /** 1256 * Helper method for creating a list of VFS entry beans from a list of the corresponding resources.<p> 1257 * 1258 * @param resources the list of resources which should be converted to entry beans 1259 * @param root true if the resources in the list are root resources 1260 * 1261 * @return the list of VFS entry beans for the resources 1262 * 1263 * @throws CmsException if something goes wrong 1264 */ 1265 protected List<CmsVfsEntryBean> makeEntryBeans(List<CmsResource> resources, boolean root) throws CmsException { 1266 1267 List<CmsVfsEntryBean> result = new ArrayList<CmsVfsEntryBean>(); 1268 for (CmsResource res : resources) { 1269 result.add(makeEntryBean(res, root)); 1270 } 1271 return result; 1272 } 1273 1274 /** 1275 * Adds additional info items for broken links.<p> 1276 * 1277 * @param cms the CMS context to use 1278 * @param resource the resource from which the additional infos should be read 1279 * @param result the result in which to store the additional info 1280 */ 1281 private void addBrokenLinkAdditionalInfo(CmsObject cms, CmsResource resource, CmsBrokenLinkBean result) { 1282 1283 String dateLastModifiedLabel = org.opencms.workplace.commons.Messages.get().getBundle( 1284 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 1285 org.opencms.workplace.commons.Messages.GUI_LABEL_DATE_LAST_MODIFIED_0); 1286 String dateLastModified = CmsVfsService.formatDateTime(cms, resource.getDateLastModified()); 1287 1288 String userLastModifiedLabel = org.opencms.workplace.commons.Messages.get().getBundle( 1289 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 1290 org.opencms.workplace.commons.Messages.GUI_LABEL_USER_LAST_MODIFIED_0); 1291 String userLastModified = "" + resource.getUserLastModified(); 1292 try { 1293 userLastModified = cms.readUser(resource.getUserLastModified()).getName(); 1294 } catch (CmsException e) { 1295 LOG.error(e.getLocalizedMessage(), e); 1296 } 1297 1298 result.addInfo(dateLastModifiedLabel, dateLastModified); 1299 result.addInfo(userLastModifiedLabel, userLastModified); 1300 } 1301 1302 /** 1303 * Creates a bean representing a historical resource version.<p> 1304 * 1305 * @param cms the current CMS context 1306 * @param historyRes the historical resource 1307 * @param offline true if this resource was read from the offline project 1308 * @param maxVersion the largest version number found 1309 * 1310 * @return the bean representing the historical resource 1311 * @throws CmsException if something goes wrong 1312 */ 1313 private CmsHistoryResourceBean createHistoryResourceBean( 1314 CmsObject cms, 1315 CmsResource historyRes, 1316 boolean offline, 1317 int maxVersion) 1318 throws CmsException { 1319 1320 CmsHistoryResourceBean result = new CmsHistoryResourceBean(); 1321 1322 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1323 result.setStructureId(historyRes.getStructureId()); 1324 result.setRootPath(historyRes.getRootPath()); 1325 result.setDateLastModified(formatDate(historyRes.getDateLastModified(), locale)); 1326 CmsUUID userId = historyRes.getUserLastModified(); 1327 String userName = userId.toString(); 1328 try { 1329 CmsUser user = cms.readUser(userId); 1330 userName = user.getName(); 1331 } catch (CmsException e) { 1332 LOG.warn(e.getLocalizedMessage(), e); 1333 } 1334 result.setUserLastModified(userName); 1335 result.setSize(historyRes.getLength()); 1336 if (historyRes instanceof I_CmsHistoryResource) { 1337 int publishTag = ((I_CmsHistoryResource)historyRes).getPublishTag(); 1338 CmsHistoryProject project = cms.readHistoryProject(publishTag); 1339 long publishDate = project.getPublishingDate(); 1340 result.setDatePublished(formatDate(publishDate, locale)); 1341 int version = ((I_CmsHistoryResource)historyRes).getVersion(); 1342 result.setVersion( 1343 new CmsHistoryVersion( 1344 Integer.valueOf(historyRes.getVersion()), 1345 maxVersion == version ? OfflineOnline.online : null)); 1346 1347 List<CmsProperty> historyProperties = cms.readHistoryPropertyObjects((I_CmsHistoryResource)historyRes); 1348 Map<String, CmsProperty> historyPropertyMap = CmsProperty.toObjectMap(historyProperties); 1349 CmsProperty titleProp = CmsProperty.wrapIfNull( 1350 historyPropertyMap.get(CmsPropertyDefinition.PROPERTY_TITLE)); 1351 CmsProperty descProp = CmsProperty.wrapIfNull( 1352 historyPropertyMap.get(CmsPropertyDefinition.PROPERTY_DESCRIPTION)); 1353 result.setTitle(titleProp.getValue()); 1354 result.setDescription(descProp.getValue()); 1355 } else { 1356 if (offline) { 1357 result.setVersion(new CmsHistoryVersion(null, OfflineOnline.offline)); 1358 } else { 1359 result.setVersion(new CmsHistoryVersion(null, OfflineOnline.online)); 1360 } 1361 } 1362 return result; 1363 } 1364 1365 /** 1366 * Internal method to delete the given resource.<p> 1367 * 1368 * @param resource the resource to delete 1369 * 1370 * @throws CmsException if something goes wrong 1371 */ 1372 private void deleteResource(CmsResource resource) throws CmsException { 1373 1374 String path = null; 1375 CmsObject cms = getCmsObject(); 1376 try { 1377 path = cms.getSitePath(resource); 1378 cms.lockResource(path); 1379 cms.deleteResource(path, CmsResource.DELETE_PRESERVE_SIBLINGS); 1380 // check if any detail container page resources exist to this resource 1381 List<CmsResource> detailContainers = CmsDetailOnlyContainerUtil.getDetailOnlyResources(cms, resource); 1382 for (CmsResource detailContainer : detailContainers) { 1383 deleteResource(detailContainer); 1384 } 1385 } finally { 1386 try { 1387 if (path != null) { 1388 getCmsObject().unlockResource(path); 1389 } 1390 } catch (Exception e) { 1391 // should really never happen 1392 LOG.debug(e.getLocalizedMessage(), e); 1393 } 1394 } 1395 } 1396 1397 /** 1398 * Converts a date to a date bean.<p> 1399 * 1400 * @param date the date to convert 1401 * @param locale the locale to use for the conversion 1402 * 1403 * @return the date bean 1404 */ 1405 private CmsClientDateBean formatDate(long date, Locale locale) { 1406 1407 return new CmsClientDateBean(date, formatDateTime(date)); 1408 } 1409 1410 /** 1411 * Formats the date for the current user's locale.<p> 1412 * 1413 * @param date the date to format 1414 * 1415 * @return the formatted date for the current user's locale 1416 */ 1417 private String formatDateTime(long date) { 1418 1419 CmsObject cms = getCmsObject(); 1420 return formatDateTime(cms, date); 1421 } 1422 1423 /** 1424 * Returns the available locales mapped to there display name for the given resource 1425 * or <code>null</code> in case of non xml-content/xml-page resources.<p> 1426 * 1427 * @param resource the resource 1428 * 1429 * @return the available locales 1430 */ 1431 private LinkedHashMap<String, String> getAvailableLocales(CmsResource resource) { 1432 1433 LinkedHashMap<String, String> result = null; 1434 List<Locale> locales = null; 1435 try { 1436 if (CmsResourceTypeXmlPage.isXmlPage(resource)) { 1437 locales = CmsXmlPageFactory.unmarshal(getCmsObject(), resource, getRequest()).getLocales(); 1438 } else if (CmsResourceTypeXmlContent.isXmlContent(resource)) { 1439 locales = CmsXmlContentFactory.unmarshal(getCmsObject(), resource, getRequest()).getLocales(); 1440 } else if (CmsResourceTypeXmlContainerPage.isContainerPage(resource)) { 1441 locales = CmsXmlContainerPageFactory.unmarshal(getCmsObject(), resource).getLocales(); 1442 } 1443 } catch (CmsException e) { 1444 LOG.warn(e.getLocalizedMessage(), e); 1445 } 1446 if (locales != null) { 1447 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()); 1448 result = new LinkedHashMap<String, String>(); 1449 for (Locale locale : locales) { 1450 result.put(locale.toString(), locale.getDisplayName(wpLocale)); 1451 } 1452 } 1453 return result; 1454 } 1455 1456 /** 1457 * Helper method for converting a map which maps resources to resources to a list of "broken link" beans, 1458 * which have beans representing the source of the corresponding link as children.<p> 1459 * 1460 * @param linkMap a multimap from resource to resources 1461 * 1462 * @return a list of beans representing links which will be broken 1463 * 1464 * @throws CmsException if something goes wrong 1465 */ 1466 private List<CmsBrokenLinkBean> getBrokenLinkBeans(Multimap<CmsResource, CmsResource> linkMap) throws CmsException { 1467 1468 CmsBrokenLinkRenderer brokenLinkRenderer = new CmsBrokenLinkRenderer(getCmsObject()); 1469 1470 Multimap<CmsBrokenLinkBean, CmsBrokenLinkBean> resultMap = HashMultimap.create(); 1471 1472 for (CmsResource source : linkMap.keySet()) { 1473 1474 for (CmsResource target : linkMap.get(source)) { 1475 CmsBrokenLinkBean targetBean = createSitemapBrokenLinkBean(target); 1476 addBrokenLinkAdditionalInfo(getCmsObject(), target, targetBean); 1477 List<CmsBrokenLinkBean> brokenLinkBeans = brokenLinkRenderer.renderBrokenLink(target, source); 1478 for (CmsBrokenLinkBean childBean : brokenLinkBeans) { 1479 addBrokenLinkAdditionalInfo(getCmsObject(), source, childBean); 1480 resultMap.put(childBean, targetBean); 1481 } 1482 } 1483 } 1484 1485 // now convert multimap representation to parent/child representation 1486 for (CmsBrokenLinkBean parent : resultMap.keySet()) { 1487 for (CmsBrokenLinkBean child : resultMap.get(parent)) { 1488 parent.addChild(child); 1489 } 1490 } 1491 return Lists.newArrayList(resultMap.keySet()); 1492 } 1493 1494 /** 1495 * Internal method to get the broken links information for the given resource.<p> 1496 * 1497 * @param entryResource the resource 1498 * 1499 * @return the broken links information 1500 * 1501 * @throws CmsException if something goes wrong 1502 */ 1503 private CmsDeleteResourceBean getBrokenLinks(CmsResource entryResource) throws CmsException { 1504 1505 CmsDeleteResourceBean result = null; 1506 1507 CmsListInfoBean info = null; 1508 List<CmsBrokenLinkBean> brokenLinks = null; 1509 1510 CmsObject cms = getCmsObject(); 1511 String resourceSitePath = cms.getSitePath(entryResource); 1512 1513 ensureSession(); 1514 1515 List<CmsResource> descendants = new ArrayList<CmsResource>(); 1516 HashSet<CmsUUID> deleteIds = new HashSet<CmsUUID>(); 1517 1518 descendants.add(entryResource); 1519 if (entryResource.isFolder()) { 1520 descendants.addAll(cms.readResources(resourceSitePath, CmsResourceFilter.IGNORE_EXPIRATION)); 1521 } 1522 1523 for (CmsResource deleteRes : descendants) { 1524 deleteIds.add(deleteRes.getStructureId()); 1525 } 1526 Multimap<CmsResource, CmsResource> linkMap = HashMultimap.create(); 1527 for (CmsResource resource : descendants) { 1528 List<CmsRelation> relations = cms.getRelationsForResource(resource, CmsRelationFilter.SOURCES); 1529 List<CmsResource> result1 = new ArrayList<CmsResource>(); 1530 for (CmsRelation relation : relations) { 1531 // only add related resources that are not going to be deleted 1532 if (!deleteIds.contains(relation.getSourceId())) { 1533 CmsResource source1 = relation.getSource(cms, CmsResourceFilter.ALL); 1534 if (!source1.getState().isDeleted()) { 1535 result1.add(source1); 1536 } 1537 } 1538 } 1539 List<CmsResource> linkSources = result1; 1540 for (CmsResource source : linkSources) { 1541 linkMap.put(source, resource); 1542 } 1543 } 1544 1545 brokenLinks = getBrokenLinkBeans(linkMap); 1546 info = getPageInfo(entryResource); 1547 1548 result = new CmsDeleteResourceBean(resourceSitePath, info, brokenLinks); 1549 1550 return result; 1551 } 1552 1553 /** 1554 * Gets the resources which link to a given structure id.<p> 1555 * 1556 * @param cms the current CMS context 1557 * @param resource the relation target resource 1558 * @param deleteIds set of resources to delete 1559 * 1560 * @return the list of resources which link to the given id 1561 * 1562 * @throws CmsException if something goes wrong 1563 */ 1564 @SuppressWarnings("unused") 1565 private List<CmsResource> getLinkSources(CmsObject cms, CmsResource resource, HashSet<CmsUUID> deleteIds) 1566 throws CmsException { 1567 1568 List<CmsRelation> relations = cms.getRelationsForResource(resource, CmsRelationFilter.SOURCES); 1569 List<CmsResource> result = new ArrayList<CmsResource>(); 1570 for (CmsRelation relation : relations) { 1571 // only add related resources that are not going to be deleted 1572 if (!deleteIds.contains(relation.getSourceId())) { 1573 CmsResource source = relation.getSource(cms, CmsResourceFilter.ALL); 1574 if (!source.getState().isDeleted()) { 1575 result.add(source); 1576 } 1577 } 1578 } 1579 return result; 1580 } 1581 1582 /** 1583 * Returns a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget}.<p> 1584 * 1585 * @param res the resource to get the page info for 1586 * 1587 * @return a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget}.<p> 1588 * 1589 * @throws CmsLoaderException if the resource type could not be found 1590 * @throws CmsException if something else goes wrong 1591 */ 1592 private CmsListInfoBean getPageInfo(CmsResource res) throws CmsException, CmsLoaderException { 1593 1594 CmsObject cms = getCmsObject(); 1595 return getPageInfo(cms, res); 1596 } 1597 1598 /** 1599 * Returns the preview info for the given resource.<p> 1600 * 1601 *@param cms the CMS context 1602 * @param resource the resource 1603 * @param locale the requested locale 1604 * 1605 * @return the preview info 1606 */ 1607 private CmsPreviewInfo getPreviewInfo(CmsObject cms, CmsResource resource, Locale locale) { 1608 1609 String title = ""; 1610 try { 1611 CmsProperty titleProperty = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, false); 1612 title = titleProperty.getValue(""); 1613 } catch (CmsException e) { 1614 LOG.warn(e.getLocalizedMessage(), e); 1615 } 1616 String noPreviewReason = getNoPreviewReason(cms, resource); 1617 String previewContent = null; 1618 int height = 0; 1619 int width = 0; 1620 LinkedHashMap<String, String> locales = getAvailableLocales(resource); 1621 if (noPreviewReason != null) { 1622 previewContent = "<div>" + noPreviewReason + "</div>"; 1623 return new CmsPreviewInfo( 1624 "<div>" + noPreviewReason + "</div>", 1625 null, 1626 false, 1627 title, 1628 cms.getSitePath(resource), 1629 locale.toString()); 1630 } else if (OpenCms.getResourceManager().matchResourceType( 1631 CmsResourceTypeImage.getStaticTypeName(), 1632 resource.getTypeId())) { 1633 CmsImageScaler scaler = new CmsImageScaler(cms, resource); 1634 String imageLink = null; 1635 if (resource instanceof I_CmsHistoryResource) { 1636 int version = ((I_CmsHistoryResource)resource).getVersion(); 1637 imageLink = OpenCms.getLinkManager().substituteLinkForUnknownTarget( 1638 cms, 1639 CmsHistoryListUtil.getHistoryLink(cms, resource.getStructureId(), "" + version)); 1640 } else { 1641 imageLink = OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath()); 1642 } 1643 imageLink = CmsRequestUtil.appendParameter(imageLink, "random", "" + Math.random()); 1644 previewContent = "<img src=\"" + imageLink + "\" title=\"" + title + "\" style=\"display:block\" />"; 1645 height = scaler.getHeight(); 1646 width = scaler.getWidth(); 1647 } else if (CmsResourceTypeXmlContainerPage.isContainerPage(resource) 1648 || CmsResourceTypeXmlPage.isXmlPage(resource)) { 1649 String link = ""; 1650 if (resource instanceof I_CmsHistoryResource) { 1651 int version = ((I_CmsHistoryResource)resource).getVersion(); 1652 link = OpenCms.getLinkManager().substituteLinkForUnknownTarget( 1653 cms, 1654 CmsHistoryListUtil.getHistoryLink(cms, resource.getStructureId(), "" + version)); 1655 } else { 1656 link = OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath()); 1657 } 1658 return new CmsPreviewInfo(null, link, true, null, cms.getSitePath(resource), locale.toString()); 1659 } else if (CmsResourceTypeXmlContent.isXmlContent(resource)) { 1660 if (!locales.containsKey(locale.toString())) { 1661 locale = CmsLocaleManager.getMainLocale(cms, resource); 1662 } 1663 previewContent = CmsPreviewService.getPreviewContent(getRequest(), getResponse(), cms, resource, locale); 1664 1665 } else if (CmsResourceTypePlain.getStaticTypeId() == resource.getTypeId()) { 1666 try { 1667 previewContent = "<pre><code>" + new String(cms.readFile(resource).getContents()) + "</code></pre>"; 1668 } catch (CmsException e) { 1669 LOG.warn(e.getLocalizedMessage(), e); 1670 previewContent = "<div>" 1671 + Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 1672 Messages.GUI_NO_PREVIEW_CAN_T_READ_CONTENT_0) 1673 + "</div>"; 1674 } 1675 } 1676 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(previewContent)) { 1677 CmsPreviewInfo result = new CmsPreviewInfo( 1678 previewContent, 1679 null, 1680 false, 1681 title, 1682 cms.getSitePath(resource), 1683 locale.toString()); 1684 result.setHeight(height); 1685 result.setWidth(width); 1686 result.setLocales(locales); 1687 return result; 1688 } 1689 if (CmsResourceTypeXmlContainerPage.isContainerPage(resource) || CmsResourceTypeXmlPage.isXmlPage(resource)) { 1690 CmsPreviewInfo result = new CmsPreviewInfo( 1691 null, 1692 OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath()) 1693 + "?" 1694 + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT 1695 + "=true" 1696 + "&__locale=" 1697 + locale.toString(), 1698 false, 1699 title, 1700 cms.getSitePath(resource), 1701 locale.toString()); 1702 result.setLocales(locales); 1703 return result; 1704 } 1705 return new CmsPreviewInfo( 1706 null, 1707 OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath()) 1708 + "?" 1709 + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT 1710 + "=true", 1711 true, 1712 title, 1713 cms.getSitePath(resource), 1714 locale.toString()); 1715 } 1716 1717}