001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH & Co. KG, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.client; 029 030import org.opencms.db.CmsResourceState; 031import org.opencms.gwt.client.rpc.CmsRpcAction; 032import org.opencms.gwt.client.rpc.CmsRpcPrefetcher; 033import org.opencms.gwt.client.ui.CmsErrorDialog; 034import org.opencms.gwt.client.ui.CmsNotification; 035import org.opencms.gwt.client.ui.input.upload.CmsFileInfo; 036import org.opencms.gwt.client.util.CmsJsUtil; 037import org.opencms.gwt.client.util.CmsMediaQuery; 038import org.opencms.gwt.client.util.CmsUniqueActiveItemContainer; 039import org.opencms.gwt.client.util.I_CmsSimpleCallback; 040import org.opencms.gwt.shared.CmsCoreData; 041import org.opencms.gwt.shared.CmsGwtConstants; 042import org.opencms.gwt.shared.I_CmsAutoBeanFactory; 043import org.opencms.gwt.shared.rpc.I_CmsCoreService; 044import org.opencms.gwt.shared.rpc.I_CmsCoreServiceAsync; 045import org.opencms.gwt.shared.rpc.I_CmsVfsService; 046import org.opencms.gwt.shared.rpc.I_CmsVfsServiceAsync; 047import org.opencms.util.CmsStringUtil; 048import org.opencms.util.CmsUUID; 049 050import com.google.gwt.core.client.GWT; 051import com.google.gwt.dom.client.Document; 052import com.google.gwt.dom.client.Element; 053import com.google.gwt.dom.client.NodeList; 054import com.google.gwt.user.client.Window.Location; 055import com.google.gwt.user.client.rpc.AsyncCallback; 056import com.google.gwt.user.client.rpc.SerializationException; 057import com.google.gwt.user.client.rpc.ServiceDefTarget; 058import com.google.web.bindery.event.shared.Event; 059import com.google.web.bindery.event.shared.EventBus; 060import com.google.web.bindery.event.shared.SimpleEventBus; 061 062import elemental2.dom.DomGlobal; 063import elemental2.webstorage.WebStorageWindow; 064 065/** 066 * Client side core data provider.<p> 067 * 068 * @since 8.0.0 069 * 070 * @see org.opencms.gwt.CmsGwtActionElement 071 */ 072public final class CmsCoreProvider extends CmsCoreData { 073 074 /** AutoBean factory instance. */ 075 public static final I_CmsAutoBeanFactory AUTO_BEAN_FACTORY = GWT.create(I_CmsAutoBeanFactory.class); 076 077 /** The media query string to detect touch only devices. */ 078 public static final String TOUCH_ONLY_RULE = "(hover: none) or (pointer: coarse)"; 079 080 /** Media query do detect device with no hover capability. */ 081 public static final CmsMediaQuery TOUCH_ONLY = CmsMediaQuery.parse(TOUCH_ONLY_RULE); 082 083 /** Path to system folder. */ 084 public static final String VFS_PATH_SYSTEM = "/system/"; 085 086 /** Internal instance. */ 087 private static CmsCoreProvider INSTANCE; 088 089 /** The core service instance. */ 090 private static I_CmsCoreServiceAsync SERVICE; 091 092 /** The vfs-service instance. */ 093 private static I_CmsVfsServiceAsync VFS_SERVICE; 094 095 /** The unique active item container for the flyout menu. */ 096 private CmsUniqueActiveItemContainer m_activeFlyoutMenu = new CmsUniqueActiveItemContainer(); 097 098 /** The client time when the data is loaded. */ 099 private long m_clientTime; 100 101 /** Event bus for client side events. */ 102 private EventBus m_eventBus = new SimpleEventBus(); 103 104 /** Flag which indicates whether we are in Internet Explorer 7. */ 105 private boolean m_isIe7; 106 107 /** 108 * Prevent instantiation.<p> 109 * 110 * @throws SerializationException if deserialization failed 111 */ 112 protected CmsCoreProvider() 113 throws SerializationException { 114 115 super((CmsCoreData)CmsRpcPrefetcher.getSerializedObjectFromDictionary(getService(), DICT_NAME)); 116 m_clientTime = System.currentTimeMillis(); 117 118 I_CmsUserAgentInfo userAgentInfo = GWT.create(I_CmsUserAgentInfo.class); 119 m_isIe7 = userAgentInfo.isIE7(); 120 } 121 122 /** 123 * Returns the client message instance.<p> 124 * 125 * @return the client message instance 126 */ 127 public static CmsCoreProvider get() { 128 129 if (INSTANCE == null) { 130 try { 131 INSTANCE = new CmsCoreProvider(); 132 } catch (SerializationException e) { 133 CmsErrorDialog.handleException( 134 new Exception( 135 "Deserialization of core data failed. This may be caused by expired java-script resources, please clear your browser cache and try again.", 136 e)); 137 } 138 } 139 return INSTANCE; 140 } 141 142 /** 143 * Gets the content attribute of a meta tag with a given name.<p> 144 * 145 * @param nameToFind the name of the meta tag 146 * 147 * @return the content attribute value of the found meta tag, or null if no meta tag with the given name was found 148 */ 149 public static String getMetaElementContent(String nameToFind) { 150 151 NodeList<Element> metas = Document.get().getDocumentElement().getElementsByTagName("meta"); 152 for (int i = 0; i < metas.getLength(); i++) { 153 Element meta = metas.getItem(i); 154 String name = meta.getAttribute("name"); 155 if (nameToFind.equals(name)) { 156 return meta.getAttribute("content"); 157 } 158 } 159 return null; 160 } 161 162 /** 163 * Returns the core service instance.<p> 164 * 165 * @return the core service instance 166 */ 167 public static I_CmsCoreServiceAsync getService() { 168 169 if (SERVICE == null) { 170 SERVICE = GWT.create(I_CmsCoreService.class); 171 String serviceUrl = CmsCoreProvider.get().link("org.opencms.gwt.CmsCoreService.gwt"); 172 ((ServiceDefTarget)SERVICE).setServiceEntryPoint(serviceUrl); 173 } 174 return SERVICE; 175 } 176 177 /** 178 * Returns the vfs service instance.<p> 179 * 180 * @return the vfs service instance 181 */ 182 public static I_CmsVfsServiceAsync getVfsService() { 183 184 if (VFS_SERVICE == null) { 185 VFS_SERVICE = GWT.create(I_CmsVfsService.class); 186 String serviceUrl = CmsCoreProvider.get().link("org.opencms.gwt.CmsVfsService.gwt"); 187 ((ServiceDefTarget)VFS_SERVICE).setServiceEntryPoint(serviceUrl); 188 } 189 return VFS_SERVICE; 190 } 191 192 /** 193 * Checks if the client is touch-only. 194 * 195 * <p>This uses media queries, but the touch-only status can also be forcibly turned on with the request parameter __touchOnly=1. 196 * 197 * @return true if the client is touch-only 198 */ 199 public static boolean isTouchOnly() { 200 201 return TOUCH_ONLY.matches() 202 || "1".equals(Location.getParameter("__touchOnly")) 203 || "1".equals(CmsJsUtil.getLocalStorage("__touchOnly")); 204 } 205 206 /** 207 * Adds the current site root of this context to the given resource name.<p> 208 * 209 * @param sitePath the resource name 210 * 211 * @return the translated resource name including site root 212 * 213 * @see #removeSiteRoot(String) 214 */ 215 public String addSiteRoot(String sitePath) { 216 217 if (sitePath == null) { 218 return null; 219 } 220 String siteRoot = getAdjustedSiteRoot(getSiteRoot(), sitePath); 221 StringBuffer result = new StringBuffer(128); 222 result.append(siteRoot); 223 if (((siteRoot.length() == 0) || (siteRoot.charAt(siteRoot.length() - 1) != '/')) 224 && ((sitePath.length() == 0) || (sitePath.charAt(0) != '/'))) { 225 // add slash between site root and resource if required 226 result.append('/'); 227 } 228 result.append(sitePath); 229 return result.toString(); 230 } 231 232 /** 233 * Creates a new CmsUUID.<p> 234 * 235 * @param callback the callback to execute 236 */ 237 public void createUUID(final AsyncCallback<CmsUUID> callback) { 238 239 // do not stop/start since we do not want to give any feedback to the user 240 CmsRpcAction<CmsUUID> action = new CmsRpcAction<CmsUUID>() { 241 242 /** 243 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 244 */ 245 @Override 246 public void execute() { 247 248 getService().createUUID(this); 249 } 250 251 /** 252 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 253 */ 254 @Override 255 protected void onResponse(CmsUUID result) { 256 257 callback.onSuccess(result); 258 } 259 }; 260 action.execute(); 261 } 262 263 /** 264 * Fires a client side event.<p> 265 * 266 * @param event the event to fire 267 */ 268 public void fireEvent(Event<?> event) { 269 270 m_eventBus.fireEvent(event); 271 } 272 273 /** 274 * Returns the adjusted site root for a resource using the provided site root as a base.<p> 275 * 276 * Usually, this would be the site root for the current site. 277 * However, if a resource from the <code>/system/</code> folder is requested, 278 * this will be the empty String.<p> 279 * 280 * @param siteRoot the site root of the current site 281 * @param resourcename the resource name to get the adjusted site root for 282 * 283 * @return the adjusted site root for the resource 284 */ 285 public String getAdjustedSiteRoot(String siteRoot, String resourcename) { 286 287 if (resourcename.startsWith(VFS_PATH_SYSTEM) || resourcename.startsWith(getSharedFolder())) { 288 return ""; 289 } else { 290 return siteRoot; 291 } 292 } 293 294 /** 295 * Returns the approximate time on the server.<p> 296 * 297 * @return the approximate server time 298 */ 299 public long getEstimatedServerTime() { 300 301 return m_clientTime + (System.currentTimeMillis() - m_clientTime); 302 } 303 304 /** 305 * Gets the core event bus.<p> 306 * 307 * @return the core event bus 308 */ 309 public EventBus getEventBus() { 310 311 return m_eventBus; 312 } 313 314 /** 315 * Returns the link to view the given resource in the file explorer.<p> 316 * 317 * @param sitePath the resource site path 318 * 319 * @return the link 320 */ 321 public String getExplorerLink(String sitePath) { 322 323 return getFileExplorerLink() + sitePath; 324 } 325 326 /** 327 * Gets the unique active item container which holds a reference to the currently active content element flyout menu.<p> 328 * 329 * @return the unique active item container for flyout menus 330 */ 331 public CmsUniqueActiveItemContainer getFlyoutMenuContainer() { 332 333 return m_activeFlyoutMenu; 334 335 } 336 337 /** 338 * Gets the page id that was last stored in sessionStorage. 339 * 340 * @return the page id that was last stored in session storage 341 */ 342 public CmsUUID getLastPageId() { 343 344 WebStorageWindow window = WebStorageWindow.of(DomGlobal.window); 345 String lastPageStr = window.sessionStorage.getItem(CmsGwtConstants.LAST_CONTAINER_PAGE_ID); 346 if (lastPageStr != null) { 347 return new CmsUUID(lastPageStr); 348 } else { 349 return null; 350 } 351 } 352 353 /** 354 * Fetches the state of a resource from the server.<p> 355 * 356 * @param structureId the structure id of the resource 357 * @param callback the callback which should receive the result 358 */ 359 public void getResourceState(final CmsUUID structureId, final AsyncCallback<CmsResourceState> callback) { 360 361 CmsRpcAction<CmsResourceState> action = new CmsRpcAction<CmsResourceState>() { 362 363 /** 364 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 365 */ 366 @Override 367 public void execute() { 368 369 start(0, false); 370 getService().getResourceState(structureId, this); 371 } 372 373 /** 374 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 375 */ 376 @Override 377 protected void onResponse(CmsResourceState result) { 378 379 stop(false); 380 callback.onSuccess(result); 381 } 382 }; 383 action.execute(); 384 } 385 386 /** 387 * Returns the resource type name for a given filename.<p> 388 * 389 * @param file the file info 390 * 391 * @return the resource type name 392 */ 393 public String getResourceType(CmsFileInfo file) { 394 395 String typeName = null; 396 typeName = getExtensionMapping().get(file.getFileSuffix().toLowerCase()); 397 if (typeName == null) { 398 typeName = "plain"; 399 } 400 return typeName; 401 } 402 403 /** 404 * Returns the resource type name for a given filename.<p> 405 * 406 * @param file the file info 407 * 408 * @return the resource type name 409 */ 410 public String getResourceTypeIcon(CmsFileInfo file) { 411 412 String typeName = null; 413 typeName = getIconMapping().get(file.getFileSuffix().toLowerCase()); 414 if (typeName == null) { 415 typeName = getIconMapping().get(""); 416 } 417 return typeName; 418 } 419 420 /** 421 * Gets the resource type icon for the given path. 422 * 423 * @param path a path 424 * @return the resource type icon 425 */ 426 public String getResourceTypeIcon(String path) { 427 428 String typeName = null; 429 String name = null; 430 int slashPos = path.lastIndexOf("/"); 431 if (slashPos >= 0) { 432 name = path.substring(slashPos + 1); 433 } else { 434 name = path; 435 } 436 int dotPos = name.lastIndexOf("."); 437 String ext = ""; 438 if (dotPos >= 0) { 439 ext = name.substring(dotPos).toLowerCase(); 440 } 441 typeName = getIconMapping().get(ext); 442 if (typeName == null) { 443 typeName = getIconMapping().get(""); 444 } 445 return typeName; 446 } 447 448 /** 449 * Returns if the current user agent is IE7.<p> 450 * 451 * @return <code>true</code> if the current user agent is IE7 452 */ 453 public boolean isIe7() { 454 455 return m_isIe7; 456 } 457 458 /** 459 * Returns an absolute link given a site path.<p> 460 * 461 * @param sitePath the site path 462 * 463 * @return the absolute link 464 */ 465 public String link(String sitePath) { 466 467 return CmsStringUtil.joinPaths(getVfsPrefix(), sitePath); 468 } 469 470 /** 471 * Locks the given resource with a temporary lock.<p> 472 * 473 * @param structureId the resource structure id 474 * @param callback the callback to execute 475 */ 476 public void lock(final CmsUUID structureId, final I_CmsSimpleCallback<Boolean> callback) { 477 478 CmsRpcAction<String> lockAction = new CmsRpcAction<String>() { 479 480 /** 481 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 482 */ 483 @Override 484 public void execute() { 485 486 start(200, false); 487 getService().lockTemp(structureId, this); 488 } 489 490 /** 491 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 492 */ 493 @Override 494 public void onResponse(String result) { 495 496 stop(false); 497 if (result != null) { 498 // unable to lock 499 String text = Messages.get().key(Messages.GUI_LOCK_NOTIFICATION_2, structureId, result); 500 CmsNotification.get().sendDeferred(CmsNotification.Type.WARNING, text); 501 } 502 callback.execute(result == null ? Boolean.TRUE : Boolean.FALSE); 503 } 504 }; 505 lockAction.execute(); 506 } 507 508 /** 509 * Locks the given resource with a temporary lock.<p> 510 * 511 * @param structureId the resource structure id 512 * @param loadTime the time when the requested resource was loaded 513 * @param callback the callback to execute 514 */ 515 public void lock(final CmsUUID structureId, long loadTime, final I_CmsSimpleCallback<Boolean> callback) { 516 517 CmsRpcAction<String> lockAction = new CmsRpcAction<String>() { 518 519 /** 520 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 521 */ 522 @Override 523 public void execute() { 524 525 start(200, false); 526 getService().lockTemp(structureId, loadTime, this); 527 } 528 529 /** 530 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 531 */ 532 @Override 533 public void onResponse(String result) { 534 535 stop(false); 536 if (result != null) { 537 // unable to lock 538 String text = Messages.get().key(Messages.GUI_LOCK_NOTIFICATION_2, structureId, result); 539 CmsNotification.get().sendDeferred(CmsNotification.Type.WARNING, text); 540 } 541 callback.execute(result == null ? Boolean.TRUE : Boolean.FALSE); 542 } 543 }; 544 lockAction.execute(); 545 } 546 547 /** 548 * Locks the given resource with a temporary lock.<p> 549 * 550 * @param sitePath the site path of the resource to lock 551 * @param loadTime the time when the requested resource was loaded 552 * @param callback the callback to execute 553 */ 554 public void lock(final String sitePath, long loadTime, final I_CmsSimpleCallback<Boolean> callback) { 555 556 CmsRpcAction<String> lockAction = new CmsRpcAction<String>() { 557 558 /** 559 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 560 */ 561 @Override 562 public void execute() { 563 564 start(200, false); 565 getService().lockIfExists(sitePath, loadTime, this); 566 } 567 568 /** 569 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 570 */ 571 @Override 572 public void onResponse(String result) { 573 574 stop(false); 575 if (result != null) { 576 // unable to lock 577 String text = Messages.get().key(Messages.GUI_LOCK_NOTIFICATION_2, sitePath, result); 578 CmsNotification.get().sendDeferred(CmsNotification.Type.WARNING, text); 579 } 580 callback.execute(result == null ? Boolean.TRUE : Boolean.FALSE); 581 } 582 }; 583 lockAction.execute(); 584 } 585 586 /** 587 * Tries to lock a resource with a given structure id and returns an error if the locking fails.<p> 588 * 589 * @param structureId the structure id of the resource to lock 590 * @param callback the callback to execute 591 */ 592 public void lockOrReturnError(final CmsUUID structureId, final I_CmsSimpleCallback<String> callback) { 593 594 CmsRpcAction<String> lockAction = new CmsRpcAction<String>() { 595 596 /** 597 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 598 */ 599 @Override 600 public void execute() { 601 602 start(200, false); 603 getService().lockTemp(structureId, this); 604 } 605 606 /** 607 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 608 */ 609 @Override 610 public void onResponse(String result) { 611 612 stop(false); 613 if (result != null) { 614 // unable to lock 615 final String text = Messages.get().key(Messages.GUI_LOCK_NOTIFICATION_2, structureId, result); 616 CmsNotification.get().sendDeferred(CmsNotification.Type.WARNING, text); 617 } 618 callback.execute(result); 619 } 620 }; 621 lockAction.execute(); 622 } 623 624 /** 625 * Tries to lock a resource with a given structure id and returns an error if the locking fails.<p> 626 * 627 * @param structureId the structure id of the resource to lock 628 * @param loadTime the time when the requested resource was loaded 629 * @param callback the callback to execute 630 */ 631 public void lockOrReturnError( 632 final CmsUUID structureId, 633 final long loadTime, 634 final I_CmsSimpleCallback<String> callback) { 635 636 CmsRpcAction<String> lockAction = new CmsRpcAction<String>() { 637 638 /** 639 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 640 */ 641 @Override 642 public void execute() { 643 644 start(200, false); 645 getService().lockTemp(structureId, loadTime, this); 646 } 647 648 /** 649 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 650 */ 651 @Override 652 public void onResponse(String result) { 653 654 stop(false); 655 if (result != null) { 656 // unable to lock 657 final String text = Messages.get().key(Messages.GUI_LOCK_NOTIFICATION_2, structureId, result); 658 CmsNotification.get().sendDeferred(CmsNotification.Type.WARNING, text); 659 } 660 callback.execute(result); 661 } 662 }; 663 lockAction.execute(); 664 } 665 666 /** 667 * Tries to lock a resource with a given site path and returns an error if the locking fails.<p> 668 * If the resource does not exist yet, the next existing ancestor folder will be checked if it is lockable.<p> 669 * 670 * @param sitePath the site path of the resource to lock 671 * @param callback the callback to execute 672 */ 673 public void lockOrReturnError(final String sitePath, final I_CmsSimpleCallback<String> callback) { 674 675 CmsRpcAction<String> lockAction = new CmsRpcAction<String>() { 676 677 /** 678 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 679 */ 680 @Override 681 public void execute() { 682 683 start(200, false); 684 getService().lockIfExists(sitePath, this); 685 } 686 687 /** 688 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 689 */ 690 @Override 691 public void onResponse(String result) { 692 693 stop(false); 694 if (result != null) { 695 // unable to lock 696 final String text = Messages.get().key(Messages.GUI_LOCK_NOTIFICATION_2, sitePath, result); 697 CmsNotification.get().sendDeferred(CmsNotification.Type.WARNING, text); 698 } 699 callback.execute(result); 700 } 701 }; 702 lockAction.execute(); 703 } 704 705 /** 706 * Tries to lock a resource with a given site path and returns an error if the locking fails.<p> 707 * If the resource does not exist yet, the next existing ancestor folder will be checked if it is lockable.<p> 708 * 709 * @param sitePath the site path of the resource to lock 710 * @param loadTime the time when the requested resource was loaded 711 * @param callback the callback to execute 712 */ 713 public void lockOrReturnError( 714 final String sitePath, 715 final long loadTime, 716 final I_CmsSimpleCallback<String> callback) { 717 718 CmsRpcAction<String> lockAction = new CmsRpcAction<String>() { 719 720 /** 721 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 722 */ 723 @Override 724 public void execute() { 725 726 start(200, false); 727 getService().lockIfExists(sitePath, loadTime, this); 728 } 729 730 /** 731 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 732 */ 733 @Override 734 public void onResponse(String result) { 735 736 stop(false); 737 if (result != null) { 738 // unable to lock 739 final String text = Messages.get().key(Messages.GUI_LOCK_NOTIFICATION_2, sitePath, result); 740 CmsNotification.get().sendDeferred(CmsNotification.Type.WARNING, text); 741 } 742 callback.execute(result); 743 } 744 }; 745 lockAction.execute(); 746 } 747 748 /** 749 * Removes the current site root prefix from the given root path, 750 * that is adjusts the resource name for the current site root.<p> 751 * 752 * If the resource name does not start with the current site root, 753 * it is left untouched.<p> 754 * 755 * @param rootPath the resource name 756 * 757 * @return the resource name adjusted for the current site root 758 * 759 * @see #addSiteRoot(String) 760 */ 761 public String removeSiteRoot(String rootPath) { 762 763 String siteRoot = getAdjustedSiteRoot(getSiteRoot(), rootPath); 764 if ((siteRoot != null) 765 && (siteRoot.equals(getSiteRoot())) 766 && rootPath.startsWith(siteRoot) 767 && ((rootPath.length() == siteRoot.length()) || (rootPath.charAt(siteRoot.length()) == '/'))) { 768 rootPath = rootPath.substring(siteRoot.length()); 769 } 770 return rootPath; 771 } 772 773 /** 774 * @see org.opencms.gwt.shared.CmsCoreData#setShowEditorHelp(boolean) 775 */ 776 @Override 777 public void setShowEditorHelp(final boolean show) { 778 779 super.setShowEditorHelp(show); 780 CmsRpcAction<Void> action = new CmsRpcAction<Void>() { 781 782 /** 783 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 784 */ 785 @Override 786 public void execute() { 787 788 getService().setShowEditorHelp(show, this); 789 } 790 791 /** 792 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 793 */ 794 @Override 795 protected void onResponse(Void result) { 796 797 //nothing to do 798 } 799 }; 800 action.execute(); 801 } 802 803 /** 804 * Returns the absolute link to the given root path.<p> 805 * 806 * @param rootPath the root path 807 * @param callback the callback to execute 808 */ 809 public void substituteLinkForRootPath(final String rootPath, final I_CmsSimpleCallback<String> callback) { 810 811 CmsRpcAction<String> action = new CmsRpcAction<String>() { 812 813 @Override 814 public void execute() { 815 816 getVfsService().substituteLinkForRootPath(getSiteRoot(), rootPath, this); 817 } 818 819 @Override 820 protected void onResponse(String result) { 821 822 callback.execute(result); 823 } 824 }; 825 action.execute(); 826 } 827 828 /** 829 * Unlocks the given resource, synchronously.<p> 830 * 831 * @param structureId the resource structure id 832 * 833 * @return <code>true</code> if succeeded, if not a a warning is already shown to the user 834 */ 835 public boolean unlock(final CmsUUID structureId) { 836 837 // lock the sitemap 838 CmsRpcAction<String> unlockAction = new CmsRpcAction<String>() { 839 840 /** 841 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 842 */ 843 @Override 844 public void execute() { 845 846 start(200, false); 847 getService().unlock(structureId, this); 848 } 849 850 /** 851 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 852 */ 853 @Override 854 public void onResponse(String result) { 855 856 stop(false); 857 if (result == null) { 858 // ok 859 return; 860 } 861 // unable to lock 862 String text = Messages.get().key(Messages.GUI_UNLOCK_NOTIFICATION_2, structureId.toString(), result); 863 CmsNotification.get().send(CmsNotification.Type.WARNING, text); 864 } 865 }; 866 return unlockAction.executeSync() == null; 867 } 868 869 /** 870 * Unlocks the given resource, synchronously.<p> 871 * 872 * @param sitePath the resource site path 873 * 874 * @return <code>true</code> if succeeded, if not a a warning is already shown to the user 875 */ 876 public boolean unlock(final String sitePath) { 877 878 // lock the sitemap 879 CmsRpcAction<String> unlockAction = new CmsRpcAction<String>() { 880 881 /** 882 * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute() 883 */ 884 @Override 885 public void execute() { 886 887 start(200, false); 888 getService().unlock(sitePath, this); 889 } 890 891 /** 892 * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object) 893 */ 894 @Override 895 public void onResponse(String result) { 896 897 stop(false); 898 if (result == null) { 899 // ok 900 return; 901 } 902 // unable to lock 903 String text = Messages.get().key(Messages.GUI_UNLOCK_NOTIFICATION_2, sitePath, result); 904 CmsNotification.get().send(CmsNotification.Type.WARNING, text); 905 } 906 }; 907 return unlockAction.executeSync() == null; 908 } 909 910}