001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: https://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: https://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt; 029 030import org.opencms.ade.configuration.CmsADEConfigData; 031import org.opencms.ade.configuration.CmsGalleryDisabledTypesMode; 032import org.opencms.db.CmsResourceState; 033import org.opencms.db.CmsUserSettings; 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.CmsResourceFilter; 040import org.opencms.file.CmsUser; 041import org.opencms.file.CmsVfsResourceNotFoundException; 042import org.opencms.flex.CmsFlexController; 043import org.opencms.gwt.shared.CmsBroadcastMessage; 044import org.opencms.gwt.shared.CmsCategoryTreeEntry; 045import org.opencms.gwt.shared.CmsContextMenuEntryBean; 046import org.opencms.gwt.shared.CmsCoreData; 047import org.opencms.gwt.shared.CmsCoreData.AdeContext; 048import org.opencms.gwt.shared.CmsCoreData.UserInfo; 049import org.opencms.gwt.shared.CmsLockInfo; 050import org.opencms.gwt.shared.CmsResourceCategoryInfo; 051import org.opencms.gwt.shared.CmsReturnLinkInfo; 052import org.opencms.gwt.shared.CmsTinyMCEData; 053import org.opencms.gwt.shared.CmsUploadRestrictionInfo; 054import org.opencms.gwt.shared.CmsUserSettingsBean; 055import org.opencms.gwt.shared.CmsValidationQuery; 056import org.opencms.gwt.shared.CmsValidationResult; 057import org.opencms.gwt.shared.rpc.I_CmsCoreService; 058import org.opencms.i18n.CmsMessages; 059import org.opencms.lock.CmsLock; 060import org.opencms.main.CmsBroadcast; 061import org.opencms.main.CmsException; 062import org.opencms.main.CmsIllegalArgumentException; 063import org.opencms.main.CmsLog; 064import org.opencms.main.CmsSessionInfo; 065import org.opencms.main.OpenCms; 066import org.opencms.module.CmsModule; 067import org.opencms.relations.CmsCategory; 068import org.opencms.relations.CmsCategoryService; 069import org.opencms.security.CmsPasswordInfo; 070import org.opencms.security.CmsRole; 071import org.opencms.security.CmsRoleManager; 072import org.opencms.security.CmsSecurityException; 073import org.opencms.site.CmsSite; 074import org.opencms.ui.CmsUserIconHelper; 075import org.opencms.ui.CmsVaadinUtils; 076import org.opencms.ui.I_CmsDialogContext; 077import org.opencms.ui.I_CmsDialogContextWithAdeContext; 078import org.opencms.ui.actions.I_CmsADEAction; 079import org.opencms.ui.apps.A_CmsWorkplaceApp; 080import org.opencms.ui.apps.CmsFileExplorerConfiguration; 081import org.opencms.ui.components.CmsBasicDialog.DialogWidth; 082import org.opencms.ui.contextmenu.CmsContextMenuTreeBuilder; 083import org.opencms.ui.contextmenu.CmsMenuItemVisibilityMode; 084import org.opencms.ui.contextmenu.I_CmsContextMenuItem; 085import org.opencms.ui.dialogs.CmsEmbeddedDialogsUI; 086import org.opencms.util.CmsFileUtil; 087import org.opencms.util.CmsStringUtil; 088import org.opencms.util.CmsTreeNode; 089import org.opencms.util.CmsUUID; 090import org.opencms.workplace.CmsWorkplace; 091import org.opencms.workplace.CmsWorkplaceLoginHandler; 092import org.opencms.workplace.CmsWorkplaceSettings; 093import org.opencms.xml.containerpage.CmsADESessionCache; 094 095import java.util.ArrayList; 096import java.util.Collection; 097import java.util.Collections; 098import java.util.HashMap; 099import java.util.HashSet; 100import java.util.Iterator; 101import java.util.LinkedHashMap; 102import java.util.List; 103import java.util.Locale; 104import java.util.Map; 105import java.util.Map.Entry; 106import java.util.Set; 107import java.util.function.Predicate; 108 109import javax.servlet.http.HttpServletRequest; 110 111import org.apache.commons.collections.Buffer; 112import org.apache.commons.logging.Log; 113 114import com.vaadin.ui.Component; 115import com.vaadin.ui.Window; 116 117/** 118 * Provides general core services.<p> 119 * 120 * @since 8.0.0 121 * 122 * @see org.opencms.gwt.CmsCoreService 123 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService 124 * @see org.opencms.gwt.shared.rpc.I_CmsCoreServiceAsync 125 */ 126public class CmsCoreService extends CmsGwtService implements I_CmsCoreService { 127 128 /** The editor back-link URI. */ 129 private static final String EDITOR_BACKLINK_URI = "/system/workplace/commons/editor-backlink.html"; 130 131 /** The xml-content editor URI. */ 132 private static final String EDITOR_URI = "/system/workplace/editors/editor.jsp"; 133 134 /** The log instance for this class. */ 135 private static final Log LOG = CmsLog.getLog(CmsCoreService.class); 136 137 /** Serialization uid. */ 138 private static final long serialVersionUID = 5915848952948986278L; 139 140 /** The workplace settings. */ 141 private CmsWorkplaceSettings m_workplaceSettings; 142 143 /** 144 * Builds the tree structure for the given categories.<p> 145 * 146 * @param cms the current cms context 147 * @param categories the categories 148 * 149 * @return the tree root element 150 */ 151 public static List<CmsCategoryTreeEntry> buildCategoryTree(CmsObject cms, List<CmsCategory> categories) { 152 153 List<CmsCategoryTreeEntry> result = new ArrayList<CmsCategoryTreeEntry>(); 154 CmsUser user = cms.getRequestContext().getCurrentUser(); 155 CmsUsedCategoriesList usedCategoriesBean = CmsUsedCategoriesList.fromJson( 156 (String)user.getAdditionalInfo(CmsUsedCategoriesList.ADDINFO_USED_CATEGORIES)); 157 Set<String> usedCategories = usedCategoriesBean.getCategories(); 158 for (CmsCategory category : categories) { 159 CmsCategoryTreeEntry current = new CmsCategoryTreeEntry(category); 160 current.setUsed(usedCategories.contains(category.getPath())); 161 current.setSitePath(cms.getRequestContext().removeSiteRoot(category.getRootPath())); 162 String parentPath = CmsResource.getParentFolder(current.getPath()); 163 CmsCategoryTreeEntry parent = null; 164 parent = findCategory(result, parentPath); 165 if (parent != null) { 166 parent.addChild(current); 167 } else { 168 result.add(current); 169 } 170 } 171 return result; 172 } 173 174 /** 175 * Helper method for getting the category beans for the given site path.<p> 176 * 177 * @param cms the CMS context to use 178 * @param sitePath the site path 179 * @return the list of category beans 180 * 181 * @throws CmsException if something goes wrong 182 */ 183 public static List<CmsCategoryTreeEntry> getCategoriesForSitePathStatic(CmsObject cms, String sitePath) 184 throws CmsException { 185 186 return getCategoriesForSitePathStatic(cms, sitePath, null); 187 } 188 189 /** 190 * Helper method for getting the category beans for the given site path.<p> 191 * 192 * @param cms the CMS context to use 193 * @param sitePath the site path 194 * @param localCategoryRepositoryPath the categories for this repository are added separately 195 * @return the list of category beans 196 * 197 * @throws CmsException if something goes wrong 198 */ 199 public static List<CmsCategoryTreeEntry> getCategoriesForSitePathStatic( 200 CmsObject cms, 201 String sitePath, 202 String localCategoryRepositoryPath) 203 throws CmsException { 204 205 List<CmsCategoryTreeEntry> result; 206 CmsCategoryService catService = CmsCategoryService.getInstance(); 207 List<CmsCategory> categories; 208 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 209 // get the categories 210 if (null == localCategoryRepositoryPath) { 211 categories = catService.readCategories(cms, "", true, sitePath); 212 categories = catService.localizeCategories(cms, categories, wpLocale); 213 result = buildCategoryTree(cms, categories); 214 } else { 215 List<String> repositories = catService.getCategoryRepositories(cms, sitePath); 216 repositories.remove(localCategoryRepositoryPath); 217 categories = catService.readCategoriesForRepositories(cms, "", true, repositories); 218 categories = catService.localizeCategories(cms, categories, wpLocale); 219 result = buildCategoryTree(cms, categories); 220 categories = catService.readCategoriesForRepositories( 221 cms, 222 "", 223 true, 224 Collections.singletonList(localCategoryRepositoryPath)); 225 categories = catService.localizeCategories(cms, categories, wpLocale); 226 List<CmsCategoryTreeEntry> localCategories = buildCategoryTree(cms, categories); 227 result.addAll(localCategories); 228 } 229 removeHiddenCategories(cms, result, entry -> false); 230 return result; 231 } 232 233 /** 234 * Returns the context menu entries for the given URI.<p> 235 * 236 * @param cms the cms context 237 * @param structureId the currently requested structure id 238 * @param context the ade context (sitemap or containerpage) 239 * @param params the additional parameters 240 * 241 * @return the context menu entries 242 */ 243 public static List<CmsContextMenuEntryBean> getContextMenuEntries( 244 final CmsObject cms, 245 CmsUUID structureId, 246 final AdeContext context, 247 Map<String, String> params) { 248 249 Map<String, CmsContextMenuEntryBean> entries = new LinkedHashMap<String, CmsContextMenuEntryBean>(); 250 try { 251 final List<CmsResource> resources; 252 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ALL.addRequireVisible()); 253 // in case of sitemap editor check visibility with empty list 254 if (context.equals(AdeContext.sitemapeditor)) { 255 resources = Collections.emptyList(); 256 cms.getRequestContext().setAttribute(I_CmsDialogContext.ATTR_SITEMAP_CONFIG_RESOURCE, resource); 257 } else { 258 resources = Collections.singletonList(resource); 259 } 260 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 261 final Map<String, String> paramsFinal = params != null ? params : new HashMap<>(); 262 // context to check item visibility 263 I_CmsDialogContext dcontext = new I_CmsDialogContextWithAdeContext() { 264 265 public void error(Throwable error) { 266 267 // not supported 268 } 269 270 public void finish(CmsProject project, String siteRoot) { 271 272 // not supported 273 } 274 275 public void finish(Collection<CmsUUID> result) { 276 277 // not supported 278 } 279 280 public void focus(CmsUUID id) { 281 282 // not supported 283 } 284 285 public AdeContext getAdeContext() { 286 287 return context; 288 } 289 290 public List<CmsUUID> getAllStructureIdsInView() { 291 292 return null; 293 } 294 295 public String getAppId() { 296 297 return context.name(); 298 } 299 300 public CmsObject getCms() { 301 302 return cms; 303 } 304 305 public ContextType getContextType() { 306 307 ContextType type; 308 switch (context) { 309 case pageeditor: 310 case editprovider: 311 type = ContextType.containerpageToolbar; 312 break; 313 case sitemapeditor: 314 type = ContextType.sitemapToolbar; 315 break; 316 default: 317 type = ContextType.fileTable; 318 } 319 return type; 320 } 321 322 public Map<String, String> getParameters() { 323 324 return paramsFinal; 325 } 326 327 public List<CmsResource> getResources() { 328 329 return resources; 330 } 331 332 public void navigateTo(String appId) { 333 334 // not supported 335 } 336 337 public void onViewChange() { 338 339 // not supported 340 } 341 342 public void reload() { 343 344 // not supported 345 } 346 347 public void setWindow(Window window) { 348 349 // not supported 350 } 351 352 public void start(String title, Component dialog) { 353 354 // not supported 355 } 356 357 public void start(String title, Component dialog, DialogWidth width) { 358 359 // not supported 360 } 361 362 public void updateUserInfo() { 363 364 // not supported 365 } 366 }; 367 CmsContextMenuTreeBuilder builder = new CmsContextMenuTreeBuilder(dcontext); 368 List<I_CmsContextMenuItem> items = new ArrayList<I_CmsContextMenuItem>(); 369 CmsTreeNode<I_CmsContextMenuItem> root = builder.buildAll( 370 OpenCms.getWorkplaceAppManager().getMenuItemProvider().getMenuItems()); 371 for (CmsTreeNode<I_CmsContextMenuItem> child : root.getChildren()) { 372 child.addDataInPreOrder(items); 373 } 374 Map<String, List<CmsContextMenuEntryBean>> submenus = new HashMap<String, List<CmsContextMenuEntryBean>>(); 375 for (I_CmsContextMenuItem item : items) { 376 if (!item.isLeafItem()) { 377 CmsMenuItemVisibilityMode visibility = item.getVisibility(dcontext); 378 entries.put( 379 item.getId(), 380 new CmsContextMenuEntryBean( 381 visibility.isActive(), 382 true, 383 null, 384 item.getTitle(locale), 385 null, 386 CmsStringUtil.isEmptyOrWhitespaceOnly(visibility.getMessageKey()) 387 ? null 388 : OpenCms.getWorkplaceManager().getMessages(locale).getString(visibility.getMessageKey()), 389 false, 390 new ArrayList<CmsContextMenuEntryBean>())); 391 392 } else if ((item instanceof I_CmsADEAction) && ((I_CmsADEAction)item).isAdeSupported()) { 393 CmsMenuItemVisibilityMode visibility = item.getVisibility(dcontext); 394 395 String jspPath = ((I_CmsADEAction)item).getJspPath(); 396 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(jspPath)) { 397 jspPath = OpenCms.getLinkManager().substituteLink(cms, jspPath); 398 } 399 CmsContextMenuEntryBean itemBean = new CmsContextMenuEntryBean( 400 visibility.isActive(), 401 true, 402 jspPath, 403 item.getTitle(locale), 404 ((I_CmsADEAction)item).getCommandClassName(), 405 CmsStringUtil.isEmptyOrWhitespaceOnly(visibility.getMessageKey()) 406 ? null 407 : OpenCms.getWorkplaceManager().getMessages(locale).getString(visibility.getMessageKey()), 408 false, 409 null); 410 Map<String, String> clientParams = ((I_CmsADEAction)item).getParams(); 411 if (clientParams != null) { 412 clientParams = new HashMap<String, String>(clientParams); 413 for (Entry<String, String> param : clientParams.entrySet()) { 414 String value = CmsVfsService.prepareFileNameForEditor(cms, resource, param.getValue()); 415 param.setValue(value); 416 } 417 itemBean.setParams(clientParams); 418 } 419 entries.put(item.getId(), itemBean); 420 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(item.getParentId())) { 421 List<CmsContextMenuEntryBean> submenu; 422 if (submenus.containsKey(item.getParentId())) { 423 submenu = submenus.get(item.getParentId()); 424 } else { 425 submenu = new ArrayList<CmsContextMenuEntryBean>(); 426 submenus.put(item.getParentId(), submenu); 427 } 428 submenu.add(itemBean); 429 } 430 } 431 } 432 List<CmsContextMenuEntryBean> result = new ArrayList<CmsContextMenuEntryBean>(); 433 for (I_CmsContextMenuItem item : items) { 434 if (entries.containsKey(item.getId())) { 435 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(item.getParentId())) { 436 if (entries.containsKey(item.getParentId())) { 437 CmsContextMenuEntryBean parent = entries.get(item.getParentId()); 438 if (parent.getSubMenu() != null) { 439 parent.getSubMenu().add(entries.get(item.getId())); 440 } 441 } 442 } else { 443 result.add(entries.get(item.getId())); 444 } 445 } 446 } 447 return result; 448 } catch (CmsException e) { 449 // ignore, the user probably has not enough permissions to read the resource 450 LOG.debug(e.getLocalizedMessage(), e); 451 } 452 return Collections.emptyList(); 453 } 454 455 /** 456 * Returns the file explorer link prefix. Append resource site path for complete link.<p> 457 * 458 * @param cms the cms context 459 * @param siteRoot the site root 460 * 461 * @return the file explorer link prefix 462 */ 463 public static String getFileExplorerLink(CmsObject cms, String siteRoot) { 464 465 return CmsVaadinUtils.getWorkplaceLink( 466 CmsFileExplorerConfiguration.APP_ID, 467 cms.getRequestContext().getCurrentProject().getUuid() 468 + A_CmsWorkplaceApp.PARAM_SEPARATOR 469 + siteRoot 470 + A_CmsWorkplaceApp.PARAM_SEPARATOR); 471 } 472 473 /** 474 * Returns the workplace link.<p> 475 * 476 * @param cms the cms context 477 * @param structureId the structure id of the current resource 478 * 479 * @return the workplace link 480 */ 481 public static String getVaadinWorkplaceLink(CmsObject cms, CmsUUID structureId) { 482 483 String resourceRootFolder = null; 484 485 if (structureId != null) { 486 try { 487 resourceRootFolder = CmsResource.getFolderPath( 488 cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED).getRootPath()); 489 } catch (CmsException e) { 490 LOG.debug("Error reading resource for workplace link.", e); 491 } 492 } 493 if (resourceRootFolder == null) { 494 resourceRootFolder = cms.getRequestContext().getSiteRoot(); 495 } 496 return getVaadinWorkplaceLink(cms, resourceRootFolder); 497 498 } 499 500 /** 501 * Returns the workplace link.<p> 502 * 503 * @param cms the cms context 504 * @param resourceRootFolder the resource folder root path 505 * 506 * @return the workplace link 507 */ 508 public static String getVaadinWorkplaceLink(CmsObject cms, String resourceRootFolder) { 509 510 CmsSite site = OpenCms.getSiteManager().getSiteForRootPath(resourceRootFolder); 511 String siteRoot = site != null 512 ? site.getSiteRoot() 513 : OpenCms.getSiteManager().startsWithShared(resourceRootFolder) 514 ? OpenCms.getSiteManager().getSharedFolder() 515 : ""; 516 String sitePath = resourceRootFolder.substring(siteRoot.length()); 517 String link = getFileExplorerLink(cms, siteRoot) + sitePath; 518 return link; 519 } 520 521 /** 522 * Internal helper method for getting a validation service.<p> 523 * 524 * @param name the class name of the validation service 525 * 526 * @return the validation service 527 * 528 * @throws CmsException if something goes wrong 529 */ 530 public static I_CmsValidationService getValidationService(String name) throws CmsException { 531 532 try { 533 Class<?> cls = Class.forName(name, false, I_CmsValidationService.class.getClassLoader()); 534 if (!I_CmsValidationService.class.isAssignableFrom(cls)) { 535 throw new CmsIllegalArgumentException( 536 Messages.get().container(Messages.ERR_VALIDATOR_INCORRECT_TYPE_1, name)); 537 } 538 return (I_CmsValidationService)cls.newInstance(); 539 } catch (ClassNotFoundException e) { 540 throw new CmsException(Messages.get().container(Messages.ERR_VALIDATOR_INSTANTIATION_FAILED_1, name), e); 541 } catch (InstantiationException e) { 542 throw new CmsException(Messages.get().container(Messages.ERR_VALIDATOR_INSTANTIATION_FAILED_1, name), e); 543 } catch (IllegalAccessException e) { 544 throw new CmsException(Messages.get().container(Messages.ERR_VALIDATOR_INSTANTIATION_FAILED_1, name), e); 545 } 546 } 547 548 /** 549 * Instantiates a class given its name using its default constructor.<p> 550 * 551 * Also checks whether the class with the given name is the subclass of another class/interface.<p> 552 * 553 * 554 * @param <T> the type of the interface/class passed as a parameter 555 * 556 * @param anInterface the interface or class against which the class should be checked 557 * @param className the name of the class 558 * @return a new instance of the class 559 * 560 * @throws CmsException if the instantiation fails 561 */ 562 public static <T> T instantiate(Class<T> anInterface, String className) throws CmsException { 563 564 try { 565 Class<?> cls = Class.forName(className, false, anInterface.getClassLoader()); 566 if (!anInterface.isAssignableFrom(cls)) { 567 // class was found, but does not implement the interface 568 throw new CmsIllegalArgumentException( 569 Messages.get().container( 570 Messages.ERR_INSTANTIATION_INCORRECT_TYPE_2, 571 className, 572 anInterface.getName())); 573 } 574 575 // we use another variable so we don't have to put the @SuppressWarnings on the method itself 576 @SuppressWarnings("unchecked") 577 Class<T> typedClass = (Class<T>)cls; 578 return typedClass.newInstance(); 579 } catch (ClassNotFoundException e) { 580 throw new CmsException(Messages.get().container(Messages.ERR_INSTANTIATION_FAILED_1, className), e); 581 } catch (InstantiationException e) { 582 throw new CmsException(Messages.get().container(Messages.ERR_INSTANTIATION_FAILED_1, className), e); 583 } catch (IllegalAccessException e) { 584 throw new CmsException(Messages.get().container(Messages.ERR_INSTANTIATION_FAILED_1, className), e); 585 } 586 } 587 588 /** 589 * Implementation method for getting the link for a given return code.<p> 590 * 591 * @param cms the CMS context 592 * @param returnCode the return code 593 * @return the link for the return code 594 * 595 * @throws CmsException if something goes wrong 596 */ 597 public static CmsReturnLinkInfo internalGetLinkForReturnCode(CmsObject cms, String returnCode) throws CmsException { 598 599 if (CmsUUID.isValidUUID(returnCode)) { 600 try { 601 CmsResource pageRes = cms.readResource(new CmsUUID(returnCode), CmsResourceFilter.IGNORE_EXPIRATION); 602 return new CmsReturnLinkInfo( 603 OpenCms.getLinkManager().substituteLink(cms, pageRes), 604 CmsReturnLinkInfo.Status.ok); 605 } catch (CmsVfsResourceNotFoundException e) { 606 LOG.debug(e.getLocalizedMessage(), e); 607 return new CmsReturnLinkInfo(null, CmsReturnLinkInfo.Status.notfound); 608 } 609 } else { 610 int colonIndex = returnCode.indexOf(':'); 611 if (colonIndex >= 0) { 612 String before = returnCode.substring(0, colonIndex); 613 String after = returnCode.substring(colonIndex + 1); 614 615 if (CmsUUID.isValidUUID(before) && CmsUUID.isValidUUID(after)) { 616 try { 617 CmsUUID pageId = new CmsUUID(before); 618 CmsUUID detailId = new CmsUUID(after); 619 CmsResource pageRes = cms.readResource(pageId); 620 CmsResource folder = pageRes.isFolder() 621 ? pageRes 622 : cms.readParentFolder(pageRes.getStructureId()); 623 String pageLink = OpenCms.getLinkManager().substituteLink(cms, folder); 624 CmsResource detailRes = cms.readResource(detailId); 625 String detailName = cms.getDetailName( 626 detailRes, 627 cms.getRequestContext().getLocale(), 628 OpenCms.getLocaleManager().getDefaultLocales()); 629 String link = CmsFileUtil.removeTrailingSeparator(pageLink) + "/" + detailName; 630 return new CmsReturnLinkInfo(link, CmsReturnLinkInfo.Status.ok); 631 } catch (CmsVfsResourceNotFoundException e) { 632 LOG.debug(e.getLocalizedMessage(), e); 633 return new CmsReturnLinkInfo(null, CmsReturnLinkInfo.Status.notfound); 634 635 } 636 } 637 } 638 throw new IllegalArgumentException("return code has wrong format"); 639 } 640 } 641 642 /** 643 * Fetches the core data.<p> 644 * 645 * @param request the current request 646 * 647 * @return the core data 648 */ 649 public static CmsCoreData prefetch(HttpServletRequest request) { 650 651 CmsCoreService srv = new CmsCoreService(); 652 srv.setCms(CmsFlexController.getCmsObject(request)); 653 srv.setRequest(request); 654 CmsCoreData result = null; 655 try { 656 result = srv.prefetch(); 657 } finally { 658 srv.clearThreadStorage(); 659 } 660 return result; 661 } 662 663 /** 664 * Recursively checks forced visibility for the entry and all its subentries. 665 * 666 * <p>A category is considered to have forced visibility if any of its subcategories match 'selectedCheck'. 667 * 668 * @param entry the category tree entry to check 669 * @param selectedCheck a predicate that checks whether the parents of a category tree entry should be forced to be visible 670 * @return 671 */ 672 private static boolean checkForcedVisibility( 673 CmsCategoryTreeEntry entry, 674 Predicate<CmsCategoryTreeEntry> selectedCheck) { 675 676 if (entry.getForcedVisible() == null) { 677 boolean forcedVisible = selectedCheck.test(entry); 678 for (CmsCategoryTreeEntry child : entry.getChildren()) { 679 forcedVisible |= checkForcedVisibility(child, selectedCheck); 680 // don't break out of the loop, we need to call checkForcedVisibility on everything 681 } 682 entry.setForcedVisible(Boolean.valueOf(forcedVisible)); 683 } 684 return entry.getForcedVisible().booleanValue(); 685 } 686 687 /** 688 * FInds a category in the given tree.<p> 689 * 690 * @param tree the the tree to search in 691 * @param path the path to search for 692 * 693 * @return the category with the given path or <code>null</code> if not found 694 */ 695 private static CmsCategoryTreeEntry findCategory(List<CmsCategoryTreeEntry> tree, String path) { 696 697 if (path == null) { 698 return null; 699 } 700 // we assume that the category to find is descendant of tree 701 List<CmsCategoryTreeEntry> children = tree; 702 boolean found = true; 703 while (found) { 704 if (children == null) { 705 return null; 706 } 707 // since the categories are sorted it is faster to go backwards 708 found = false; 709 for (int i = children.size() - 1; i >= 0; i--) { 710 CmsCategoryTreeEntry child = children.get(i); 711 if (path.equals(child.getPath())) { 712 return child; 713 } 714 if (path.startsWith(child.getPath())) { 715 children = child.getChildren(); 716 found = true; 717 break; 718 } 719 } 720 } 721 return null; 722 } 723 724 /** 725 * Removes hidden category tree entries. 726 * 727 * <p>A category entry is considered hidden if one of its ancestors has the 'category.hidden' property with a value of 'true', and none of its subcategories have a structure id that 728 * is in 'selected'. 729 * 730 * @param cms the current CMS context 731 * @param entries the entries to filter 732 * @param selected the set of structure ids of categories whose ancestors should not be filtered (usually a set of categories already assigned to a resource) 733 */ 734 private static void removeHiddenCategories( 735 CmsObject cms, 736 List<CmsCategoryTreeEntry> entries, 737 Predicate<CmsCategoryTreeEntry> selectedCheck) { 738 739 Iterator<CmsCategoryTreeEntry> iter = entries.iterator(); 740 while (iter.hasNext()) { 741 CmsCategoryTreeEntry entry = iter.next(); 742 if (checkForcedVisibility(entry, selectedCheck)) { 743 // this node is forced visible by one of the descendants, but there could still be other hidden children 744 removeHiddenCategories(cms, entry.getChildren(), selectedCheck); 745 } else { 746 boolean hidden = false; 747 try { 748 CmsResource resource = cms.readResource(entry.getId(), CmsResourceFilter.IGNORE_EXPIRATION); 749 CmsProperty hiddenProp = cms.readPropertyObject( 750 resource, 751 CmsPropertyDefinition.PROPERTY_CATEGORY_HIDDEN, 752 true); 753 hidden = Boolean.parseBoolean(hiddenProp.getValue()); 754 } catch (CmsVfsResourceNotFoundException | CmsSecurityException e) { 755 LOG.debug(e.getLocalizedMessage(), e); 756 } catch (Exception e) { 757 LOG.error(e.getLocalizedMessage(), e); 758 } 759 if (hidden) { 760 iter.remove(); 761 } else { 762 removeHiddenCategories(cms, entry.getChildren(), selectedCheck); 763 } 764 765 } 766 } 767 } 768 769 /** 770 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#changePassword(java.lang.String, java.lang.String, java.lang.String) 771 */ 772 public String changePassword(String oldPassword, String newPassword, String newPasswordConfirm) 773 throws CmsRpcException { 774 775 CmsObject cms = getCmsObject(); 776 CmsPasswordInfo passwordBean = new CmsPasswordInfo(cms); 777 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 778 try { 779 passwordBean.setCurrentPwd(oldPassword); 780 passwordBean.setNewPwd(newPassword); 781 passwordBean.setConfirmation(newPasswordConfirm); 782 passwordBean.applyChanges(); 783 return null; 784 } catch (CmsSecurityException e) { 785 LOG.error(e.getLocalizedMessage(), e); 786 return e.getMessageContainer().key(wpLocale); 787 } catch (CmsIllegalArgumentException e) { 788 LOG.warn(e.getLocalizedMessage(), e); 789 return e.getMessageContainer().key(wpLocale); 790 } catch (Exception e) { 791 error(e); 792 return null; // will never be executed 793 } 794 } 795 796 /** 797 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#createUUID() 798 */ 799 public CmsUUID createUUID() { 800 801 return new CmsUUID(); 802 } 803 804 /** 805 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getBroadcast() 806 */ 807 @SuppressWarnings("unchecked") 808 public List<CmsBroadcastMessage> getBroadcast() { 809 810 setBroadcastPoll(); 811 CmsObject cms = getCmsObject(); 812 Set<CmsBroadcast> repeatedBroadcasts = new HashSet<CmsBroadcast>(); 813 OpenCms.getWorkplaceManager().checkWorkplaceRequest(getRequest(), getCmsObject()); 814 CmsSessionInfo sessionInfo = OpenCms.getSessionManager().getSessionInfo(getRequest().getSession()); 815 if (sessionInfo == null) { 816 return null; 817 } 818 String sessionId = sessionInfo.getSessionId().toString(); 819 Buffer messageQueue = OpenCms.getSessionManager().getBroadcastQueue(sessionId); 820 if (!messageQueue.isEmpty()) { 821 CmsMessages messages = org.opencms.workplace.Messages.get().getBundle( 822 OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject())); 823 List<CmsBroadcastMessage> result = new ArrayList<CmsBroadcastMessage>(); 824 // the user has pending messages, display them all 825 while (!messageQueue.isEmpty()) { 826 827 CmsBroadcast broadcastMessage = (CmsBroadcast)messageQueue.remove(); 828 if ((broadcastMessage.getLastDisplay() 829 + CmsBroadcast.DISPLAY_AGAIN_TIME) < System.currentTimeMillis()) { 830 CmsUserIconHelper helper = OpenCms.getWorkplaceAppManager().getUserIconHelper(); 831 String picPath = ""; 832 if (broadcastMessage.getUser() != null) { 833 picPath = helper.getSmallIconPath(getCmsObject(), broadcastMessage.getUser()); 834 } 835 CmsBroadcastMessage message = new CmsBroadcastMessage( 836 broadcastMessage.getUser() != null 837 ? broadcastMessage.getUser().getName() 838 : messages.key(org.opencms.workplace.Messages.GUI_LABEL_BROADCAST_FROM_SYSTEM_0), 839 picPath, 840 messages.getDateTime(broadcastMessage.getSendTime()), 841 broadcastMessage.getMessage()); 842 result.add(message); 843 if (broadcastMessage.isRepeat()) { 844 repeatedBroadcasts.add(broadcastMessage.withLastDisplay(System.currentTimeMillis())); 845 } 846 } else { 847 repeatedBroadcasts.add(broadcastMessage); 848 } 849 } 850 if (!repeatedBroadcasts.isEmpty()) { 851 for (CmsBroadcast broadcast : repeatedBroadcasts) { 852 messageQueue.add(broadcast); 853 } 854 } 855 return result; 856 } 857 // no message pending, return null 858 return null; 859 } 860 861 /** 862 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategories(java.lang.String, boolean, java.lang.String, boolean) 863 */ 864 public List<CmsCategoryTreeEntry> getCategories( 865 String fromPath, 866 boolean includeSubCats, 867 String refPath, 868 boolean showWithRepositories, 869 Set<String> selected) 870 throws CmsRpcException { 871 872 CmsObject cms = getCmsObject(); 873 Set<CmsUUID> selectedIds = new HashSet<>(); 874 for (String path : selected) { 875 try { 876 CmsResource catResource = cms.readResource(path, CmsResourceFilter.IGNORE_EXPIRATION); 877 selectedIds.add(catResource.getStructureId()); 878 } catch (CmsVfsResourceNotFoundException | CmsSecurityException e) { 879 LOG.debug(e.getLocalizedMessage(), e); 880 } catch (Exception e) { 881 LOG.error(e.getLocalizedMessage(), e); 882 } 883 884 } 885 return getCategoriesInternal( 886 fromPath, 887 includeSubCats, 888 refPath, 889 showWithRepositories, 890 entry -> selectedIds.contains(entry.getId())); 891 } 892 893 /** 894 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategoriesForSitePath(java.lang.String) 895 */ 896 public List<CmsCategoryTreeEntry> getCategoriesForSitePath(String sitePath) throws CmsRpcException { 897 898 List<CmsCategoryTreeEntry> result = null; 899 CmsObject cms = getCmsObject(); 900 try { 901 result = getCategoriesForSitePathStatic(cms, sitePath); 902 } catch (Throwable e) { 903 error(e); 904 } 905 return result; 906 } 907 908 /** 909 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategoryInfo(org.opencms.util.CmsUUID) 910 */ 911 public CmsResourceCategoryInfo getCategoryInfo(CmsUUID structureId) throws CmsRpcException { 912 913 CmsObject cms = getCmsObject(); 914 CmsCategoryService catService = CmsCategoryService.getInstance(); 915 try { 916 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ignoreExpirationOffline(cms)); 917 List<CmsCategory> categories = catService.readResourceCategories(cms, resource); 918 List<String> currentCategories = new ArrayList<String>(); 919 Set<CmsUUID> selected = new HashSet<>(); 920 921 for (CmsCategory category : categories) { 922 currentCategories.add(category.getPath()); 923 selected.add(category.getId()); 924 } 925 return new CmsResourceCategoryInfo( 926 structureId, 927 CmsVfsService.getPageInfoWithLock(cms, resource), 928 currentCategories, 929 getCategoriesInternal( 930 null, 931 true, 932 cms.getSitePath(resource), 933 OpenCms.getWorkplaceManager().isDisplayCategoriesByRepository(), 934 entry -> selected.contains(entry.getId()))); 935 } catch (CmsException e) { 936 error(e); 937 } 938 return null; 939 } 940 941 /** 942 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getContextMenuEntries(org.opencms.util.CmsUUID, org.opencms.gwt.shared.CmsCoreData.AdeContext) 943 */ 944 public List<CmsContextMenuEntryBean> getContextMenuEntries(CmsUUID structureId, AdeContext context) 945 throws CmsRpcException { 946 947 List<CmsContextMenuEntryBean> result = null; 948 try { 949 result = getContextMenuEntries(getCmsObject(), structureId, context, new HashMap<>()); 950 } catch (Throwable e) { 951 error(e); 952 } 953 return result; 954 } 955 956 /** 957 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getContextMenuEntries(org.opencms.util.CmsUUID, org.opencms.gwt.shared.CmsCoreData.AdeContext) 958 */ 959 public List<CmsContextMenuEntryBean> getContextMenuEntries( 960 CmsUUID structureId, 961 AdeContext context, 962 Map<String, String> params) 963 throws CmsRpcException { 964 965 List<CmsContextMenuEntryBean> result = null; 966 try { 967 result = getContextMenuEntries(getCmsObject(), structureId, context, params); 968 } catch (Throwable e) { 969 error(e); 970 } 971 return result; 972 } 973 974 /** 975 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getLinkForReturnCode(java.lang.String) 976 */ 977 public CmsReturnLinkInfo getLinkForReturnCode(String returnCode) throws CmsRpcException { 978 979 try { 980 return internalGetLinkForReturnCode(getCmsObject(), returnCode); 981 } catch (Throwable e) { 982 error(e); 983 return null; 984 985 } 986 } 987 988 /** 989 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getResourceState(org.opencms.util.CmsUUID) 990 */ 991 public CmsResourceState getResourceState(CmsUUID structureId) throws CmsRpcException { 992 993 CmsObject cms = getCmsObject(); 994 CmsResourceState result = null; 995 try { 996 try { 997 CmsResource res = cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 998 result = res.getState(); 999 } catch (CmsVfsResourceNotFoundException e) { 1000 LOG.debug(e.getLocalizedMessage(), e); 1001 result = CmsResourceState.STATE_DELETED; 1002 } 1003 } catch (CmsException e) { 1004 error(e); 1005 } 1006 return result; 1007 } 1008 1009 /** 1010 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getUniqueFileName(java.lang.String, java.lang.String) 1011 */ 1012 public String getUniqueFileName(String parentFolder, String baseName) { 1013 1014 return OpenCms.getResourceManager().getNameGenerator().getUniqueFileName( 1015 getCmsObject(), 1016 parentFolder, 1017 baseName); 1018 } 1019 1020 /** 1021 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getUserInfo() 1022 */ 1023 public UserInfo getUserInfo() { 1024 1025 CmsObject cms = getCmsObject(); 1026 CmsRoleManager roleManager = OpenCms.getRoleManager(); 1027 boolean isAdmin = roleManager.hasRole(cms, CmsRole.ADMINISTRATOR); 1028 boolean isDeveloper = roleManager.hasRole(cms, CmsRole.DEVELOPER); 1029 boolean isCategoryManager = roleManager.hasRole(cms, CmsRole.CATEGORY_EDITOR); 1030 boolean isWorkplaceUser = roleManager.hasRole(cms, CmsRole.WORKPLACE_USER); 1031 UserInfo userInfo = new UserInfo( 1032 cms.getRequestContext().getCurrentUser().getName(), 1033 OpenCms.getWorkplaceAppManager().getUserIconHelper().getSmallIconPath( 1034 cms, 1035 cms.getRequestContext().getCurrentUser()), 1036 isAdmin, 1037 isDeveloper, 1038 isCategoryManager, 1039 isWorkplaceUser, 1040 cms.getRequestContext().getCurrentUser().isManaged()); 1041 return userInfo; 1042 } 1043 1044 /** 1045 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getWorkplaceLink(org.opencms.util.CmsUUID) 1046 */ 1047 public String getWorkplaceLink(CmsUUID structureId) throws CmsRpcException { 1048 1049 String result = null; 1050 CmsObject cms = getCmsObject(); 1051 try { 1052 String resourceRootFolder = structureId != null 1053 ? CmsResource.getFolderPath( 1054 cms.readResource(structureId, CmsResourceFilter.ALL.addRequireVisible()).getRootPath()) 1055 : cms.getRequestContext().getSiteRoot(); 1056 result = getVaadinWorkplaceLink(cms, resourceRootFolder); 1057 } catch (Exception e) { 1058 error(e); 1059 } 1060 return result; 1061 } 1062 1063 /** 1064 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getWorkplaceLinkForPath(java.lang.String) 1065 */ 1066 public String getWorkplaceLinkForPath(String path) throws CmsRpcException { 1067 1068 CmsObject cms = getCmsObject(); 1069 try { 1070 CmsObject workCms = cms; 1071 if (path.startsWith("/sites/")) { 1072 workCms = OpenCms.initCmsObject(cms); 1073 workCms.getRequestContext().setSiteRoot(""); 1074 } 1075 String currentPath = CmsResource.getParentFolder(path); 1076 CmsResource folder = null; 1077 try { 1078 folder = workCms.readResource(currentPath, CmsResourceFilter.IGNORE_EXPIRATION.addRequireVisible()); 1079 } catch (CmsVfsResourceNotFoundException | CmsSecurityException e) { 1080 throw new CmsException(Messages.get().container(Messages.ERR_COULD_NOT_FIND_PARENT_FOLDER_1, path), e); 1081 } 1082 return getVaadinWorkplaceLink(cms, folder.getRootPath()); 1083 } catch (Exception e) { 1084 error(e); 1085 return null; 1086 } 1087 } 1088 1089 /** 1090 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#loadUploadRestrictionInfo() 1091 */ 1092 @Override 1093 public CmsUploadRestrictionInfo loadUploadRestrictionInfo() throws CmsRpcException { 1094 1095 CmsObject cms = getCmsObject(); 1096 CmsUploadRestrictionInfo result = OpenCms.getWorkplaceManager().getUploadRestriction().getUploadRestrictionInfo( 1097 cms); 1098 return result; 1099 1100 } 1101 1102 /** 1103 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#loadUserSettings() 1104 */ 1105 public CmsUserSettingsBean loadUserSettings() throws CmsRpcException { 1106 1107 CmsObject cms = getCmsObject(); 1108 CmsClientUserSettingConverter converter = new CmsClientUserSettingConverter(cms, getRequest(), getResponse()); 1109 try { 1110 return converter.loadSettings(); 1111 } catch (Exception e) { 1112 error(e); 1113 return null; 1114 } 1115 } 1116 1117 /** 1118 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockIfExists(java.lang.String) 1119 */ 1120 public String lockIfExists(String sitePath) throws CmsRpcException { 1121 1122 CmsObject cms = getCmsObject(); 1123 String errorMessage = null; 1124 try { 1125 if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) { 1126 1127 try { 1128 ensureLock(cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)); 1129 } catch (CmsException e) { 1130 errorMessage = e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1131 } 1132 1133 } else { 1134 // check if parent folder may be locked by the current user 1135 String parentFolder = CmsResource.getParentFolder(sitePath); 1136 while ((parentFolder != null) 1137 && !cms.existsResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION)) { 1138 parentFolder = CmsResource.getParentFolder(parentFolder); 1139 } 1140 if (parentFolder != null) { 1141 CmsResource ancestorFolder = cms.readResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION); 1142 CmsUser user = cms.getRequestContext().getCurrentUser(); 1143 CmsLock lock = cms.getLock(ancestorFolder); 1144 if (!lock.isLockableBy(user)) { 1145 errorMessage = "Can not lock parent folder '" + parentFolder + "'."; 1146 } 1147 } else { 1148 errorMessage = "Can not access any parent folder."; 1149 } 1150 } 1151 } catch (Throwable e) { 1152 error(e); 1153 } 1154 1155 return errorMessage; 1156 } 1157 1158 /** 1159 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockIfExists(java.lang.String, long) 1160 */ 1161 public String lockIfExists(String sitePath, long loadTime) throws CmsRpcException { 1162 1163 CmsObject cms = getCmsObject(); 1164 String errorMessage = null; 1165 try { 1166 if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) { 1167 1168 try { 1169 CmsResource resource = cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION); 1170 if (resource.getDateLastModified() > loadTime) { 1171 // the resource has been changed since it was loaded 1172 CmsUser user = null; 1173 try { 1174 user = cms.readUser(resource.getUserLastModified()); 1175 } catch (CmsException e) { 1176 // ignore 1177 } 1178 CmsMessages messages = Messages.get().getBundle( 1179 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1180 return user != null 1181 ? messages.key( 1182 Messages.ERR_LOCKING_MODIFIED_RESOURCE_2, 1183 resource.getRootPath(), 1184 user.getFullName()) 1185 : messages.key(Messages.ERR_LOCKING_MODIFIED_RESOURCE_1, resource.getRootPath()); 1186 } 1187 ensureLock(resource); 1188 } catch (CmsException e) { 1189 errorMessage = e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1190 } 1191 1192 } else { 1193 // check if parent folder may be locked by the current user 1194 String parentFolder = CmsResource.getParentFolder(sitePath); 1195 while ((parentFolder != null) 1196 && !cms.existsResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION)) { 1197 parentFolder = CmsResource.getParentFolder(parentFolder); 1198 } 1199 if (parentFolder != null) { 1200 CmsResource ancestorFolder = cms.readResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION); 1201 CmsUser user = cms.getRequestContext().getCurrentUser(); 1202 CmsLock lock = cms.getLock(ancestorFolder); 1203 if (!lock.isLockableBy(user)) { 1204 errorMessage = "Can not lock parent folder '" + parentFolder + "'."; 1205 } 1206 } else { 1207 errorMessage = "Can not access any parent folder."; 1208 } 1209 } 1210 } catch (Throwable e) { 1211 error(e); 1212 } 1213 1214 return errorMessage; 1215 } 1216 1217 /** 1218 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockTemp(org.opencms.util.CmsUUID) 1219 */ 1220 public String lockTemp(CmsUUID structureId) throws CmsRpcException { 1221 1222 CmsObject cms = getCmsObject(); 1223 try { 1224 try { 1225 ensureLock(structureId); 1226 } catch (CmsException e) { 1227 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1228 } 1229 } catch (Throwable e) { 1230 error(e); 1231 } 1232 return null; 1233 } 1234 1235 /** 1236 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockTemp(org.opencms.util.CmsUUID, long) 1237 */ 1238 public String lockTemp(CmsUUID structureId, long loadTime) throws CmsRpcException { 1239 1240 CmsObject cms = getCmsObject(); 1241 try { 1242 try { 1243 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1244 if (resource.getDateLastModified() > loadTime) { 1245 // the resource has been changed since it was loaded 1246 CmsUser user = null; 1247 try { 1248 user = cms.readUser(resource.getUserLastModified()); 1249 } catch (CmsException e) { 1250 // ignore 1251 } 1252 CmsMessages messages = Messages.get().getBundle( 1253 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1254 return user != null 1255 ? messages.key(Messages.ERR_LOCKING_MODIFIED_RESOURCE_2, resource.getRootPath(), user.getFullName()) 1256 : messages.key(Messages.ERR_LOCKING_MODIFIED_RESOURCE_1, resource.getRootPath()); 1257 } 1258 ensureLock(resource); 1259 } catch (CmsException e) { 1260 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1261 } 1262 } catch (Throwable e) { 1263 error(e); 1264 } 1265 return null; 1266 } 1267 1268 /** 1269 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#prefetch() 1270 */ 1271 public CmsCoreData prefetch() { 1272 1273 CmsObject cms = getCmsObject(); 1274 String navigationUri = cms.getRequestContext().getUri(); 1275 CmsADEConfigData sitemapConfig = OpenCms.getADEManager().lookupConfigurationWithCache( 1276 cms, 1277 cms.getRequestContext().getRootUri()); 1278 boolean toolbarVisible = CmsADESessionCache.getCache(getRequest(), getCmsObject()).isToolbarVisible(); 1279 boolean isShowHelp = OpenCms.getADEManager().isShowEditorHelp(cms); 1280 1281 CmsUUID structureId = null; 1282 1283 try { 1284 CmsResource requestedResource = cms.readResource( 1285 cms.getRequestContext().getUri(), 1286 CmsResourceFilter.ignoreExpirationOffline(cms)); 1287 structureId = requestedResource.getStructureId(); 1288 } catch (CmsException e) { 1289 // may happen in case of VAADIN UI 1290 LOG.debug("Could not read resource for URI.", e); 1291 structureId = CmsUUID.getNullUUID(); 1292 } 1293 String loginUrl = CmsWorkplaceLoginHandler.LOGIN_FORM; 1294 try { 1295 loginUrl = cms.readPropertyObject( 1296 cms.getRequestContext().getUri(), 1297 CmsPropertyDefinition.PROPERTY_LOGIN_FORM, 1298 true).getValue(loginUrl); 1299 } catch (CmsException e) { 1300 log(e.getLocalizedMessage(), e); 1301 } 1302 String defaultWorkplaceLink = OpenCms.getSystemInfo().getWorkplaceContext(); 1303 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1304 UserInfo userInfo = getUserInfo(); 1305 String aboutLink = OpenCms.getLinkManager().substituteLink( 1306 getCmsObject(), 1307 "/system/workplace/commons/about.jsp"); 1308 String tinyMCE = CmsWorkplace.getStaticResourceUri("/editors/tinymce/jscripts/tinymce/tinymce.min.js"); 1309 boolean uploadDisabled = OpenCms.getWorkplaceManager().isAdeGalleryUploadDisabled(cms); 1310 CmsUploadRestrictionInfo uploadRestrictionInfo = OpenCms.getWorkplaceManager().getUploadRestriction().getUploadRestrictionInfo( 1311 cms); 1312 String categoryBaseFolder = CmsCategoryService.getInstance().getRepositoryBaseFolderName(cms); 1313 CmsGalleryDisabledTypesMode disabledTypesMode = sitemapConfig.getDisabledTypeMode( 1314 CmsGalleryDisabledTypesMode.mark); 1315 boolean hideDisabledTypes = disabledTypesMode == CmsGalleryDisabledTypesMode.hide; 1316 getWorkplaceSettings().getUserSettings(); 1317 String checkReuseWarning = CmsUserSettings.getAdditionalPreference(cms, "checkReuseWarning", true); 1318 boolean warnWhenEditingReusedElement = Boolean.parseBoolean(checkReuseWarning); 1319 1320 CmsCoreData data = new CmsCoreData( 1321 EDITOR_URI, 1322 EDITOR_BACKLINK_URI, 1323 loginUrl, 1324 OpenCms.getStaticExportManager().getVfsPrefix(), 1325 getFileExplorerLink(cms, cms.getRequestContext().getSiteRoot()), 1326 OpenCms.getSystemInfo().getStaticResourceContext(), 1327 CmsEmbeddedDialogsUI.getEmbeddedDialogsContextPath(), 1328 cms.getRequestContext().getSiteRoot(), 1329 OpenCms.getSiteManager().getSharedFolder(), 1330 cms.getRequestContext().getCurrentProject().getId(), 1331 cms.getRequestContext().getLocale().toString(), 1332 wpLocale.toString(), 1333 cms.getRequestContext().getUri(), 1334 navigationUri, 1335 structureId, 1336 new HashMap<String, String>(OpenCms.getResourceManager().getExtensionMapping()), 1337 CmsIconUtil.getExtensionIconMapping(), 1338 System.currentTimeMillis(), 1339 isShowHelp, 1340 toolbarVisible, 1341 defaultWorkplaceLink, 1342 aboutLink, 1343 userInfo, 1344 OpenCms.getWorkplaceManager().getFileBytesMaxUploadSize(getCmsObject()), 1345 OpenCms.getWorkplaceManager().isKeepAlive(), 1346 uploadDisabled, 1347 OpenCms.getADEManager().getParameters(getCmsObject()), 1348 uploadRestrictionInfo, 1349 categoryBaseFolder, 1350 hideDisabledTypes, 1351 warnWhenEditingReusedElement); 1352 CmsTinyMCEData tinyMCEData = new CmsTinyMCEData(); 1353 tinyMCEData.setLink(tinyMCE); 1354 data.setTinymce(tinyMCEData); 1355 data.setMaxLocaleButtons(OpenCms.getWorkplaceManager().getEditorMaxLocaleButtons()); 1356 return data; 1357 } 1358 1359 /** 1360 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#saveUsedCategory(java.lang.String) 1361 */ 1362 @Override 1363 public void saveUsedCategory(String category) throws CmsRpcException { 1364 1365 try { 1366 CmsObject cms = getCmsObject(); 1367 CmsUsedCategoriesList.addUsedCategoryForCurrentUser(cms, category); 1368 } catch (Exception e) { 1369 LOG.error(e.getLocalizedMessage(), e); 1370 error(e); 1371 } 1372 } 1373 1374 /** 1375 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#saveUserSettings(java.util.Map, java.util.Set) 1376 */ 1377 public void saveUserSettings(Map<String, String> userSettings, Set<String> edited) throws CmsRpcException { 1378 1379 try { 1380 CmsObject cms = getCmsObject(); 1381 CmsClientUserSettingConverter converter = new CmsClientUserSettingConverter( 1382 cms, 1383 getRequest(), 1384 getResponse()); 1385 userSettings.keySet().retainAll(edited); 1386 converter.saveSettings(userSettings); 1387 } catch (Exception e) { 1388 error(e); 1389 } 1390 } 1391 1392 /** 1393 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#setResourceCategories(org.opencms.util.CmsUUID, java.util.List) 1394 */ 1395 public void setResourceCategories(CmsUUID structureId, List<String> categories) throws CmsRpcException { 1396 1397 CmsObject cms = getCmsObject(); 1398 CmsCategoryService catService = CmsCategoryService.getInstance(); 1399 try { 1400 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1401 ensureLock(resource); 1402 String sitePath = cms.getSitePath(resource); 1403 List<CmsCategory> previousCategories = catService.readResourceCategories(cms, resource); 1404 for (CmsCategory category : previousCategories) { 1405 if (categories.contains(category.getPath())) { 1406 categories.remove(category.getPath()); 1407 } else { 1408 catService.removeResourceFromCategory(cms, sitePath, category); 1409 } 1410 } 1411 for (String path : categories) { 1412 if (!path.isEmpty()) { // Prevent adding category repositories itself. 1413 catService.addResourceToCategory(cms, sitePath, path); 1414 } 1415 } 1416 tryUnlock(resource); 1417 } catch (Throwable t) { 1418 error(t); 1419 } 1420 } 1421 1422 /** 1423 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#setShowEditorHelp(boolean) 1424 */ 1425 public void setShowEditorHelp(boolean visible) throws CmsRpcException { 1426 1427 try { 1428 OpenCms.getADEManager().setShowEditorHelp(getCmsObject(), visible); 1429 } catch (Throwable e) { 1430 error(e); 1431 } 1432 } 1433 1434 /** 1435 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#setToolbarVisible(boolean) 1436 */ 1437 public void setToolbarVisible(boolean visible) throws CmsRpcException { 1438 1439 try { 1440 ensureSession(); 1441 CmsADESessionCache.getCache(getRequest(), getCmsObject()).setToolbarVisible(visible); 1442 } catch (Throwable e) { 1443 error(e); 1444 } 1445 } 1446 1447 /** 1448 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#unlock(org.opencms.util.CmsUUID) 1449 */ 1450 public String unlock(CmsUUID structureId) throws CmsRpcException { 1451 1452 CmsObject cms = getCmsObject(); 1453 try { 1454 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1455 tryUnlock(resource); 1456 } catch (CmsException e) { 1457 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1458 } catch (Throwable e) { 1459 error(e); 1460 } 1461 return null; 1462 } 1463 1464 /** 1465 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#unlock(java.lang.String) 1466 */ 1467 public String unlock(String sitePath) throws CmsRpcException { 1468 1469 try { 1470 CmsObject cms = OpenCms.initCmsObject(getCmsObject()); 1471 cms.getRequestContext().setSiteRoot(""); 1472 if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) { 1473 CmsResource resource = cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION); 1474 tryUnlock(resource); 1475 } 1476 } catch (CmsException e) { 1477 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject())); 1478 } catch (Throwable e) { 1479 error(e); 1480 } 1481 return null; 1482 } 1483 1484 /** 1485 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#validate(java.util.Map) 1486 */ 1487 public Map<String, CmsValidationResult> validate(Map<String, CmsValidationQuery> validationQueries) 1488 throws CmsRpcException { 1489 1490 try { 1491 Map<String, CmsValidationResult> result = new HashMap<String, CmsValidationResult>(); 1492 for (Map.Entry<String, CmsValidationQuery> queryEntry : validationQueries.entrySet()) { 1493 String fieldName = queryEntry.getKey(); 1494 CmsValidationQuery query = queryEntry.getValue(); 1495 result.put(fieldName, validate(query.getValidatorId(), query.getValue(), query.getConfig())); 1496 } 1497 return result; 1498 } catch (Throwable e) { 1499 error(e); 1500 } 1501 return null; 1502 } 1503 1504 /** 1505 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#validate(java.lang.String, java.util.Map, java.util.Map, java.lang.String) 1506 */ 1507 public Map<String, CmsValidationResult> validate( 1508 String formValidatorClass, 1509 Map<String, CmsValidationQuery> validationQueries, 1510 Map<String, String> values, 1511 String config) 1512 throws CmsRpcException { 1513 1514 try { 1515 I_CmsFormValidator formValidator = instantiate(I_CmsFormValidator.class, formValidatorClass); 1516 return formValidator.validate(getCmsObject(), validationQueries, values, config); 1517 } catch (Throwable e) { 1518 error(e); 1519 } 1520 return null; 1521 } 1522 1523 /** 1524 * Collect GWT build ids from the different ADE modules.<p> 1525 * 1526 * @return the map of GWT build ids 1527 */ 1528 protected Map<String, String> getBuildIds() { 1529 1530 List<CmsModule> modules = OpenCms.getModuleManager().getAllInstalledModules(); 1531 Map<String, String> result = new HashMap<String, String>(); 1532 for (CmsModule module : modules) { 1533 String buildid = module.getParameter(CmsCoreData.KEY_GWT_BUILDID); 1534 if (buildid != null) { 1535 result.put(module.getName(), buildid); 1536 } 1537 } 1538 return result; 1539 } 1540 1541 /** 1542 * Helper method for locking a resource which returns some information on whether the locking 1543 * failed, and why.<p> 1544 * 1545 * @param structureId the structure id of the resource 1546 * @return the locking information 1547 * 1548 * @throws CmsException if something went wrong 1549 */ 1550 protected CmsLockInfo getLock(CmsUUID structureId) throws CmsException { 1551 1552 CmsResource res = getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1553 return getLock(getCmsObject().getSitePath(res)); 1554 } 1555 1556 /** 1557 * Helper method for locking a resource which returns some information on whether the locking 1558 * failed, and why.<p> 1559 * 1560 * @param sitepath the site path of the resource to lock 1561 * @return the locking information 1562 * 1563 * @throws CmsException if something went wrong 1564 */ 1565 protected CmsLockInfo getLock(String sitepath) throws CmsException { 1566 1567 CmsObject cms = getCmsObject(); 1568 CmsUser user = cms.getRequestContext().getCurrentUser(); 1569 CmsLock lock = cms.getLock(sitepath); 1570 if (lock.isOwnedBy(user)) { 1571 return CmsLockInfo.forSuccess(); 1572 } 1573 if (lock.getUserId().isNullUUID()) { 1574 cms.lockResourceTemporary(sitepath); 1575 return CmsLockInfo.forSuccess(); 1576 } 1577 CmsUser owner = cms.readUser(lock.getUserId()); 1578 return CmsLockInfo.forLockedResource(owner.getName()); 1579 } 1580 1581 /** 1582 * Helper method for reading and filtering categories. 1583 * 1584 * @param fromCatPath the category path to start with, can be <code>null</code> or empty to use the root 1585 * @param includeSubCats if to include all categories, or first level child categories only 1586 * @param refVfsPath the reference path (site-relative path according to which the available category repositories are determined), can be <code>null</code> to only use the system repository 1587 * @param withRepositories flag, indicating if also the category repositories should be returned as category 1588 * @param selectedCheck a predicate that checks for categories whose ancestors should be included even if they are marked as hidden 1589 * 1590 * @return the resource categories 1591 * 1592 * @throws CmsRpcException if something goes wrong 1593 1594 * 1595 * @return 1596 * @throws CmsRpcException 1597 */ 1598 private List<CmsCategoryTreeEntry> getCategoriesInternal( 1599 String fromPath, 1600 boolean includeSubCats, 1601 String refPath, 1602 boolean showWithRepositories, 1603 Predicate<CmsCategoryTreeEntry> selectedCheck) 1604 throws CmsRpcException { 1605 1606 CmsObject cms = getCmsObject(); 1607 CmsCategoryService catService = CmsCategoryService.getInstance(); 1608 1609 List<String> repositories = new ArrayList<String>(); 1610 repositories.addAll(catService.getCategoryRepositories(getCmsObject(), refPath)); 1611 1612 List<CmsCategoryTreeEntry> result = null; 1613 try { 1614 // get the categories 1615 List<CmsCategory> categories = catService.readCategoriesForRepositories( 1616 cms, 1617 fromPath, 1618 includeSubCats, 1619 repositories, 1620 showWithRepositories); 1621 categories = catService.localizeCategories( 1622 cms, 1623 categories, 1624 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1625 result = buildCategoryTree(cms, categories); 1626 removeHiddenCategories(cms, result, selectedCheck); 1627 1628 } catch (Throwable e) { 1629 error(e); 1630 } 1631 return result; 1632 } 1633 1634 /** 1635 * Returns the workplace settings of the current user.<p> 1636 * 1637 * @return the workplace settings 1638 */ 1639 private CmsWorkplaceSettings getWorkplaceSettings() { 1640 1641 if (m_workplaceSettings == null) { 1642 m_workplaceSettings = CmsWorkplace.getWorkplaceSettings(getCmsObject(), getRequest()); 1643 } 1644 return m_workplaceSettings; 1645 } 1646 1647 /** 1648 * Internal helper method for validating a single value.<p> 1649 * 1650 * @param validator the class name of the validation service 1651 * @param value the value to validate 1652 * @param config the configuration for the validation service 1653 * 1654 * @return the result of the validation 1655 * 1656 * @throws Exception if something goes wrong 1657 */ 1658 private CmsValidationResult validate(String validator, String value, String config) throws Exception { 1659 1660 I_CmsValidationService validationService = getValidationService(validator); 1661 return validationService.validate(getCmsObject(), value, config); 1662 } 1663}