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#getDetailName(org.opencms.util.CmsUUID, java.lang.String) 578 */ 579 public String getDetailName(CmsUUID id, String localeStr) throws CmsRpcException { 580 581 CmsObject cms = getCmsObject(); 582 try { 583 OpenCms.getLocaleManager(); 584 Locale locale = CmsLocaleManager.getLocale(localeStr); 585 return cms.readBestUrlName(id, locale, OpenCms.getLocaleManager().getDefaultLocales()); 586 } catch (Exception e) { 587 error(e); 588 return null; 589 } 590 } 591 592 /** 593 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getFileReplaceInfo(org.opencms.util.CmsUUID) 594 */ 595 public CmsReplaceInfo getFileReplaceInfo(CmsUUID structureId) throws CmsRpcException { 596 597 CmsReplaceInfo result = null; 598 try { 599 CmsObject cms = getCmsObject(); 600 CmsResource res = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 601 CmsListInfoBean fileInfo = getPageInfo(res); 602 boolean isLockable = cms.getLock(res).isLockableBy(cms.getRequestContext().getCurrentUser()); 603 long maxFileSize = OpenCms.getWorkplaceManager().getFileBytesMaxUploadSize(cms); 604 result = new CmsReplaceInfo(fileInfo, cms.getSitePath(res), isLockable, maxFileSize); 605 } catch (Throwable e) { 606 error(e); 607 } 608 return result; 609 } 610 611 /** 612 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getHistoryPreviewInfo(org.opencms.util.CmsUUID, java.lang.String, org.opencms.gwt.shared.CmsHistoryVersion) 613 */ 614 public CmsPreviewInfo getHistoryPreviewInfo(CmsUUID structureId, String locale, CmsHistoryVersion versionBean) 615 throws CmsRpcException { 616 617 try { 618 CmsObject cms = getCmsObject(); 619 CmsResource previewResource = null; 620 if (versionBean.getVersionNumber() != null) { 621 previewResource = (CmsResource)(cms.readResource( 622 structureId, 623 versionBean.getVersionNumber().intValue())); 624 } else if (versionBean.isOffline()) { 625 previewResource = cms.readResource(structureId, CmsResourceFilter.ALL); 626 } else if (versionBean.isOnline()) { 627 CmsProject online = cms.readProject(CmsProject.ONLINE_PROJECT_ID); 628 cms = OpenCms.initCmsObject(cms); 629 cms.getRequestContext().setCurrentProject(online); 630 previewResource = cms.readResource(structureId, CmsResourceFilter.ALL); 631 } 632 CmsFile previewFile = cms.readFile(previewResource); 633 return getPreviewInfo(cms, previewFile, CmsLocaleManager.getLocale(locale)); 634 } catch (Exception e) { 635 error(e); 636 return null; // return statement will never be reached 637 } 638 } 639 640 /** 641 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getLockReportInfo(org.opencms.util.CmsUUID) 642 */ 643 public CmsLockReportInfo getLockReportInfo(CmsUUID structureId) throws CmsRpcException { 644 645 CmsLockReportInfo result = null; 646 CmsObject cms = getCmsObject(); 647 try { 648 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL); 649 List<CmsListInfoBean> lockedInfos = new ArrayList<CmsListInfoBean>(); 650 List<CmsResource> lockedResources = cms.getBlockingLockedResources(resource); 651 if (lockedResources != null) { 652 for (CmsResource lockedResource : lockedResources) { 653 lockedInfos.add(getPageInfoWithLock(cms, lockedResource)); 654 } 655 } 656 result = new CmsLockReportInfo(getPageInfoWithLock(cms, resource), lockedInfos); 657 } catch (Throwable e) { 658 error(e); 659 } 660 return result; 661 } 662 663 /** 664 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPageInfo(org.opencms.util.CmsUUID) 665 */ 666 public CmsListInfoBean getPageInfo(CmsUUID structureId) throws CmsRpcException { 667 668 try { 669 CmsResource res = getCmsObject().readResource(structureId, CmsResourceFilter.ALL); 670 return getPageInfo(res); 671 } catch (Throwable e) { 672 error(e); 673 return null; // will never be reached 674 } 675 } 676 677 /** 678 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPageInfo(java.lang.String) 679 */ 680 public CmsListInfoBean getPageInfo(String vfsPath) throws CmsRpcException { 681 682 try { 683 CmsResource res = getCmsObject().readResource(vfsPath, CmsResourceFilter.IGNORE_EXPIRATION); 684 return getPageInfo(res); 685 } catch (Throwable e) { 686 error(e); 687 return null; // will never be reached 688 } 689 } 690 691 /** 692 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPreviewInfo(org.opencms.util.CmsUUID, java.lang.String) 693 */ 694 public CmsPreviewInfo getPreviewInfo(CmsUUID structureId, String locale) throws CmsRpcException { 695 696 CmsPreviewInfo result = null; 697 try { 698 result = getPreviewInfo( 699 getCmsObject(), 700 getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION), 701 CmsLocaleManager.getLocale(locale)); 702 } catch (Exception e) { 703 error(e); 704 } 705 return result; 706 707 } 708 709 /** 710 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getPreviewInfo(java.lang.String, java.lang.String) 711 */ 712 public CmsPreviewInfo getPreviewInfo(String sitePath, String locale) throws CmsRpcException { 713 714 CmsPreviewInfo result = null; 715 try { 716 result = getPreviewInfo( 717 getCmsObject(), 718 getCmsObject().readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION), 719 CmsLocaleManager.getLocale(locale)); 720 } catch (Exception e) { 721 error(e); 722 } 723 return result; 724 } 725 726 /** 727 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getRenameInfo(org.opencms.util.CmsUUID) 728 */ 729 public CmsRenameInfoBean getRenameInfo(CmsUUID structureId) throws CmsRpcException { 730 731 try { 732 CmsObject cms = getCmsObject(); 733 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 734 CmsListInfoBean listInfo = getPageInfo(resource); 735 String sitePath = cms.getSitePath(resource); 736 return new CmsRenameInfoBean(sitePath, structureId, listInfo); 737 } catch (Throwable e) { 738 error(e); 739 return null; 740 } 741 } 742 743 /** 744 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getResourceHistory(org.opencms.util.CmsUUID) 745 */ 746 public CmsHistoryResourceCollection getResourceHistory(CmsUUID structureId) throws CmsRpcException { 747 748 try { 749 CmsHistoryResourceCollection result = getResourceHistoryInternal(structureId); 750 CmsListInfoBean info = getPageInfo(structureId); 751 result.setContentInfo(info); 752 return result; 753 754 } catch (Exception e) { 755 error(e); 756 return null; // return statement will never be reached 757 } 758 } 759 760 /** 761 * Internal version of getResourceHistory.<p> 762 * 763 * @param structureId the structure id of the resource 764 * 765 * @return the resource history 766 * 767 * @throws CmsException if something goes wrong 768 */ 769 public CmsHistoryResourceCollection getResourceHistoryInternal(CmsUUID structureId) throws CmsException { 770 771 CmsHistoryResourceCollection result = new CmsHistoryResourceCollection(); 772 CmsObject cms = getCmsObject(); 773 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL); 774 List<I_CmsHistoryResource> versions = cms.readAllAvailableVersions(resource); 775 if (!resource.getState().isUnchanged()) { 776 result.add(createHistoryResourceBean(cms, resource, true, -1)); 777 } 778 int maxVersion = 0; 779 780 if (versions.isEmpty()) { 781 try { 782 CmsProject online = cms.readProject(CmsProject.ONLINE_PROJECT_ID); 783 CmsObject onlineCms = OpenCms.initCmsObject(cms); 784 onlineCms.getRequestContext().setCurrentProject(online); 785 CmsResource onlineResource = onlineCms.readResource(structureId, CmsResourceFilter.ALL); 786 CmsHistoryResourceBean onlineResBean = createHistoryResourceBean(onlineCms, onlineResource, false, 0); 787 result.add(onlineResBean); 788 } catch (CmsVfsResourceNotFoundException e) { 789 LOG.info(e.getLocalizedMessage(), e); 790 } catch (Exception e) { 791 LOG.error(e.getLocalizedMessage(), e); 792 } 793 } else { 794 for (I_CmsHistoryResource historyRes : versions) { 795 maxVersion = Math.max(maxVersion, historyRes.getVersion()); 796 } 797 for (I_CmsHistoryResource historyRes : versions) { 798 CmsHistoryResourceBean historyBean = createHistoryResourceBean( 799 cms, 800 (CmsResource)historyRes, 801 false, 802 maxVersion); 803 result.add(historyBean); 804 } 805 } 806 return result; 807 } 808 809 /** 810 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getResourceStatus(org.opencms.util.CmsUUID, java.lang.String, boolean, org.opencms.util.CmsUUID, java.util.Map) 811 */ 812 public CmsResourceStatusBean getResourceStatus( 813 CmsUUID structureId, 814 String contentLocale, 815 boolean includeTargets, 816 CmsUUID detailContentId, 817 Map<String, String> context) 818 throws CmsRpcException { 819 820 if (context == null) { 821 context = new HashMap<>(); 822 } 823 try { 824 CmsObject cms = getCmsObject(); 825 CmsDefaultResourceStatusProvider provider = new CmsDefaultResourceStatusProvider(); 826 return provider.getResourceStatus( 827 getRequest(), 828 cms, 829 structureId, 830 contentLocale, 831 includeTargets, 832 detailContentId, 833 detailContentId != null ? Collections.singletonList(detailContentId) : null, 834 context); 835 } catch (Throwable e) { 836 error(e); 837 return null; 838 } 839 } 840 841 /** 842 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getRestoreInfo(org.opencms.util.CmsUUID) 843 */ 844 public CmsRestoreInfoBean getRestoreInfo(CmsUUID structureId) throws CmsRpcException { 845 846 try { 847 CmsObject cms = getCmsObject(); 848 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 849 CmsListInfoBean listInfo = getPageInfo(resource); 850 CmsRestoreInfoBean result = new CmsRestoreInfoBean(); 851 result.setListInfoBean(listInfo); 852 853 CmsObject onlineCms = OpenCms.initCmsObject(cms); 854 CmsProject onlineProject = cms.readProject(CmsProject.ONLINE_PROJECT_NAME); 855 onlineCms.getRequestContext().setCurrentProject(onlineProject); 856 CmsResource onlineResource = onlineCms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 857 result.setOnlinePath(onlineResource.getRootPath()); 858 result.setOfflinePath(resource.getRootPath()); 859 860 String offlineDate = formatDateTime(resource.getDateLastModified()); 861 String onlineDate = formatDateTime(onlineResource.getDateLastModified()); 862 result.setOfflineDate(offlineDate); 863 result.setOnlineDate(onlineDate); 864 result.setStructureId(structureId); 865 866 CmsObject offlineRootCms = OpenCms.initCmsObject(cms); 867 offlineRootCms.getRequestContext().setSiteRoot(""); 868 CmsObject onlineRootCms = OpenCms.initCmsObject(onlineCms); 869 onlineRootCms.getRequestContext().setSiteRoot(""); 870 String parent = CmsResource.getParentFolder(onlineResource.getRootPath()); 871 boolean canUndoMove = offlineRootCms.existsResource(parent, CmsResourceFilter.IGNORE_EXPIRATION); 872 873 result.setCanUndoMove(canUndoMove); 874 875 return result; 876 } catch (Throwable e) { 877 error(e); 878 return null; 879 } 880 } 881 882 /** 883 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getRootEntries() 884 */ 885 public List<CmsVfsEntryBean> getRootEntries() throws CmsRpcException { 886 887 try { 888 CmsObject cms = getCmsObject(); 889 List<CmsResource> roots = new ArrayList<CmsResource>(); 890 roots.add(cms.readResource("/", CmsResourceFilter.IGNORE_EXPIRATION)); 891 return makeEntryBeans(roots, true); 892 } catch (CmsException e) { 893 error(e); 894 } 895 return null; 896 } 897 898 /** 899 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#getSitePath(org.opencms.util.CmsUUID) 900 */ 901 public String getSitePath(CmsUUID structureId) { 902 903 try { 904 CmsResource resource = getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 905 return getCmsObject().getSitePath(resource); 906 } catch (CmsException e) { 907 if (LOG.isWarnEnabled()) { 908 LOG.warn(e.getMessageContainer(), e); 909 } 910 } 911 return null; 912 } 913 914 /** 915 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#loadLinkInfo(org.opencms.util.CmsUUID) 916 */ 917 public CmsExternalLinkInfoBean loadLinkInfo(CmsUUID structureId) throws CmsRpcException { 918 919 CmsExternalLinkInfoBean info = new CmsExternalLinkInfoBean(); 920 CmsObject cms = getCmsObject(); 921 try { 922 CmsResource linkResource = cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 923 addPageInfo(cms, linkResource, info); 924 CmsFile linkFile = cms.readFile(linkResource); 925 OpenCms.getLocaleManager(); 926 String link = new String(linkFile.getContents(), CmsLocaleManager.getResourceEncoding(cms, linkResource)); 927 info.setLink(link); 928 info.setSitePath(cms.getSitePath(linkResource)); 929 } catch (Exception e) { 930 error(e); 931 } 932 return info; 933 } 934 935 /** 936 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#loadPropertyData(org.opencms.util.CmsUUID) 937 */ 938 public CmsPropertiesBean loadPropertyData(CmsUUID id) throws CmsRpcException { 939 940 CmsObject cms = getCmsObject(); 941 try { 942 CmsPropertyEditorHelper helper = new CmsPropertyEditorHelper(cms); 943 return helper.loadPropertyData(id); 944 } catch (Throwable e) { 945 error(e); 946 } 947 return null; 948 } 949 950 /** 951 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#loadQuickLaunchItems(org.opencms.gwt.shared.CmsQuickLaunchParams) 952 */ 953 public List<CmsQuickLaunchData> loadQuickLaunchItems(CmsQuickLaunchParams params) throws CmsRpcException { 954 955 try { 956 return CmsQuickLaunchProvider.getQuickLaunchData(getCmsObject(), getRequest().getSession(), params); 957 } catch (Exception e) { 958 error(e); 959 return null; 960 } 961 } 962 963 /** 964 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#prepareEdit(org.opencms.util.CmsUUID, java.lang.String) 965 */ 966 public CmsPrepareEditResponse prepareEdit(CmsUUID currentPageId, String pathWithMacros) throws CmsRpcException { 967 968 try { 969 CmsObject cms = getCmsObject(); 970 CmsResource resource = null; 971 if (cms.existsResource(pathWithMacros, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED)) { 972 resource = cms.readResource(pathWithMacros, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 973 } else { 974 CmsResource currentPage = cms.readResource(currentPageId, CmsResourceFilter.IGNORE_EXPIRATION); 975 String path = prepareFileNameForEditor(cms, currentPage, pathWithMacros); 976 resource = cms.readResource(path, CmsResourceFilter.IGNORE_EXPIRATION); 977 } 978 ensureLock(resource); 979 CmsPrepareEditResponse result = new CmsPrepareEditResponse(); 980 result.setRootPath(resource.getRootPath()); 981 result.setSitePath(cms.getSitePath(resource)); 982 result.setStructureId(resource.getStructureId()); 983 return result; 984 } catch (Throwable e) { 985 error(e); 986 } 987 return null; 988 } 989 990 /** 991 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#renameResource(org.opencms.util.CmsUUID, java.lang.String) 992 */ 993 public String renameResource(CmsUUID structureId, String newName) throws CmsRpcException { 994 995 try { 996 return renameResourceInternal(structureId, newName); 997 } catch (Throwable e) { 998 error(e); 999 return null; 1000 } 1001 } 1002 1003 /** 1004 * Internal implementation for renaming a resource.<p> 1005 * 1006 * @param structureId the structure id of the resource to rename 1007 * @param newName the new resource name 1008 * @return either null if the rename was successful, or an error message 1009 * 1010 * @throws CmsException if something goes wrong 1011 */ 1012 public String renameResourceInternal(CmsUUID structureId, String newName) throws CmsException { 1013 1014 newName = newName.trim(); 1015 CmsObject rootCms = OpenCms.initCmsObject(getCmsObject()); 1016 rootCms.getRequestContext().setSiteRoot(""); 1017 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(rootCms); 1018 try { 1019 CmsResource.checkResourceName(newName); 1020 } catch (CmsIllegalArgumentException e) { 1021 return e.getLocalizedMessage(locale); 1022 } 1023 CmsResource resource = rootCms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1024 String oldPath = resource.getRootPath(); 1025 String parentPath = CmsResource.getParentFolder(oldPath); 1026 String newPath = CmsStringUtil.joinPaths(parentPath, newName); 1027 try { 1028 ensureLock(resource); 1029 rootCms.moveResource(oldPath, newPath); 1030 resource = rootCms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1031 } catch (CmsException e) { 1032 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(rootCms)); 1033 } 1034 tryUnlock(resource); 1035 return null; 1036 } 1037 1038 /** 1039 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#restoreResource(org.opencms.util.CmsUUID, int) 1040 */ 1041 public void restoreResource(CmsUUID structureId, int version) throws CmsRpcException { 1042 1043 CmsObject cms = getCmsObject(); 1044 try { 1045 ensureLock(structureId); 1046 cms.restoreResourceVersion(structureId, version); 1047 try { 1048 CmsResource res = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1049 cms.unlockResource(res); 1050 } catch (Exception e) { 1051 LOG.error(e.getLocalizedMessage(), e); 1052 } 1053 1054 } catch (Exception e) { 1055 error(e); 1056 return; // return stmt will never be reached 1057 } 1058 1059 } 1060 1061 /** 1062 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#saveAliases(org.opencms.util.CmsUUID, java.util.List) 1063 */ 1064 public void saveAliases(CmsUUID structureId, List<CmsAliasBean> aliasBeans) throws CmsRpcException { 1065 1066 try { 1067 m_aliasHelper.saveAliases(structureId, aliasBeans); 1068 } catch (Throwable e) { 1069 error(e); 1070 } 1071 } 1072 1073 /** 1074 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#saveExternalLink(org.opencms.util.CmsUUID, java.lang.String, java.lang.String, java.lang.String) 1075 */ 1076 public void saveExternalLink(CmsUUID structureId, String title, String link, String fileName) 1077 throws CmsRpcException { 1078 1079 try { 1080 CmsObject cms = getCmsObject(); 1081 CmsResource res = cms.readResource(structureId); 1082 ensureLock(res); 1083 CmsFile file = cms.readFile(res); 1084 String oldLink = new String(file.getContents(), CmsLocaleManager.getResourceEncoding(cms, res)); 1085 if (!oldLink.equals(link)) { 1086 file.setContents(link.getBytes(CmsLocaleManager.getResourceEncoding(cms, res))); 1087 cms.writeFile(file); 1088 } 1089 CmsProperty titleProp = cms.readPropertyObject(res, CmsPropertyDefinition.PROPERTY_TITLE, false); 1090 if (titleProp.isNullProperty()) { 1091 titleProp = new CmsProperty(CmsPropertyDefinition.PROPERTY_TITLE, title, null); 1092 cms.writePropertyObject(cms.getSitePath(res), titleProp); 1093 } else if (!titleProp.getValue().equals(title)) { 1094 titleProp.setStructureValue(title); 1095 cms.writePropertyObject(cms.getSitePath(res), titleProp); 1096 } 1097 if (!res.getName().equals(fileName)) { 1098 String oldSitePath = cms.getSitePath(res); 1099 String newSitePath = CmsStringUtil.joinPaths(CmsResource.getParentFolder(oldSitePath), fileName); 1100 getCmsObject().renameResource(oldSitePath, newSitePath); 1101 } 1102 tryUnlock(res); 1103 // update the offline search indices 1104 OpenCms.getSearchManager().updateOfflineIndexes(); 1105 } catch (Exception e) { 1106 error(e); 1107 } 1108 } 1109 1110 /** 1111 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#saveProperties(org.opencms.gwt.shared.property.CmsPropertyChangeSet) 1112 */ 1113 public void saveProperties(CmsPropertyChangeSet changes) throws CmsRpcException { 1114 1115 String origSiteRoot = getCmsObject().getRequestContext().getSiteRoot(); 1116 try { 1117 getCmsObject().getRequestContext().setSiteRoot(""); 1118 CmsPropertyEditorHelper helper = new CmsPropertyEditorHelper(getCmsObject()); 1119 helper.saveProperties(changes); 1120 } catch (Throwable t) { 1121 error(t); 1122 } finally { 1123 getCmsObject().getRequestContext().setSiteRoot(origSiteRoot); 1124 } 1125 } 1126 1127 /** 1128 * Sets the current cms context.<p> 1129 * 1130 * @param cms the current cms context to set 1131 */ 1132 @Override 1133 public synchronized void setCms(CmsObject cms) { 1134 1135 super.setCms(cms); 1136 m_aliasHelper.setCms(cms); 1137 } 1138 1139 /** 1140 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#substituteLinkForRootPath(java.lang.String, java.lang.String) 1141 */ 1142 public String substituteLinkForRootPath(String currentSiteRoot, String rootPath) throws CmsRpcException { 1143 1144 String result = null; 1145 try { 1146 CmsObject cms = OpenCms.initCmsObject(getCmsObject()); 1147 cms.getRequestContext().setSiteRoot(currentSiteRoot); 1148 result = OpenCms.getLinkManager().substituteLinkForRootPath(cms, rootPath); 1149 } catch (CmsException e) { 1150 error(e); 1151 } 1152 return result; 1153 } 1154 1155 /** 1156 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#syncDeleteResource(org.opencms.util.CmsUUID) 1157 */ 1158 public void syncDeleteResource(CmsUUID structureId) throws CmsRpcException { 1159 1160 deleteResource(structureId); 1161 } 1162 1163 /** 1164 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#undelete(org.opencms.util.CmsUUID) 1165 */ 1166 public void undelete(CmsUUID structureId) throws CmsRpcException { 1167 1168 try { 1169 CmsObject cms = OpenCms.initCmsObject(getCmsObject()); 1170 cms.getRequestContext().setSiteRoot(""); 1171 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL); 1172 ensureLock(resource); 1173 cms.undeleteResource(resource.getRootPath(), true); 1174 } catch (Exception e) { 1175 error(e); 1176 } 1177 } 1178 1179 /** 1180 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#undoChanges(org.opencms.util.CmsUUID, boolean) 1181 */ 1182 public void undoChanges(CmsUUID structureId, boolean undoMove) throws CmsRpcException { 1183 1184 try { 1185 CmsObject cms = getCmsObject(); 1186 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1187 ensureLock(resource); 1188 CmsResourceUndoMode mode = undoMove ? CmsResource.UNDO_MOVE_CONTENT : CmsResource.UNDO_CONTENT; 1189 String path = cms.getSitePath(resource); 1190 cms.undoChanges(path, mode); 1191 try { 1192 resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1193 path = cms.getSitePath(resource); 1194 cms.unlockResource(path); 1195 } catch (CmsException e) { 1196 LOG.info("Could not unlock resource after undoing changes: " + e.getLocalizedMessage(), e); 1197 } 1198 } catch (Throwable e) { 1199 error(e); 1200 } 1201 } 1202 1203 /** 1204 * @see org.opencms.gwt.shared.rpc.I_CmsVfsService#validateAliases(org.opencms.util.CmsUUID, java.util.Map) 1205 */ 1206 public Map<String, String> validateAliases(CmsUUID uuid, Map<String, String> aliasPaths) throws CmsRpcException { 1207 1208 try { 1209 return m_aliasHelper.validateAliases(uuid, aliasPaths); 1210 } catch (Throwable e) { 1211 error(e); 1212 } 1213 return null; 1214 1215 } 1216 1217 /** 1218 * Creates a "broken link" bean based on a resource.<p> 1219 * 1220 * @param resource the resource 1221 * 1222 * @return the "broken link" bean with the data from the resource 1223 * 1224 * @throws CmsException if something goes wrong 1225 */ 1226 protected CmsBrokenLinkBean createSitemapBrokenLinkBean(CmsResource resource) throws CmsException { 1227 1228 CmsObject cms = getCmsObject(); 1229 CmsProperty titleProp = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, true); 1230 String typeName = OpenCms.getResourceManager().getResourceType(resource).getTypeName(); 1231 String defaultTitle = ""; 1232 String title = titleProp.getValue(defaultTitle); 1233 String path = cms.getSitePath(resource); 1234 String subtitle = path; 1235 1236 CmsBrokenLinkBean result = new CmsBrokenLinkBean(resource.getStructureId(), title, subtitle, typeName); 1237 1238 return result; 1239 } 1240 1241 /** 1242 * Helper method for creating a VFS entry bean from a resource.<p> 1243 * 1244 * @param resource the resource whose data should be stored in the bean 1245 * @param root true if the resource is a root resource 1246 * 1247 * @return the data bean representing the resource 1248 * 1249 * @throws CmsException if something goes wrong 1250 */ 1251 protected CmsVfsEntryBean makeEntryBean(CmsResource resource, boolean root) throws CmsException { 1252 1253 CmsObject cms = getCmsObject(); 1254 boolean isFolder = resource.isFolder(); 1255 String name = root ? "/" : resource.getName(); 1256 String path = cms.getSitePath(resource); 1257 boolean hasChildren = false; 1258 if (isFolder) { 1259 List<CmsResource> children = cms.getResourcesInFolder( 1260 cms.getRequestContext().getSitePath(resource), 1261 CmsResourceFilter.DEFAULT); 1262 if (!children.isEmpty()) { 1263 hasChildren = true; 1264 } 1265 } 1266 String resourceType = OpenCms.getResourceManager().getResourceType(resource.getTypeId()).getTypeName(); 1267 1268 return new CmsVfsEntryBean(path, name, resourceType, isFolder, hasChildren); 1269 } 1270 1271 /** 1272 * Helper method for creating a list of VFS entry beans from a list of the corresponding resources.<p> 1273 * 1274 * @param resources the list of resources which should be converted to entry beans 1275 * @param root true if the resources in the list are root resources 1276 * 1277 * @return the list of VFS entry beans for the resources 1278 * 1279 * @throws CmsException if something goes wrong 1280 */ 1281 protected List<CmsVfsEntryBean> makeEntryBeans(List<CmsResource> resources, boolean root) throws CmsException { 1282 1283 List<CmsVfsEntryBean> result = new ArrayList<CmsVfsEntryBean>(); 1284 for (CmsResource res : resources) { 1285 result.add(makeEntryBean(res, root)); 1286 } 1287 return result; 1288 } 1289 1290 /** 1291 * Adds additional info items for broken links.<p> 1292 * 1293 * @param cms the CMS context to use 1294 * @param resource the resource from which the additional infos should be read 1295 * @param result the result in which to store the additional info 1296 */ 1297 private void addBrokenLinkAdditionalInfo(CmsObject cms, CmsResource resource, CmsBrokenLinkBean result) { 1298 1299 String dateLastModifiedLabel = org.opencms.workplace.commons.Messages.get().getBundle( 1300 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 1301 org.opencms.workplace.commons.Messages.GUI_LABEL_DATE_LAST_MODIFIED_0); 1302 String dateLastModified = CmsVfsService.formatDateTime(cms, resource.getDateLastModified()); 1303 1304 String userLastModifiedLabel = org.opencms.workplace.commons.Messages.get().getBundle( 1305 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 1306 org.opencms.workplace.commons.Messages.GUI_LABEL_USER_LAST_MODIFIED_0); 1307 String userLastModified = "" + resource.getUserLastModified(); 1308 try { 1309 userLastModified = cms.readUser(resource.getUserLastModified()).getName(); 1310 } catch (CmsException e) { 1311 LOG.error(e.getLocalizedMessage(), e); 1312 } 1313 1314 result.addInfo(dateLastModifiedLabel, dateLastModified); 1315 result.addInfo(userLastModifiedLabel, userLastModified); 1316 } 1317 1318 /** 1319 * Creates a bean representing a historical resource version.<p> 1320 * 1321 * @param cms the current CMS context 1322 * @param historyRes the historical resource 1323 * @param offline true if this resource was read from the offline project 1324 * @param maxVersion the largest version number found 1325 * 1326 * @return the bean representing the historical resource 1327 * @throws CmsException if something goes wrong 1328 */ 1329 private CmsHistoryResourceBean createHistoryResourceBean( 1330 CmsObject cms, 1331 CmsResource historyRes, 1332 boolean offline, 1333 int maxVersion) 1334 throws CmsException { 1335 1336 CmsHistoryResourceBean result = new CmsHistoryResourceBean(); 1337 1338 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1339 result.setStructureId(historyRes.getStructureId()); 1340 result.setRootPath(historyRes.getRootPath()); 1341 result.setDateLastModified(formatDate(historyRes.getDateLastModified(), locale)); 1342 CmsUUID userId = historyRes.getUserLastModified(); 1343 String userName = userId.toString(); 1344 try { 1345 CmsUser user = cms.readUser(userId); 1346 userName = user.getName(); 1347 } catch (CmsException e) { 1348 LOG.warn(e.getLocalizedMessage(), e); 1349 } 1350 result.setUserLastModified(userName); 1351 result.setSize(historyRes.getLength()); 1352 if (historyRes instanceof I_CmsHistoryResource) { 1353 int publishTag = ((I_CmsHistoryResource)historyRes).getPublishTag(); 1354 CmsHistoryProject project = cms.readHistoryProject(publishTag); 1355 long publishDate = project.getPublishingDate(); 1356 result.setDatePublished(formatDate(publishDate, locale)); 1357 int version = ((I_CmsHistoryResource)historyRes).getVersion(); 1358 result.setVersion( 1359 new CmsHistoryVersion( 1360 Integer.valueOf(historyRes.getVersion()), 1361 maxVersion == version ? OfflineOnline.online : null)); 1362 1363 List<CmsProperty> historyProperties = cms.readHistoryPropertyObjects((I_CmsHistoryResource)historyRes); 1364 Map<String, CmsProperty> historyPropertyMap = CmsProperty.toObjectMap(historyProperties); 1365 CmsProperty titleProp = CmsProperty.wrapIfNull( 1366 historyPropertyMap.get(CmsPropertyDefinition.PROPERTY_TITLE)); 1367 CmsProperty descProp = CmsProperty.wrapIfNull( 1368 historyPropertyMap.get(CmsPropertyDefinition.PROPERTY_DESCRIPTION)); 1369 result.setTitle(titleProp.getValue()); 1370 result.setDescription(descProp.getValue()); 1371 } else { 1372 if (offline) { 1373 result.setVersion(new CmsHistoryVersion(null, OfflineOnline.offline)); 1374 } else { 1375 result.setVersion(new CmsHistoryVersion(null, OfflineOnline.online)); 1376 } 1377 } 1378 return result; 1379 } 1380 1381 /** 1382 * Internal method to delete the given resource.<p> 1383 * 1384 * @param resource the resource to delete 1385 * 1386 * @throws CmsException if something goes wrong 1387 */ 1388 private void deleteResource(CmsResource resource) throws CmsException { 1389 1390 String path = null; 1391 CmsObject cms = getCmsObject(); 1392 try { 1393 path = cms.getSitePath(resource); 1394 cms.lockResource(path); 1395 cms.deleteResource(path, CmsResource.DELETE_PRESERVE_SIBLINGS); 1396 // check if any detail container page resources exist to this resource 1397 List<CmsResource> detailContainers = CmsDetailOnlyContainerUtil.getDetailOnlyResources(cms, resource); 1398 for (CmsResource detailContainer : detailContainers) { 1399 deleteResource(detailContainer); 1400 } 1401 } finally { 1402 try { 1403 if (path != null) { 1404 getCmsObject().unlockResource(path); 1405 } 1406 } catch (Exception e) { 1407 // should really never happen 1408 LOG.debug(e.getLocalizedMessage(), e); 1409 } 1410 } 1411 } 1412 1413 /** 1414 * Converts a date to a date bean.<p> 1415 * 1416 * @param date the date to convert 1417 * @param locale the locale to use for the conversion 1418 * 1419 * @return the date bean 1420 */ 1421 private CmsClientDateBean formatDate(long date, Locale locale) { 1422 1423 return new CmsClientDateBean(date, formatDateTime(date)); 1424 } 1425 1426 /** 1427 * Formats the date for the current user's locale.<p> 1428 * 1429 * @param date the date to format 1430 * 1431 * @return the formatted date for the current user's locale 1432 */ 1433 private String formatDateTime(long date) { 1434 1435 CmsObject cms = getCmsObject(); 1436 return formatDateTime(cms, date); 1437 } 1438 1439 /** 1440 * Returns the available locales mapped to there display name for the given resource 1441 * or <code>null</code> in case of non xml-content/xml-page resources.<p> 1442 * 1443 * @param resource the resource 1444 * 1445 * @return the available locales 1446 */ 1447 private LinkedHashMap<String, String> getAvailableLocales(CmsResource resource) { 1448 1449 LinkedHashMap<String, String> result = null; 1450 List<Locale> locales = null; 1451 try { 1452 if (CmsResourceTypeXmlPage.isXmlPage(resource)) { 1453 locales = CmsXmlPageFactory.unmarshal(getCmsObject(), resource, getRequest()).getLocales(); 1454 } else if (CmsResourceTypeXmlContent.isXmlContent(resource)) { 1455 locales = CmsXmlContentFactory.unmarshal(getCmsObject(), resource, getRequest()).getLocales(); 1456 } else if (CmsResourceTypeXmlContainerPage.isContainerPage(resource)) { 1457 locales = CmsXmlContainerPageFactory.unmarshal(getCmsObject(), resource).getLocales(); 1458 } 1459 } catch (CmsException e) { 1460 LOG.warn(e.getLocalizedMessage(), e); 1461 } 1462 if (locales != null) { 1463 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()); 1464 result = new LinkedHashMap<String, String>(); 1465 for (Locale locale : locales) { 1466 result.put(locale.toString(), locale.getDisplayName(wpLocale)); 1467 } 1468 } 1469 return result; 1470 } 1471 1472 /** 1473 * Helper method for converting a map which maps resources to resources to a list of "broken link" beans, 1474 * which have beans representing the source of the corresponding link as children.<p> 1475 * 1476 * @param linkMap a multimap from resource to resources 1477 * 1478 * @return a list of beans representing links which will be broken 1479 * 1480 * @throws CmsException if something goes wrong 1481 */ 1482 private List<CmsBrokenLinkBean> getBrokenLinkBeans(Multimap<CmsResource, CmsResource> linkMap) throws CmsException { 1483 1484 CmsBrokenLinkRenderer brokenLinkRenderer = new CmsBrokenLinkRenderer(getCmsObject()); 1485 1486 Multimap<CmsBrokenLinkBean, CmsBrokenLinkBean> resultMap = HashMultimap.create(); 1487 1488 for (CmsResource source : linkMap.keySet()) { 1489 1490 for (CmsResource target : linkMap.get(source)) { 1491 CmsBrokenLinkBean targetBean = createSitemapBrokenLinkBean(target); 1492 addBrokenLinkAdditionalInfo(getCmsObject(), target, targetBean); 1493 List<CmsBrokenLinkBean> brokenLinkBeans = brokenLinkRenderer.renderBrokenLink(target, source); 1494 for (CmsBrokenLinkBean childBean : brokenLinkBeans) { 1495 addBrokenLinkAdditionalInfo(getCmsObject(), source, childBean); 1496 resultMap.put(childBean, targetBean); 1497 } 1498 } 1499 } 1500 1501 // now convert multimap representation to parent/child representation 1502 for (CmsBrokenLinkBean parent : resultMap.keySet()) { 1503 for (CmsBrokenLinkBean child : resultMap.get(parent)) { 1504 parent.addChild(child); 1505 } 1506 } 1507 return Lists.newArrayList(resultMap.keySet()); 1508 } 1509 1510 /** 1511 * Internal method to get the broken links information for the given resource.<p> 1512 * 1513 * @param entryResource the resource 1514 * 1515 * @return the broken links information 1516 * 1517 * @throws CmsException if something goes wrong 1518 */ 1519 private CmsDeleteResourceBean getBrokenLinks(CmsResource entryResource) throws CmsException { 1520 1521 CmsDeleteResourceBean result = null; 1522 1523 CmsListInfoBean info = null; 1524 List<CmsBrokenLinkBean> brokenLinks = null; 1525 1526 CmsObject cms = getCmsObject(); 1527 String resourceSitePath = cms.getSitePath(entryResource); 1528 1529 ensureSession(); 1530 1531 List<CmsResource> descendants = new ArrayList<CmsResource>(); 1532 HashSet<CmsUUID> deleteIds = new HashSet<CmsUUID>(); 1533 1534 descendants.add(entryResource); 1535 if (entryResource.isFolder()) { 1536 descendants.addAll(cms.readResources(resourceSitePath, CmsResourceFilter.IGNORE_EXPIRATION)); 1537 } 1538 1539 for (CmsResource deleteRes : descendants) { 1540 deleteIds.add(deleteRes.getStructureId()); 1541 } 1542 Multimap<CmsResource, CmsResource> linkMap = HashMultimap.create(); 1543 for (CmsResource resource : descendants) { 1544 List<CmsRelation> relations = cms.getRelationsForResource(resource, CmsRelationFilter.SOURCES); 1545 List<CmsResource> result1 = new ArrayList<CmsResource>(); 1546 for (CmsRelation relation : relations) { 1547 // only add related resources that are not going to be deleted 1548 if (!deleteIds.contains(relation.getSourceId())) { 1549 CmsResource source1 = relation.getSource(cms, CmsResourceFilter.ALL); 1550 if (!source1.getState().isDeleted()) { 1551 result1.add(source1); 1552 } 1553 } 1554 } 1555 List<CmsResource> linkSources = result1; 1556 for (CmsResource source : linkSources) { 1557 linkMap.put(source, resource); 1558 } 1559 } 1560 1561 brokenLinks = getBrokenLinkBeans(linkMap); 1562 info = getPageInfo(entryResource); 1563 1564 result = new CmsDeleteResourceBean(resourceSitePath, info, brokenLinks); 1565 1566 return result; 1567 } 1568 1569 /** 1570 * Gets the resources which link to a given structure id.<p> 1571 * 1572 * @param cms the current CMS context 1573 * @param resource the relation target resource 1574 * @param deleteIds set of resources to delete 1575 * 1576 * @return the list of resources which link to the given id 1577 * 1578 * @throws CmsException if something goes wrong 1579 */ 1580 @SuppressWarnings("unused") 1581 private List<CmsResource> getLinkSources(CmsObject cms, CmsResource resource, HashSet<CmsUUID> deleteIds) 1582 throws CmsException { 1583 1584 List<CmsRelation> relations = cms.getRelationsForResource(resource, CmsRelationFilter.SOURCES); 1585 List<CmsResource> result = new ArrayList<CmsResource>(); 1586 for (CmsRelation relation : relations) { 1587 // only add related resources that are not going to be deleted 1588 if (!deleteIds.contains(relation.getSourceId())) { 1589 CmsResource source = relation.getSource(cms, CmsResourceFilter.ALL); 1590 if (!source.getState().isDeleted()) { 1591 result.add(source); 1592 } 1593 } 1594 } 1595 return result; 1596 } 1597 1598 /** 1599 * Returns a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget}.<p> 1600 * 1601 * @param res the resource to get the page info for 1602 * 1603 * @return a bean to display the {@link org.opencms.gwt.client.ui.CmsListItemWidget}.<p> 1604 * 1605 * @throws CmsLoaderException if the resource type could not be found 1606 * @throws CmsException if something else goes wrong 1607 */ 1608 private CmsListInfoBean getPageInfo(CmsResource res) throws CmsException, CmsLoaderException { 1609 1610 CmsObject cms = getCmsObject(); 1611 return getPageInfo(cms, res); 1612 } 1613 1614 /** 1615 * Returns the preview info for the given resource.<p> 1616 * 1617 *@param cms the CMS context 1618 * @param resource the resource 1619 * @param locale the requested locale 1620 * 1621 * @return the preview info 1622 */ 1623 private CmsPreviewInfo getPreviewInfo(CmsObject cms, CmsResource resource, Locale locale) { 1624 1625 String title = ""; 1626 try { 1627 CmsProperty titleProperty = cms.readPropertyObject(resource, CmsPropertyDefinition.PROPERTY_TITLE, false); 1628 title = titleProperty.getValue(""); 1629 } catch (CmsException e) { 1630 LOG.warn(e.getLocalizedMessage(), e); 1631 } 1632 String noPreviewReason = getNoPreviewReason(cms, resource); 1633 String previewContent = null; 1634 int height = 0; 1635 int width = 0; 1636 LinkedHashMap<String, String> locales = getAvailableLocales(resource); 1637 if (noPreviewReason != null) { 1638 previewContent = "<div>" + noPreviewReason + "</div>"; 1639 return new CmsPreviewInfo( 1640 "<div>" + noPreviewReason + "</div>", 1641 null, 1642 false, 1643 title, 1644 cms.getSitePath(resource), 1645 locale.toString()); 1646 } else if (OpenCms.getResourceManager().matchResourceType( 1647 CmsResourceTypeImage.getStaticTypeName(), 1648 resource.getTypeId())) { 1649 CmsImageScaler scaler = new CmsImageScaler(cms, resource); 1650 String imageLink = null; 1651 if (resource instanceof I_CmsHistoryResource) { 1652 int version = ((I_CmsHistoryResource)resource).getVersion(); 1653 imageLink = OpenCms.getLinkManager().substituteLinkForUnknownTarget( 1654 cms, 1655 CmsHistoryListUtil.getHistoryLink(cms, resource.getStructureId(), "" + version)); 1656 } else { 1657 imageLink = OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath()); 1658 } 1659 imageLink = CmsRequestUtil.appendParameter(imageLink, "random", "" + Math.random()); 1660 previewContent = "<img src=\"" + imageLink + "\" title=\"" + title + "\" style=\"display:block\" />"; 1661 height = scaler.getHeight(); 1662 width = scaler.getWidth(); 1663 } else if (CmsResourceTypeXmlContainerPage.isContainerPage(resource) 1664 || CmsResourceTypeXmlPage.isXmlPage(resource)) { 1665 String link = ""; 1666 if (resource instanceof I_CmsHistoryResource) { 1667 int version = ((I_CmsHistoryResource)resource).getVersion(); 1668 link = OpenCms.getLinkManager().substituteLinkForUnknownTarget( 1669 cms, 1670 CmsHistoryListUtil.getHistoryLink(cms, resource.getStructureId(), "" + version)); 1671 } else { 1672 link = OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath()); 1673 } 1674 return new CmsPreviewInfo(null, link, true, null, cms.getSitePath(resource), locale.toString()); 1675 } else if (CmsResourceTypeXmlContent.isXmlContent(resource)) { 1676 if (!locales.containsKey(locale.toString())) { 1677 locale = CmsLocaleManager.getMainLocale(cms, resource); 1678 } 1679 previewContent = CmsPreviewService.getPreviewContent( 1680 getRequest(), 1681 getResponse(), 1682 cms, 1683 resource, 1684 locale); 1685 1686 } else if (CmsResourceTypePlain.getStaticTypeId() == resource.getTypeId()) { 1687 try { 1688 previewContent = "<pre><code>" 1689 + new String(cms.readFile(resource).getContents()) 1690 + "</code></pre>"; 1691 } catch (CmsException e) { 1692 LOG.warn(e.getLocalizedMessage(), e); 1693 previewContent = "<div>" 1694 + Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 1695 Messages.GUI_NO_PREVIEW_CAN_T_READ_CONTENT_0) 1696 + "</div>"; 1697 } 1698 } 1699 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(previewContent)) { 1700 CmsPreviewInfo result = new CmsPreviewInfo( 1701 previewContent, 1702 null, 1703 false, 1704 title, 1705 cms.getSitePath(resource), 1706 locale.toString()); 1707 result.setHeight(height); 1708 result.setWidth(width); 1709 result.setLocales(locales); 1710 return result; 1711 } 1712 if (CmsResourceTypeXmlContainerPage.isContainerPage(resource) || CmsResourceTypeXmlPage.isXmlPage(resource)) { 1713 CmsPreviewInfo result = new CmsPreviewInfo( 1714 null, 1715 OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath()) 1716 + "?" 1717 + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT 1718 + "=true" 1719 + "&__locale=" 1720 + locale.toString(), 1721 false, 1722 title, 1723 cms.getSitePath(resource), 1724 locale.toString()); 1725 result.setLocales(locales); 1726 return result; 1727 } 1728 return new CmsPreviewInfo( 1729 null, 1730 OpenCms.getLinkManager().substituteLinkForUnknownTarget(cms, resource.getRootPath()) 1731 + "?" 1732 + CmsGwtConstants.PARAM_DISABLE_DIRECT_EDIT 1733 + "=true", 1734 true, 1735 title, 1736 cms.getSitePath(resource), 1737 locale.toString()); 1738 } 1739 1740}