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