001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt; 029 030import org.opencms.ade.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 Set<CmsBroadcast> repeatedBroadcasts = new HashSet<CmsBroadcast>(); 812 OpenCms.getWorkplaceManager().checkWorkplaceRequest(getRequest(), getCmsObject()); 813 CmsSessionInfo sessionInfo = OpenCms.getSessionManager().getSessionInfo(getRequest().getSession()); 814 if (sessionInfo == null) { 815 return null; 816 } 817 String sessionId = sessionInfo.getSessionId().toString(); 818 Buffer messageQueue = OpenCms.getSessionManager().getBroadcastQueue(sessionId); 819 if (!messageQueue.isEmpty()) { 820 CmsMessages messages = org.opencms.workplace.Messages.get().getBundle( 821 OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject())); 822 List<CmsBroadcastMessage> result = new ArrayList<CmsBroadcastMessage>(); 823 // the user has pending messages, display them all 824 while (!messageQueue.isEmpty()) { 825 826 CmsBroadcast broadcastMessage = (CmsBroadcast)messageQueue.remove(); 827 if ((broadcastMessage.getLastDisplay() 828 + CmsBroadcast.DISPLAY_AGAIN_TIME) < System.currentTimeMillis()) { 829 CmsUserIconHelper helper = OpenCms.getWorkplaceAppManager().getUserIconHelper(); 830 String picPath = ""; 831 if (broadcastMessage.getUser() != null) { 832 picPath = helper.getSmallIconPath(getCmsObject(), broadcastMessage.getUser()); 833 } 834 CmsBroadcastMessage message = new CmsBroadcastMessage( 835 broadcastMessage.getUser() != null 836 ? broadcastMessage.getUser().getName() 837 : messages.key(org.opencms.workplace.Messages.GUI_LABEL_BROADCAST_FROM_SYSTEM_0), 838 picPath, 839 messages.getDateTime(broadcastMessage.getSendTime()), 840 broadcastMessage.getMessage()); 841 result.add(message); 842 if (broadcastMessage.isRepeat()) { 843 repeatedBroadcasts.add(broadcastMessage.withLastDisplay(System.currentTimeMillis())); 844 } 845 } else { 846 repeatedBroadcasts.add(broadcastMessage); 847 } 848 } 849 if (!repeatedBroadcasts.isEmpty()) { 850 for (CmsBroadcast broadcast : repeatedBroadcasts) { 851 messageQueue.add(broadcast); 852 } 853 } 854 return result; 855 } 856 // no message pending, return null 857 return null; 858 } 859 860 /** 861 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategories(java.lang.String, boolean, java.lang.String, boolean) 862 */ 863 public List<CmsCategoryTreeEntry> getCategories( 864 String fromPath, 865 boolean includeSubCats, 866 String refPath, 867 boolean showWithRepositories, 868 Set<String> selected) 869 throws CmsRpcException { 870 871 CmsObject cms = getCmsObject(); 872 Set<CmsUUID> selectedIds = new HashSet<>(); 873 for (String path : selected) { 874 try { 875 CmsResource catResource = cms.readResource(path, CmsResourceFilter.IGNORE_EXPIRATION); 876 selectedIds.add(catResource.getStructureId()); 877 } catch (CmsVfsResourceNotFoundException | CmsSecurityException e) { 878 LOG.debug(e.getLocalizedMessage(), e); 879 } catch (Exception e) { 880 LOG.error(e.getLocalizedMessage(), e); 881 } 882 883 } 884 return getCategoriesInternal( 885 fromPath, 886 includeSubCats, 887 refPath, 888 showWithRepositories, 889 entry -> selectedIds.contains(entry.getId())); 890 } 891 892 /** 893 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategoriesForSitePath(java.lang.String) 894 */ 895 public List<CmsCategoryTreeEntry> getCategoriesForSitePath(String sitePath) throws CmsRpcException { 896 897 List<CmsCategoryTreeEntry> result = null; 898 CmsObject cms = getCmsObject(); 899 try { 900 result = getCategoriesForSitePathStatic(cms, sitePath); 901 } catch (Throwable e) { 902 error(e); 903 } 904 return result; 905 } 906 907 /** 908 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getCategoryInfo(org.opencms.util.CmsUUID) 909 */ 910 public CmsResourceCategoryInfo getCategoryInfo(CmsUUID structureId) throws CmsRpcException { 911 912 CmsObject cms = getCmsObject(); 913 CmsCategoryService catService = CmsCategoryService.getInstance(); 914 try { 915 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.ignoreExpirationOffline(cms)); 916 List<CmsCategory> categories = catService.readResourceCategories(cms, resource); 917 List<String> currentCategories = new ArrayList<String>(); 918 Set<CmsUUID> selected = new HashSet<>(); 919 920 for (CmsCategory category : categories) { 921 currentCategories.add(category.getPath()); 922 selected.add(category.getId()); 923 } 924 return new CmsResourceCategoryInfo( 925 structureId, 926 CmsVfsService.getPageInfoWithLock(cms, resource), 927 currentCategories, 928 getCategoriesInternal( 929 null, 930 true, 931 cms.getSitePath(resource), 932 OpenCms.getWorkplaceManager().isDisplayCategoriesByRepository(), 933 entry -> selected.contains(entry.getId()))); 934 } catch (CmsException e) { 935 error(e); 936 } 937 return null; 938 } 939 940 /** 941 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getContextMenuEntries(org.opencms.util.CmsUUID, org.opencms.gwt.shared.CmsCoreData.AdeContext) 942 */ 943 public List<CmsContextMenuEntryBean> getContextMenuEntries(CmsUUID structureId, AdeContext context) 944 throws CmsRpcException { 945 946 List<CmsContextMenuEntryBean> result = null; 947 try { 948 result = getContextMenuEntries(getCmsObject(), structureId, context, new HashMap<>()); 949 } catch (Throwable e) { 950 error(e); 951 } 952 return result; 953 } 954 955 /** 956 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getContextMenuEntries(org.opencms.util.CmsUUID, org.opencms.gwt.shared.CmsCoreData.AdeContext) 957 */ 958 public List<CmsContextMenuEntryBean> getContextMenuEntries( 959 CmsUUID structureId, 960 AdeContext context, 961 Map<String, String> params) 962 throws CmsRpcException { 963 964 List<CmsContextMenuEntryBean> result = null; 965 try { 966 result = getContextMenuEntries(getCmsObject(), structureId, context, params); 967 } catch (Throwable e) { 968 error(e); 969 } 970 return result; 971 } 972 973 /** 974 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getLinkForReturnCode(java.lang.String) 975 */ 976 public CmsReturnLinkInfo getLinkForReturnCode(String returnCode) throws CmsRpcException { 977 978 try { 979 return internalGetLinkForReturnCode(getCmsObject(), returnCode); 980 } catch (Throwable e) { 981 error(e); 982 return null; 983 984 } 985 } 986 987 /** 988 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getResourceState(org.opencms.util.CmsUUID) 989 */ 990 public CmsResourceState getResourceState(CmsUUID structureId) throws CmsRpcException { 991 992 CmsObject cms = getCmsObject(); 993 CmsResourceState result = null; 994 try { 995 try { 996 CmsResource res = cms.readResource(structureId, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 997 result = res.getState(); 998 } catch (CmsVfsResourceNotFoundException e) { 999 LOG.debug(e.getLocalizedMessage(), e); 1000 result = CmsResourceState.STATE_DELETED; 1001 } 1002 } catch (CmsException e) { 1003 error(e); 1004 } 1005 return result; 1006 } 1007 1008 /** 1009 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getUniqueFileName(java.lang.String, java.lang.String) 1010 */ 1011 public String getUniqueFileName(String parentFolder, String baseName) { 1012 1013 return OpenCms.getResourceManager().getNameGenerator().getUniqueFileName( 1014 getCmsObject(), 1015 parentFolder, 1016 baseName); 1017 } 1018 1019 /** 1020 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getUserInfo() 1021 */ 1022 public UserInfo getUserInfo() { 1023 1024 CmsObject cms = getCmsObject(); 1025 CmsRoleManager roleManager = OpenCms.getRoleManager(); 1026 boolean isAdmin = roleManager.hasRole(cms, CmsRole.ADMINISTRATOR); 1027 boolean isDeveloper = roleManager.hasRole(cms, CmsRole.DEVELOPER); 1028 boolean isCategoryManager = roleManager.hasRole(cms, CmsRole.CATEGORY_EDITOR); 1029 boolean isWorkplaceUser = roleManager.hasRole(cms, CmsRole.WORKPLACE_USER); 1030 UserInfo userInfo = new UserInfo( 1031 cms.getRequestContext().getCurrentUser().getName(), 1032 OpenCms.getWorkplaceAppManager().getUserIconHelper().getSmallIconPath( 1033 cms, 1034 cms.getRequestContext().getCurrentUser()), 1035 isAdmin, 1036 isDeveloper, 1037 isCategoryManager, 1038 isWorkplaceUser, 1039 cms.getRequestContext().getCurrentUser().isManaged()); 1040 return userInfo; 1041 } 1042 1043 /** 1044 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getWorkplaceLink(org.opencms.util.CmsUUID) 1045 */ 1046 public String getWorkplaceLink(CmsUUID structureId) throws CmsRpcException { 1047 1048 String result = null; 1049 CmsObject cms = getCmsObject(); 1050 try { 1051 String resourceRootFolder = structureId != null 1052 ? CmsResource.getFolderPath( 1053 cms.readResource(structureId, CmsResourceFilter.ALL.addRequireVisible()).getRootPath()) 1054 : cms.getRequestContext().getSiteRoot(); 1055 result = getVaadinWorkplaceLink(cms, resourceRootFolder); 1056 } catch (Exception e) { 1057 error(e); 1058 } 1059 return result; 1060 } 1061 1062 /** 1063 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#getWorkplaceLinkForPath(java.lang.String) 1064 */ 1065 public String getWorkplaceLinkForPath(String path) throws CmsRpcException { 1066 1067 CmsObject cms = getCmsObject(); 1068 try { 1069 CmsObject workCms = cms; 1070 if (path.startsWith("/sites/")) { 1071 workCms = OpenCms.initCmsObject(cms); 1072 workCms.getRequestContext().setSiteRoot(""); 1073 } 1074 String currentPath = CmsResource.getParentFolder(path); 1075 CmsResource folder = null; 1076 try { 1077 folder = workCms.readResource(currentPath, CmsResourceFilter.IGNORE_EXPIRATION.addRequireVisible()); 1078 } catch (CmsVfsResourceNotFoundException | CmsSecurityException e) { 1079 throw new CmsException(Messages.get().container(Messages.ERR_COULD_NOT_FIND_PARENT_FOLDER_1, path), e); 1080 } 1081 return getVaadinWorkplaceLink(cms, folder.getRootPath()); 1082 } catch (Exception e) { 1083 error(e); 1084 return null; 1085 } 1086 } 1087 1088 /** 1089 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#loadUserSettings() 1090 */ 1091 public CmsUserSettingsBean loadUserSettings() throws CmsRpcException { 1092 1093 CmsObject cms = getCmsObject(); 1094 CmsClientUserSettingConverter converter = new CmsClientUserSettingConverter(cms, getRequest(), getResponse()); 1095 try { 1096 return converter.loadSettings(); 1097 } catch (Exception e) { 1098 error(e); 1099 return null; 1100 } 1101 } 1102 1103 /** 1104 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockIfExists(java.lang.String) 1105 */ 1106 public String lockIfExists(String sitePath) throws CmsRpcException { 1107 1108 CmsObject cms = getCmsObject(); 1109 String errorMessage = null; 1110 try { 1111 if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) { 1112 1113 try { 1114 ensureLock(cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)); 1115 } catch (CmsException e) { 1116 errorMessage = e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1117 } 1118 1119 } else { 1120 // check if parent folder may be locked by the current user 1121 String parentFolder = CmsResource.getParentFolder(sitePath); 1122 while ((parentFolder != null) 1123 && !cms.existsResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION)) { 1124 parentFolder = CmsResource.getParentFolder(parentFolder); 1125 } 1126 if (parentFolder != null) { 1127 CmsResource ancestorFolder = cms.readResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION); 1128 CmsUser user = cms.getRequestContext().getCurrentUser(); 1129 CmsLock lock = cms.getLock(ancestorFolder); 1130 if (!lock.isLockableBy(user)) { 1131 errorMessage = "Can not lock parent folder '" + parentFolder + "'."; 1132 } 1133 } else { 1134 errorMessage = "Can not access any parent folder."; 1135 } 1136 } 1137 } catch (Throwable e) { 1138 error(e); 1139 } 1140 1141 return errorMessage; 1142 } 1143 1144 /** 1145 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockIfExists(java.lang.String, long) 1146 */ 1147 public String lockIfExists(String sitePath, long loadTime) throws CmsRpcException { 1148 1149 CmsObject cms = getCmsObject(); 1150 String errorMessage = null; 1151 try { 1152 if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) { 1153 1154 try { 1155 CmsResource resource = cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION); 1156 if (resource.getDateLastModified() > loadTime) { 1157 // the resource has been changed since it was loaded 1158 CmsUser user = null; 1159 try { 1160 user = cms.readUser(resource.getUserLastModified()); 1161 } catch (CmsException e) { 1162 // ignore 1163 } 1164 CmsMessages messages = Messages.get().getBundle( 1165 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1166 return user != null 1167 ? messages.key( 1168 Messages.ERR_LOCKING_MODIFIED_RESOURCE_2, 1169 resource.getRootPath(), 1170 user.getFullName()) 1171 : messages.key(Messages.ERR_LOCKING_MODIFIED_RESOURCE_1, resource.getRootPath()); 1172 } 1173 ensureLock(resource); 1174 } catch (CmsException e) { 1175 errorMessage = e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1176 } 1177 1178 } else { 1179 // check if parent folder may be locked by the current user 1180 String parentFolder = CmsResource.getParentFolder(sitePath); 1181 while ((parentFolder != null) 1182 && !cms.existsResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION)) { 1183 parentFolder = CmsResource.getParentFolder(parentFolder); 1184 } 1185 if (parentFolder != null) { 1186 CmsResource ancestorFolder = cms.readResource(parentFolder, CmsResourceFilter.IGNORE_EXPIRATION); 1187 CmsUser user = cms.getRequestContext().getCurrentUser(); 1188 CmsLock lock = cms.getLock(ancestorFolder); 1189 if (!lock.isLockableBy(user)) { 1190 errorMessage = "Can not lock parent folder '" + parentFolder + "'."; 1191 } 1192 } else { 1193 errorMessage = "Can not access any parent folder."; 1194 } 1195 } 1196 } catch (Throwable e) { 1197 error(e); 1198 } 1199 1200 return errorMessage; 1201 } 1202 1203 /** 1204 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockTemp(org.opencms.util.CmsUUID) 1205 */ 1206 public String lockTemp(CmsUUID structureId) throws CmsRpcException { 1207 1208 CmsObject cms = getCmsObject(); 1209 try { 1210 try { 1211 ensureLock(structureId); 1212 } catch (CmsException e) { 1213 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1214 } 1215 } catch (Throwable e) { 1216 error(e); 1217 } 1218 return null; 1219 } 1220 1221 /** 1222 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#lockTemp(org.opencms.util.CmsUUID, long) 1223 */ 1224 public String lockTemp(CmsUUID structureId, long loadTime) throws CmsRpcException { 1225 1226 CmsObject cms = getCmsObject(); 1227 try { 1228 try { 1229 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1230 if (resource.getDateLastModified() > loadTime) { 1231 // the resource has been changed since it was loaded 1232 CmsUser user = null; 1233 try { 1234 user = cms.readUser(resource.getUserLastModified()); 1235 } catch (CmsException e) { 1236 // ignore 1237 } 1238 CmsMessages messages = Messages.get().getBundle( 1239 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1240 return user != null 1241 ? messages.key(Messages.ERR_LOCKING_MODIFIED_RESOURCE_2, resource.getRootPath(), user.getFullName()) 1242 : messages.key(Messages.ERR_LOCKING_MODIFIED_RESOURCE_1, resource.getRootPath()); 1243 } 1244 ensureLock(resource); 1245 } catch (CmsException e) { 1246 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1247 } 1248 } catch (Throwable e) { 1249 error(e); 1250 } 1251 return null; 1252 } 1253 1254 /** 1255 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#prefetch() 1256 */ 1257 public CmsCoreData prefetch() { 1258 1259 CmsObject cms = getCmsObject(); 1260 String navigationUri = cms.getRequestContext().getUri(); 1261 CmsADEConfigData sitemapConfig = OpenCms.getADEManager().lookupConfigurationWithCache( 1262 cms, 1263 cms.getRequestContext().getRootUri()); 1264 boolean toolbarVisible = CmsADESessionCache.getCache(getRequest(), getCmsObject()).isToolbarVisible(); 1265 boolean isShowHelp = OpenCms.getADEManager().isShowEditorHelp(cms); 1266 1267 CmsUUID structureId = null; 1268 1269 try { 1270 CmsResource requestedResource = cms.readResource( 1271 cms.getRequestContext().getUri(), 1272 CmsResourceFilter.ignoreExpirationOffline(cms)); 1273 structureId = requestedResource.getStructureId(); 1274 } catch (CmsException e) { 1275 // may happen in case of VAADIN UI 1276 LOG.debug("Could not read resource for URI.", e); 1277 structureId = CmsUUID.getNullUUID(); 1278 } 1279 String loginUrl = CmsWorkplaceLoginHandler.LOGIN_FORM; 1280 try { 1281 loginUrl = cms.readPropertyObject( 1282 cms.getRequestContext().getUri(), 1283 CmsPropertyDefinition.PROPERTY_LOGIN_FORM, 1284 true).getValue(loginUrl); 1285 } catch (CmsException e) { 1286 log(e.getLocalizedMessage(), e); 1287 } 1288 String defaultWorkplaceLink = OpenCms.getSystemInfo().getWorkplaceContext(); 1289 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1290 UserInfo userInfo = getUserInfo(); 1291 String aboutLink = OpenCms.getLinkManager().substituteLink( 1292 getCmsObject(), 1293 "/system/workplace/commons/about.jsp"); 1294 String tinyMCE = CmsWorkplace.getStaticResourceUri("/editors/tinymce/jscripts/tinymce/tinymce.min.js"); 1295 boolean uploadDisabled = OpenCms.getWorkplaceManager().isAdeGalleryUploadDisabled(cms); 1296 CmsUploadRestrictionInfo uploadRestrictionInfo = OpenCms.getWorkplaceManager().getUploadRestriction().getUploadRestrictionInfo( 1297 cms); 1298 String categoryBaseFolder = CmsCategoryService.getInstance().getRepositoryBaseFolderName(cms); 1299 CmsGalleryDisabledTypesMode disabledTypesMode = sitemapConfig.getDisabledTypeMode( 1300 CmsGalleryDisabledTypesMode.mark); 1301 boolean hideDisabledTypes = disabledTypesMode == CmsGalleryDisabledTypesMode.hide; 1302 getWorkplaceSettings().getUserSettings(); 1303 String checkReuseWarning = CmsUserSettings.getAdditionalPreference(cms, "checkReuseWarning", true); 1304 boolean warnWhenEditingReusedElement = Boolean.parseBoolean(checkReuseWarning); 1305 1306 CmsCoreData data = new CmsCoreData( 1307 EDITOR_URI, 1308 EDITOR_BACKLINK_URI, 1309 loginUrl, 1310 OpenCms.getStaticExportManager().getVfsPrefix(), 1311 getFileExplorerLink(cms, cms.getRequestContext().getSiteRoot()), 1312 OpenCms.getSystemInfo().getStaticResourceContext(), 1313 CmsEmbeddedDialogsUI.getEmbeddedDialogsContextPath(), 1314 cms.getRequestContext().getSiteRoot(), 1315 OpenCms.getSiteManager().getSharedFolder(), 1316 cms.getRequestContext().getCurrentProject().getId(), 1317 cms.getRequestContext().getLocale().toString(), 1318 wpLocale.toString(), 1319 cms.getRequestContext().getUri(), 1320 navigationUri, 1321 structureId, 1322 new HashMap<String, String>(OpenCms.getResourceManager().getExtensionMapping()), 1323 CmsIconUtil.getExtensionIconMapping(), 1324 System.currentTimeMillis(), 1325 isShowHelp, 1326 toolbarVisible, 1327 defaultWorkplaceLink, 1328 aboutLink, 1329 userInfo, 1330 OpenCms.getWorkplaceManager().getFileBytesMaxUploadSize(getCmsObject()), 1331 OpenCms.getWorkplaceManager().isKeepAlive(), 1332 uploadDisabled, 1333 OpenCms.getADEManager().getParameters(getCmsObject()), 1334 uploadRestrictionInfo, 1335 categoryBaseFolder, 1336 hideDisabledTypes, 1337 warnWhenEditingReusedElement); 1338 CmsTinyMCEData tinyMCEData = new CmsTinyMCEData(); 1339 tinyMCEData.setLink(tinyMCE); 1340 data.setTinymce(tinyMCEData); 1341 data.setMaxLocaleButtons(OpenCms.getWorkplaceManager().getEditorMaxLocaleButtons()); 1342 return data; 1343 } 1344 1345 /** 1346 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#saveUsedCategory(java.lang.String) 1347 */ 1348 @Override 1349 public void saveUsedCategory(String category) throws CmsRpcException { 1350 1351 try { 1352 CmsObject cms = getCmsObject(); 1353 CmsUsedCategoriesList.addUsedCategoryForCurrentUser(cms, category); 1354 } catch (Exception e) { 1355 LOG.error(e.getLocalizedMessage(), e); 1356 error(e); 1357 } 1358 } 1359 1360 /** 1361 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#saveUserSettings(java.util.Map, java.util.Set) 1362 */ 1363 public void saveUserSettings(Map<String, String> userSettings, Set<String> edited) throws CmsRpcException { 1364 1365 try { 1366 CmsObject cms = getCmsObject(); 1367 CmsClientUserSettingConverter converter = new CmsClientUserSettingConverter( 1368 cms, 1369 getRequest(), 1370 getResponse()); 1371 userSettings.keySet().retainAll(edited); 1372 converter.saveSettings(userSettings); 1373 } catch (Exception e) { 1374 error(e); 1375 } 1376 } 1377 1378 /** 1379 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#setResourceCategories(org.opencms.util.CmsUUID, java.util.List) 1380 */ 1381 public void setResourceCategories(CmsUUID structureId, List<String> categories) throws CmsRpcException { 1382 1383 CmsObject cms = getCmsObject(); 1384 CmsCategoryService catService = CmsCategoryService.getInstance(); 1385 try { 1386 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1387 ensureLock(resource); 1388 String sitePath = cms.getSitePath(resource); 1389 List<CmsCategory> previousCategories = catService.readResourceCategories(cms, resource); 1390 for (CmsCategory category : previousCategories) { 1391 if (categories.contains(category.getPath())) { 1392 categories.remove(category.getPath()); 1393 } else { 1394 catService.removeResourceFromCategory(cms, sitePath, category); 1395 } 1396 } 1397 for (String path : categories) { 1398 if (!path.isEmpty()) { // Prevent adding category repositories itself. 1399 catService.addResourceToCategory(cms, sitePath, path); 1400 } 1401 } 1402 tryUnlock(resource); 1403 } catch (Throwable t) { 1404 error(t); 1405 } 1406 } 1407 1408 /** 1409 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#setShowEditorHelp(boolean) 1410 */ 1411 public void setShowEditorHelp(boolean visible) throws CmsRpcException { 1412 1413 try { 1414 OpenCms.getADEManager().setShowEditorHelp(getCmsObject(), visible); 1415 } catch (Throwable e) { 1416 error(e); 1417 } 1418 } 1419 1420 /** 1421 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#setToolbarVisible(boolean) 1422 */ 1423 public void setToolbarVisible(boolean visible) throws CmsRpcException { 1424 1425 try { 1426 ensureSession(); 1427 CmsADESessionCache.getCache(getRequest(), getCmsObject()).setToolbarVisible(visible); 1428 } catch (Throwable e) { 1429 error(e); 1430 } 1431 } 1432 1433 /** 1434 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#unlock(org.opencms.util.CmsUUID) 1435 */ 1436 public String unlock(CmsUUID structureId) throws CmsRpcException { 1437 1438 CmsObject cms = getCmsObject(); 1439 try { 1440 CmsResource resource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1441 tryUnlock(resource); 1442 } catch (CmsException e) { 1443 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1444 } catch (Throwable e) { 1445 error(e); 1446 } 1447 return null; 1448 } 1449 1450 /** 1451 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#unlock(java.lang.String) 1452 */ 1453 public String unlock(String sitePath) throws CmsRpcException { 1454 1455 try { 1456 CmsObject cms = OpenCms.initCmsObject(getCmsObject()); 1457 cms.getRequestContext().setSiteRoot(""); 1458 if (cms.existsResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION)) { 1459 CmsResource resource = cms.readResource(sitePath, CmsResourceFilter.IGNORE_EXPIRATION); 1460 tryUnlock(resource); 1461 } 1462 } catch (CmsException e) { 1463 return e.getLocalizedMessage(OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject())); 1464 } catch (Throwable e) { 1465 error(e); 1466 } 1467 return null; 1468 } 1469 1470 /** 1471 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#validate(java.util.Map) 1472 */ 1473 public Map<String, CmsValidationResult> validate(Map<String, CmsValidationQuery> validationQueries) 1474 throws CmsRpcException { 1475 1476 try { 1477 Map<String, CmsValidationResult> result = new HashMap<String, CmsValidationResult>(); 1478 for (Map.Entry<String, CmsValidationQuery> queryEntry : validationQueries.entrySet()) { 1479 String fieldName = queryEntry.getKey(); 1480 CmsValidationQuery query = queryEntry.getValue(); 1481 result.put(fieldName, validate(query.getValidatorId(), query.getValue(), query.getConfig())); 1482 } 1483 return result; 1484 } catch (Throwable e) { 1485 error(e); 1486 } 1487 return null; 1488 } 1489 1490 /** 1491 * @see org.opencms.gwt.shared.rpc.I_CmsCoreService#validate(java.lang.String, java.util.Map, java.util.Map, java.lang.String) 1492 */ 1493 public Map<String, CmsValidationResult> validate( 1494 String formValidatorClass, 1495 Map<String, CmsValidationQuery> validationQueries, 1496 Map<String, String> values, 1497 String config) 1498 throws CmsRpcException { 1499 1500 try { 1501 I_CmsFormValidator formValidator = instantiate(I_CmsFormValidator.class, formValidatorClass); 1502 return formValidator.validate(getCmsObject(), validationQueries, values, config); 1503 } catch (Throwable e) { 1504 error(e); 1505 } 1506 return null; 1507 } 1508 1509 /** 1510 * Collect GWT build ids from the different ADE modules.<p> 1511 * 1512 * @return the map of GWT build ids 1513 */ 1514 protected Map<String, String> getBuildIds() { 1515 1516 List<CmsModule> modules = OpenCms.getModuleManager().getAllInstalledModules(); 1517 Map<String, String> result = new HashMap<String, String>(); 1518 for (CmsModule module : modules) { 1519 String buildid = module.getParameter(CmsCoreData.KEY_GWT_BUILDID); 1520 if (buildid != null) { 1521 result.put(module.getName(), buildid); 1522 } 1523 } 1524 return result; 1525 } 1526 1527 /** 1528 * Helper method for locking a resource which returns some information on whether the locking 1529 * failed, and why.<p> 1530 * 1531 * @param structureId the structure id of the resource 1532 * @return the locking information 1533 * 1534 * @throws CmsException if something went wrong 1535 */ 1536 protected CmsLockInfo getLock(CmsUUID structureId) throws CmsException { 1537 1538 CmsResource res = getCmsObject().readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1539 return getLock(getCmsObject().getSitePath(res)); 1540 } 1541 1542 /** 1543 * Helper method for locking a resource which returns some information on whether the locking 1544 * failed, and why.<p> 1545 * 1546 * @param sitepath the site path of the resource to lock 1547 * @return the locking information 1548 * 1549 * @throws CmsException if something went wrong 1550 */ 1551 protected CmsLockInfo getLock(String sitepath) throws CmsException { 1552 1553 CmsObject cms = getCmsObject(); 1554 CmsUser user = cms.getRequestContext().getCurrentUser(); 1555 CmsLock lock = cms.getLock(sitepath); 1556 if (lock.isOwnedBy(user)) { 1557 return CmsLockInfo.forSuccess(); 1558 } 1559 if (lock.getUserId().isNullUUID()) { 1560 cms.lockResourceTemporary(sitepath); 1561 return CmsLockInfo.forSuccess(); 1562 } 1563 CmsUser owner = cms.readUser(lock.getUserId()); 1564 return CmsLockInfo.forLockedResource(owner.getName()); 1565 } 1566 1567 /** 1568 * Helper method for reading and filtering categories. 1569 * 1570 * @param fromCatPath the category path to start with, can be <code>null</code> or empty to use the root 1571 * @param includeSubCats if to include all categories, or first level child categories only 1572 * @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 1573 * @param withRepositories flag, indicating if also the category repositories should be returned as category 1574 * @param selectedCheck a predicate that checks for categories whose ancestors should be included even if they are marked as hidden 1575 * 1576 * @return the resource categories 1577 * 1578 * @throws CmsRpcException if something goes wrong 1579 1580 * 1581 * @return 1582 * @throws CmsRpcException 1583 */ 1584 private List<CmsCategoryTreeEntry> getCategoriesInternal( 1585 String fromPath, 1586 boolean includeSubCats, 1587 String refPath, 1588 boolean showWithRepositories, 1589 Predicate<CmsCategoryTreeEntry> selectedCheck) 1590 throws CmsRpcException { 1591 1592 CmsObject cms = getCmsObject(); 1593 CmsCategoryService catService = CmsCategoryService.getInstance(); 1594 1595 List<String> repositories = new ArrayList<String>(); 1596 repositories.addAll(catService.getCategoryRepositories(getCmsObject(), refPath)); 1597 1598 List<CmsCategoryTreeEntry> result = null; 1599 try { 1600 // get the categories 1601 List<CmsCategory> categories = catService.readCategoriesForRepositories( 1602 cms, 1603 fromPath, 1604 includeSubCats, 1605 repositories, 1606 showWithRepositories); 1607 categories = catService.localizeCategories( 1608 cms, 1609 categories, 1610 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); 1611 result = buildCategoryTree(cms, categories); 1612 removeHiddenCategories(cms, result, selectedCheck); 1613 1614 } catch (Throwable e) { 1615 error(e); 1616 } 1617 return result; 1618 } 1619 1620 /** 1621 * Returns the workplace settings of the current user.<p> 1622 * 1623 * @return the workplace settings 1624 */ 1625 private CmsWorkplaceSettings getWorkplaceSettings() { 1626 1627 if (m_workplaceSettings == null) { 1628 m_workplaceSettings = CmsWorkplace.getWorkplaceSettings(getCmsObject(), getRequest()); 1629 } 1630 return m_workplaceSettings; 1631 } 1632 1633 /** 1634 * Internal helper method for validating a single value.<p> 1635 * 1636 * @param validator the class name of the validation service 1637 * @param value the value to validate 1638 * @param config the configuration for the validation service 1639 * 1640 * @return the result of the validation 1641 * 1642 * @throws Exception if something goes wrong 1643 */ 1644 private CmsValidationResult validate(String validator, String value, String config) throws Exception { 1645 1646 I_CmsValidationService validationService = getValidationService(validator); 1647 return validationService.validate(getCmsObject(), value, config); 1648 } 1649}