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.ade.containerpage; 029 030import org.opencms.ade.configuration.CmsADEConfigData; 031import org.opencms.ade.configuration.CmsADEManager; 032import org.opencms.ade.configuration.CmsElementView; 033import org.opencms.ade.configuration.CmsModelPageConfig; 034import org.opencms.ade.configuration.CmsResourceTypeConfig; 035import org.opencms.ade.containerpage.inherited.CmsInheritanceReference; 036import org.opencms.ade.containerpage.inherited.CmsInheritanceReferenceParser; 037import org.opencms.ade.containerpage.inherited.CmsInheritedContainerState; 038import org.opencms.ade.containerpage.shared.CmsCntPageData; 039import org.opencms.ade.containerpage.shared.CmsCntPageData.ElementDeleteMode; 040import org.opencms.ade.containerpage.shared.CmsCntPageData.ElementReuseMode; 041import org.opencms.ade.containerpage.shared.CmsContainer; 042import org.opencms.ade.containerpage.shared.CmsContainerElement; 043import org.opencms.ade.containerpage.shared.CmsContainerElement.ModelGroupState; 044import org.opencms.ade.containerpage.shared.CmsContainerElementData; 045import org.opencms.ade.containerpage.shared.CmsContainerPageGalleryData; 046import org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext; 047import org.opencms.ade.containerpage.shared.CmsCreateElementData; 048import org.opencms.ade.containerpage.shared.CmsDialogOptions; 049import org.opencms.ade.containerpage.shared.CmsDialogOptionsAndInfo; 050import org.opencms.ade.containerpage.shared.CmsElementSettingsConfig; 051import org.opencms.ade.containerpage.shared.CmsElementViewInfo; 052import org.opencms.ade.containerpage.shared.CmsFormatterConfig; 053import org.opencms.ade.containerpage.shared.CmsGroupContainer; 054import org.opencms.ade.containerpage.shared.CmsGroupContainerSaveResult; 055import org.opencms.ade.containerpage.shared.CmsInheritanceContainer; 056import org.opencms.ade.containerpage.shared.CmsInheritanceInfo; 057import org.opencms.ade.containerpage.shared.CmsLocaleLinkBean; 058import org.opencms.ade.containerpage.shared.CmsPageSaveStatus; 059import org.opencms.ade.containerpage.shared.CmsRemovedElementStatus; 060import org.opencms.ade.containerpage.shared.CmsReuseInfo; 061import org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService; 062import org.opencms.ade.detailpage.CmsDetailPageInfo; 063import org.opencms.ade.detailpage.CmsDetailPageResourceHandler; 064import org.opencms.ade.galleries.CmsGalleryService; 065import org.opencms.ade.galleries.shared.CmsGalleryDataBean; 066import org.opencms.ade.galleries.shared.CmsGallerySearchBean; 067import org.opencms.ade.galleries.shared.CmsResourceTypeBean; 068import org.opencms.ade.galleries.shared.CmsVfsEntryBean; 069import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants.GalleryTabId; 070import org.opencms.ade.sitemap.CmsVfsSitemapService; 071import org.opencms.file.CmsFile; 072import org.opencms.file.CmsObject; 073import org.opencms.file.CmsProperty; 074import org.opencms.file.CmsPropertyDefinition; 075import org.opencms.file.CmsResource; 076import org.opencms.file.CmsResourceFilter; 077import org.opencms.file.CmsUser; 078import org.opencms.file.CmsVfsResourceNotFoundException; 079import org.opencms.file.types.CmsResourceTypeBinary; 080import org.opencms.file.types.CmsResourceTypeFunctionConfig; 081import org.opencms.file.types.CmsResourceTypeImage; 082import org.opencms.file.types.CmsResourceTypePlain; 083import org.opencms.file.types.CmsResourceTypeXmlContainerPage; 084import org.opencms.file.types.CmsResourceTypeXmlContent; 085import org.opencms.file.types.I_CmsResourceType; 086import org.opencms.flex.CmsFlexController; 087import org.opencms.gwt.CmsDefaultResourceStatusProvider; 088import org.opencms.gwt.CmsGwtActionElement; 089import org.opencms.gwt.CmsGwtService; 090import org.opencms.gwt.CmsIconUtil; 091import org.opencms.gwt.CmsRpcException; 092import org.opencms.gwt.CmsVfsService; 093import org.opencms.gwt.shared.CmsGwtConstants; 094import org.opencms.gwt.shared.CmsListElementCreationDialogData; 095import org.opencms.gwt.shared.CmsListElementCreationOption; 096import org.opencms.gwt.shared.CmsListInfoBean; 097import org.opencms.gwt.shared.CmsModelResourceInfo; 098import org.opencms.gwt.shared.CmsResourceListInfo; 099import org.opencms.gwt.shared.CmsTemplateContextInfo; 100import org.opencms.gwt.shared.I_CmsAutoBeanFactory; 101import org.opencms.gwt.shared.I_CmsListAddMetadata; 102import org.opencms.gwt.shared.I_CmsUnlockData; 103import org.opencms.i18n.CmsEncoder; 104import org.opencms.i18n.CmsLocaleGroup; 105import org.opencms.i18n.CmsLocaleManager; 106import org.opencms.i18n.CmsMessages; 107import org.opencms.jsp.CmsJspTagEdit; 108import org.opencms.jsp.util.CmsJspStandardContextBean.TemplateBean; 109import org.opencms.loader.CmsTemplateContextManager; 110import org.opencms.loader.I_CmsTemplateContextProvider; 111import org.opencms.lock.CmsLock; 112import org.opencms.lock.CmsLockType; 113import org.opencms.main.CmsException; 114import org.opencms.main.CmsIllegalArgumentException; 115import org.opencms.main.CmsLog; 116import org.opencms.main.OpenCms; 117import org.opencms.module.CmsModule; 118import org.opencms.relations.CmsRelation; 119import org.opencms.relations.CmsRelationFilter; 120import org.opencms.relations.CmsRelationType; 121import org.opencms.search.galleries.CmsGallerySearch; 122import org.opencms.search.galleries.CmsGallerySearchResult; 123import org.opencms.security.CmsPermissionSet; 124import org.opencms.security.CmsPermissionViolationException; 125import org.opencms.security.CmsRole; 126import org.opencms.site.CmsSite; 127import org.opencms.site.CmsSiteManagerImpl; 128import org.opencms.ui.apps.CmsQuickLaunchLocationCache; 129import org.opencms.util.CmsFileUtil; 130import org.opencms.util.CmsPair; 131import org.opencms.util.CmsRequestUtil; 132import org.opencms.util.CmsStringUtil; 133import org.opencms.util.CmsUUID; 134import org.opencms.workplace.CmsWorkplace; 135import org.opencms.workplace.CmsWorkplaceMessages; 136import org.opencms.workplace.CmsWorkplaceSettings; 137import org.opencms.workplace.editors.CmsWorkplaceEditorManager; 138import org.opencms.workplace.editors.directedit.I_CmsEditHandler; 139import org.opencms.workplace.explorer.CmsExplorerTypeSettings; 140import org.opencms.workplace.explorer.CmsResourceUtil; 141import org.opencms.xml.CmsXmlException; 142import org.opencms.xml.containerpage.CmsADESessionCache; 143import org.opencms.xml.containerpage.CmsContainerBean; 144import org.opencms.xml.containerpage.CmsContainerElementBean; 145import org.opencms.xml.containerpage.CmsContainerPageBean; 146import org.opencms.xml.containerpage.CmsFormatterConfiguration; 147import org.opencms.xml.containerpage.CmsGroupContainerBean; 148import org.opencms.xml.containerpage.CmsMacroFormatterBean; 149import org.opencms.xml.containerpage.CmsXmlContainerPage; 150import org.opencms.xml.containerpage.CmsXmlContainerPageFactory; 151import org.opencms.xml.containerpage.CmsXmlGroupContainer; 152import org.opencms.xml.containerpage.CmsXmlGroupContainerFactory; 153import org.opencms.xml.containerpage.I_CmsFormatterBean; 154import org.opencms.xml.content.CmsXmlContent; 155import org.opencms.xml.content.CmsXmlContentFactory; 156import org.opencms.xml.content.CmsXmlContentProperty; 157import org.opencms.xml.content.CmsXmlContentPropertyHelper; 158 159import java.nio.charset.StandardCharsets; 160import java.security.MessageDigest; 161import java.security.NoSuchAlgorithmException; 162import java.util.ArrayList; 163import java.util.Arrays; 164import java.util.Collection; 165import java.util.Collections; 166import java.util.HashMap; 167import java.util.HashSet; 168import java.util.Iterator; 169import java.util.LinkedHashMap; 170import java.util.List; 171import java.util.Locale; 172import java.util.Map; 173import java.util.Map.Entry; 174import java.util.Set; 175import java.util.stream.Collectors; 176 177import javax.servlet.http.HttpServletRequest; 178import javax.servlet.http.HttpServletResponse; 179 180import org.apache.commons.codec.binary.Hex; 181import org.apache.commons.logging.Log; 182 183import com.google.common.base.Optional; 184import com.google.common.collect.Lists; 185import com.google.common.collect.Maps; 186import com.google.common.collect.Sets; 187import com.google.web.bindery.autobean.shared.AutoBean; 188import com.google.web.bindery.autobean.shared.AutoBeanCodex; 189import com.google.web.bindery.autobean.vm.AutoBeanFactorySource; 190 191/** 192 * The RPC service used by the container-page editor.<p> 193 * 194 * @since 8.0.0 195 */ 196public class CmsContainerpageService extends CmsGwtService implements I_CmsContainerpageService { 197 198 /** 199 * Helper class used to determine both the available views and the active start view when loading a container page.<p> 200 */ 201 private class InitialElementViewProvider { 202 203 /** Start view id. */ 204 private CmsUUID m_defaultView; 205 206 /** Map of available views. */ 207 private Map<CmsUUID, CmsElementViewInfo> m_viewMap; 208 209 /** 210 * Empty default constructor.<p> 211 */ 212 public InitialElementViewProvider() { 213 214 // do nothing 215 } 216 217 /** 218 * Returns the default view info.<p> 219 * 220 * @return the default view info 221 */ 222 public CmsElementViewInfo getDefaultView() { 223 224 return getViewMap().get(getDefaultViewId()); 225 } 226 227 /** 228 * Gets the start view id.<p> 229 * 230 * @return the start view id 231 */ 232 public CmsUUID getDefaultViewId() { 233 234 return m_defaultView; 235 } 236 237 /** 238 * Gets the map of available views.<p> 239 * 240 * @return the map of available views 241 */ 242 public Map<CmsUUID, CmsElementViewInfo> getViewMap() { 243 244 return m_viewMap; 245 } 246 247 /** 248 * Initializes this object.<p> 249 * 250 * @param defaultValue the default view id from the session cache 251 * @param checkRes the resource used to check permissions 252 * @param templateContextInfo the template context information 253 */ 254 @SuppressWarnings("synthetic-access") 255 public void init(CmsUUID defaultValue, CmsResource checkRes, CmsTemplateContextInfo templateContextInfo) { 256 257 Map<CmsUUID, CmsElementViewInfo> result = new LinkedHashMap<CmsUUID, CmsElementViewInfo>(); 258 CmsObject cms = getCmsObject(); 259 String templateKey = templateContextInfo != null ? templateContextInfo.getCurrentContext() : null; 260 261 // collect the actually used element view ids 262 CmsADEConfigData config = getConfigData( 263 cms.getRequestContext().addSiteRoot(cms.getRequestContext().getUri())); 264 Set<CmsUUID> usedIds = new HashSet<CmsUUID>(); 265 for (CmsResourceTypeConfig typeConfig : config.getResourceTypes()) { 266 if (typeConfig.isAvailableInTemplate(templateKey)) { 267 usedIds.add(typeConfig.getElementView()); 268 } 269 } 270 271 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 272 Map<CmsUUID, CmsElementView> realViewMap = OpenCms.getADEManager().getElementViews(cms); 273 274 Set<CmsUUID> parentIds = Sets.newHashSet(); 275 for (CmsElementView view : realViewMap.values()) { 276 if (view.getParentViewId() != null) { 277 parentIds.add(view.getParentViewId()); 278 } 279 // add only element view that are used within the type configuration and the user has sufficient permissions for 280 if (usedIds.contains(view.getId()) && view.hasPermission(cms, checkRes) && !view.isOther()) { 281 result.put(view.getId(), new CmsElementViewInfo(view.getTitle(cms, wpLocale), view.getId())); 282 } 283 284 } 285 m_viewMap = result; 286 for (Map.Entry<CmsUUID, CmsElementViewInfo> viewEntry : m_viewMap.entrySet()) { 287 CmsElementView realView = realViewMap.get(viewEntry.getKey()); 288 CmsUUID parentViewId = realView.getParentViewId(); 289 if ((parentViewId != null) && !parentIds.contains(viewEntry.getKey())) { 290 CmsElementViewInfo parentBean = m_viewMap.get(parentViewId); 291 if (parentBean != null) { 292 viewEntry.getValue().setParent(parentBean); 293 } 294 } 295 } 296 if (m_viewMap.containsKey(defaultValue)) { 297 m_defaultView = defaultValue; 298 } else if (m_viewMap.containsKey(CmsElementView.DEFAULT_ELEMENT_VIEW.getId())) { 299 m_defaultView = CmsElementView.DEFAULT_ELEMENT_VIEW.getId(); 300 } else if (!m_viewMap.isEmpty()) { 301 m_defaultView = m_viewMap.values().iterator().next().getElementViewId(); 302 } else { 303 m_defaultView = defaultValue; 304 LOG.error( 305 "Initial view not available and no suitable replacement view found: user=" 306 + getCmsObject().getRequestContext().getCurrentUser().getName() 307 + " view=" 308 + defaultValue 309 + " path=" 310 + checkRes.getRootPath()); 311 } 312 313 } 314 } 315 316 /** Additional info key for storing the "edit small elements" setting on the user. */ 317 public static final String ADDINFO_EDIT_SMALL_ELEMENTS = "EDIT_SMALL_ELEMENTS"; 318 319 /** Session attribute name used to store the selected clipboard tab. */ 320 public static final String ATTR_CLIPBOARD_TAB = "clipboardtab"; 321 322 /** Maximum number of reuse locations to display in the reuse warning dialog. */ 323 public static final int MAX_VISIBLE_ELEMENT_USES = 100; 324 325 /** The model group pages path fragment. */ 326 public static final String MODEL_GROUP_PATH_FRAGMENT = "/.content/.modelgroups/"; 327 328 /** Runtime property key to enable / disable placement mode. */ 329 public static final String PARAM_PAGE_EDITOR_PLACEMENT_MODE_ENABLED = "pageEditor.placementMode.enabled"; 330 331 /** The source container page id settings key. */ 332 public static final String SOURCE_CONTAINERPAGE_ID_SETTING = "source_containerpage_id"; 333 334 /** Static reference to the log. */ 335 static final Log LOG = CmsLog.getLog(CmsContainerpageService.class); 336 337 /** Serial version UID. */ 338 private static final long serialVersionUID = -6188370638303594280L; 339 340 /** The configuration data of the current container page context. */ 341 private CmsADEConfigData m_configData; 342 343 /** The session cache. */ 344 private CmsADESessionCache m_sessionCache; 345 346 /** The workplace settings. */ 347 private CmsWorkplaceSettings m_workplaceSettings; 348 349 /** 350 * Generates the model resource data list.<p> 351 * 352 * @param cms the cms context 353 * @param resourceType the resource type name 354 * @param modelResources the model resource 355 * @param contentLocale the content locale 356 * 357 * @return the model resources data 358 * 359 * @throws CmsException if something goes wrong reading the resource information 360 */ 361 public static List<CmsModelResourceInfo> generateModelResourceList( 362 CmsObject cms, 363 String resourceType, 364 List<CmsResource> modelResources, 365 Locale contentLocale) 366 throws CmsException { 367 368 List<CmsModelResourceInfo> result = new ArrayList<CmsModelResourceInfo>(); 369 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 370 CmsModelResourceInfo defaultInfo = new CmsModelResourceInfo( 371 Messages.get().getBundle(wpLocale).key(Messages.GUI_TITLE_DEFAULT_RESOURCE_CONTENT_0), 372 Messages.get().getBundle(wpLocale).key(Messages.GUI_DESCRIPTION_DEFAULT_RESOURCE_CONTENT_0), 373 null); 374 defaultInfo.setResourceType(resourceType); 375 result.add(defaultInfo); 376 for (CmsResource model : modelResources) { 377 CmsGallerySearchResult searchInfo = CmsGallerySearch.searchById(cms, model.getStructureId(), contentLocale); 378 CmsModelResourceInfo modelInfo = new CmsModelResourceInfo( 379 searchInfo.getTitle(), 380 searchInfo.getDescription(), 381 null); 382 modelInfo.addAdditionalInfo( 383 Messages.get().getBundle(wpLocale).key(Messages.GUI_LABEL_PATH_0), 384 cms.getSitePath(model)); 385 modelInfo.setResourceType(resourceType); 386 modelInfo.setStructureId(model.getStructureId()); 387 result.add(modelInfo); 388 } 389 return result; 390 } 391 392 /** 393 * Returns serialized container data.<p> 394 * 395 * @param container the container 396 * 397 * @return the serialized data 398 * 399 * @throws Exception if serialization fails 400 */ 401 public static String getSerializedContainerInfo(CmsContainer container) throws Exception { 402 403 return CmsGwtActionElement.serialize(I_CmsContainerpageService.class.getMethod("getContainerInfo"), container); 404 } 405 406 /** 407 * Returns the serialized element data.<p> 408 * 409 * @param cms the cms context 410 * @param request the servlet request 411 * @param response the servlet response 412 * @param elementBean the element to serialize 413 * @param page the container page 414 * 415 * @return the serialized element data 416 * 417 * @throws Exception if something goes wrong 418 */ 419 public static String getSerializedElementInfo( 420 CmsObject cms, 421 HttpServletRequest request, 422 HttpServletResponse response, 423 CmsContainerElementBean elementBean, 424 CmsContainerPageBean page) 425 throws Exception { 426 427 CmsContainerElement result = new CmsContainerElement(); 428 CmsElementUtil util = new CmsElementUtil( 429 cms, 430 cms.getRequestContext().getUri(), 431 page, 432 null, 433 request, 434 response, 435 false, 436 cms.getRequestContext().getLocale()); 437 util.setElementInfo(elementBean, result); 438 return CmsGwtActionElement.serialize(I_CmsContainerpageService.class.getMethod("getElementInfo"), result); 439 } 440 441 /** 442 * Checks whether the current page is a model group page.<p> 443 * 444 * @param cms the CMS context 445 * @param containerPage the current page 446 * 447 * @return <code>true</code> if the current page is a model group page 448 */ 449 public static boolean isEditingModelGroups(CmsObject cms, CmsResource containerPage) { 450 451 return (OpenCms.getResourceManager().getResourceType(containerPage).getTypeName().equals( 452 CmsResourceTypeXmlContainerPage.MODEL_GROUP_TYPE_NAME) 453 && OpenCms.getRoleManager().hasRole(cms, CmsRole.DEVELOPER)); 454 } 455 456 /** 457 * Fetches the container page data.<p> 458 * 459 * @param request the current request 460 * 461 * @return the container page data 462 * 463 * @throws CmsRpcException if something goes wrong 464 */ 465 public static CmsCntPageData prefetch(HttpServletRequest request) throws CmsRpcException { 466 467 CmsContainerpageService srv = new CmsContainerpageService(); 468 srv.setCms(CmsFlexController.getCmsObject(request)); 469 srv.setRequest(request); 470 CmsCntPageData result = null; 471 try { 472 result = srv.prefetch(); 473 } finally { 474 srv.clearThreadStorage(); 475 } 476 return result; 477 } 478 479 /** 480 * Unlocks a page or set of pages if they are locked by the current user. 481 * 482 * <p>This is not called via the normal GWT-RPC mechanism, but with the browser's sendBeacon function. 483 * 484 * @param cms the CMS context 485 * @param request the current request 486 * @param response the current response 487 * @throws Exception if something goes wrong 488 */ 489 @SuppressWarnings("resource") 490 public static void unlockPage(CmsObject cms, HttpServletRequest request, HttpServletResponse response) 491 throws Exception { 492 493 // don't bother doing anything unless we have a session and are offline 494 495 if (request.getSession(false) == null) { 496 LOG.debug("no session found"); 497 return; 498 } 499 if (cms.getRequestContext().getCurrentProject().isOnlineProject()) { 500 LOG.debug("can't unlock page in online project"); 501 return; 502 } 503 504 byte[] byteData = CmsFileUtil.readFully(request.getInputStream(), false); 505 506 String encoding = request.getCharacterEncoding(); 507 if (encoding == null) { 508 encoding = "UTF-8"; 509 } 510 String strData = new String(byteData, encoding); 511 LOG.debug("Unlock request received: " + strData); 512 513 AutoBean<I_CmsUnlockData> data = AutoBeanCodex.decode( 514 AutoBeanFactorySource.create(I_CmsAutoBeanFactory.class), 515 I_CmsUnlockData.class, 516 strData); 517 518 I_CmsUnlockData unlockData = data.as(); 519 List<CmsUUID> ids = new ArrayList<>(); 520 if (CmsUUID.isValidUUID(unlockData.getPageId())) { 521 ids.add(new CmsUUID(unlockData.getPageId())); 522 } 523 CmsUUID detailId = null; 524 if (CmsUUID.isValidUUID(unlockData.getDetailId())) { 525 detailId = new CmsUUID(unlockData.getDetailId()); 526 try { 527 CmsResource detailResource = cms.readResource(detailId, CmsResourceFilter.ALL); 528 Optional<CmsResource> detailOnlyPage = CmsDetailOnlyContainerUtil.getDetailOnlyPage( 529 cms, 530 detailResource, 531 unlockData.getLocale()); 532 if (detailOnlyPage.isPresent()) { 533 ids.add(detailOnlyPage.get().getStructureId()); 534 } 535 } catch (CmsVfsResourceNotFoundException e) { 536 LOG.info(e.getLocalizedMessage(), e); 537 } catch (Exception e) { 538 LOG.error(e.getLocalizedMessage(), e); 539 } 540 } 541 542 for (CmsUUID id : ids) { 543 try { 544 CmsResource page = cms.readResource(id, CmsResourceFilter.IGNORE_EXPIRATION); 545 CmsLock lock = cms.getLock(page); 546 if (!lock.isUnlocked() && lock.isOwnedBy(cms.getRequestContext().getCurrentUser())) { 547 LOG.debug("Unlocking " + page.getRootPath()); 548 cms.unlockResource(page); 549 } else { 550 LOG.debug("Can't unlock " + page.getRootPath() + " because it's not locked for the current user."); 551 } 552 } catch (Exception e) { 553 LOG.error(e.getLocalizedMessage(), e); 554 } 555 } 556 } 557 558 /** 559 * Returns the server id part of the given client id.<p> 560 * 561 * @param id the id 562 * 563 * @return the server id 564 */ 565 private static String getServerIdString(String id) { 566 567 if (id.contains(CmsADEManager.CLIENT_ID_SEPERATOR)) { 568 id = id.substring(0, id.indexOf(CmsADEManager.CLIENT_ID_SEPERATOR)); 569 } 570 return id; 571 } 572 573 /** 574 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#addToFavoriteList(org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext, java.lang.String) 575 */ 576 public void addToFavoriteList(CmsContainerPageRpcContext context, String clientId) throws CmsRpcException { 577 578 try { 579 ensureSession(); 580 List<CmsContainerElementBean> list = OpenCms.getADEManager().getFavoriteList(getCmsObject()); 581 CmsResource containerPage = getCmsObject().readResource( 582 context.getPageStructureId(), 583 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 584 updateFavoriteRecentList(containerPage, clientId, list); 585 OpenCms.getADEManager().saveFavoriteList(getCmsObject(), list); 586 } catch (Throwable e) { 587 error(e); 588 } 589 } 590 591 /** 592 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#addToRecentList(org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext, java.lang.String) 593 */ 594 public void addToRecentList(CmsContainerPageRpcContext context, String clientId) throws CmsRpcException { 595 596 try { 597 ensureSession(); 598 List<CmsContainerElementBean> list = OpenCms.getADEManager().getRecentList(getCmsObject()); 599 CmsResource containerPage = getCmsObject().readResource( 600 context.getPageStructureId(), 601 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 602 updateFavoriteRecentList(containerPage, clientId, list); 603 OpenCms.getADEManager().saveRecentList(getCmsObject(), list); 604 } catch (Throwable e) { 605 error(e); 606 } 607 } 608 609 /** 610 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#checkContainerpageOrElementsChanged(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, java.lang.String) 611 */ 612 public boolean checkContainerpageOrElementsChanged( 613 CmsUUID structureId, 614 CmsUUID detailContentId, 615 String contentLocale) 616 throws CmsRpcException { 617 618 try { 619 List<CmsUUID> additionalIds = new ArrayList<CmsUUID>(); 620 additionalIds.add(structureId); 621 boolean detailOnlyChanged = false; 622 if (detailContentId != null) { 623 additionalIds.add(detailContentId); 624 try { 625 626 CmsObject cms = getCmsObject(); 627 CmsResource detailContentRes = cms.readResource(detailContentId, CmsResourceFilter.ALL); 628 OpenCms.getLocaleManager(); 629 CmsResource page = cms.readResource(structureId, CmsResourceFilter.ignoreExpirationOffline(cms)); 630 Optional<CmsResource> detailOnlyRes = CmsDetailOnlyContainerUtil.getDetailOnlyResource( 631 cms, 632 contentLocale, 633 detailContentRes, 634 page); 635 if (detailOnlyRes.isPresent()) { 636 detailOnlyChanged = CmsDefaultResourceStatusProvider.getContainerpageRelationTargets( 637 getCmsObject(), 638 detailOnlyRes.get().getStructureId(), 639 Arrays.asList(detailOnlyRes.get().getStructureId()), 640 true).isChanged(); 641 } 642 } catch (CmsException e) { 643 LOG.error(e.getLocalizedMessage(), e); 644 } 645 } 646 return detailOnlyChanged 647 || CmsDefaultResourceStatusProvider.getContainerpageRelationTargets( 648 getCmsObject(), 649 structureId, 650 additionalIds, 651 true /*stop looking if we find a changed resource.*/).isChanged(); 652 } catch (Throwable e) { 653 error(e); 654 return false; // will never be reached 655 } 656 657 } 658 659 /** 660 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#checkCreateNewElement(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, java.lang.String, java.lang.String, org.opencms.ade.containerpage.shared.CmsContainer, java.lang.String) 661 */ 662 public CmsCreateElementData checkCreateNewElement( 663 CmsUUID pageStructureId, 664 CmsUUID detailContentId, 665 String clientId, 666 String resourceType, 667 CmsContainer container, 668 String locale) 669 throws CmsRpcException { 670 671 CmsObject cms = getCmsObject(); 672 CmsCreateElementData result = new CmsCreateElementData(); 673 try { 674 CmsResource currentPage = cms.readResource(pageStructureId, CmsResourceFilter.ignoreExpirationOffline(cms)); 675 676 List<CmsResource> modelResources = CmsResourceTypeXmlContent.getModelFiles( 677 getCmsObject(), 678 CmsResource.getFolderPath(cms.getSitePath(currentPage)), 679 resourceType); 680 if (modelResources.isEmpty()) { 681 CmsContainerElementBean bean = getCachedElement(clientId, currentPage.getRootPath()); 682 I_CmsFormatterBean formatter = CmsElementUtil.getFormatterForContainer( 683 cms, 684 bean, 685 container, 686 getConfigData(currentPage.getRootPath()), 687 getSessionCache()); 688 CmsUUID modelResId = null; 689 if (formatter instanceof CmsMacroFormatterBean) { 690 modelResId = ((CmsMacroFormatterBean)formatter).getDefaultContentStructureId(); 691 } 692 result.setCreatedElement( 693 createNewElement(pageStructureId, detailContentId, clientId, resourceType, modelResId, locale)); 694 } else { 695 result.setModelResources( 696 generateModelResourceList( 697 getCmsObject(), 698 resourceType, 699 modelResources, 700 CmsLocaleManager.getLocale(locale))); 701 } 702 } catch (CmsException e) { 703 error(e); 704 } 705 return result; 706 } 707 708 /** 709 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#checkNewWidgetsAvailable(org.opencms.util.CmsUUID) 710 */ 711 public boolean checkNewWidgetsAvailable(CmsUUID structureId) throws CmsRpcException { 712 713 try { 714 CmsObject cms = getCmsObject(); 715 CmsResource resource = cms.readResource(structureId); 716 return CmsWorkplaceEditorManager.checkAcaciaEditorAvailable(cms, resource); 717 } catch (Throwable t) { 718 error(t); 719 } 720 return false; 721 } 722 723 /** 724 * Parses an element id.<p> 725 * 726 * @param id the element id 727 * 728 * @return the corresponding structure id 729 * 730 * @throws CmsIllegalArgumentException if the id has not the right format 731 */ 732 public CmsUUID convertToServerId(String id) throws CmsIllegalArgumentException { 733 734 if (id == null) { 735 throw new CmsIllegalArgumentException( 736 org.opencms.xml.containerpage.Messages.get().container( 737 org.opencms.xml.containerpage.Messages.ERR_INVALID_ID_1, 738 id)); 739 } 740 String serverId = getServerIdString(id); 741 try { 742 return new CmsUUID(serverId); 743 } catch (NumberFormatException e) { 744 throw new CmsIllegalArgumentException( 745 org.opencms.xml.containerpage.Messages.get().container( 746 org.opencms.xml.containerpage.Messages.ERR_INVALID_ID_1, 747 id), 748 e); 749 } 750 } 751 752 /** 753 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#copyElement(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, java.lang.String) 754 */ 755 public CmsUUID copyElement(CmsUUID pageId, CmsUUID originalElementId, String locale) throws CmsRpcException { 756 757 try { 758 CmsObject cms = OpenCms.initCmsObject(getCmsObject()); 759 cms.getRequestContext().setLocale(CmsLocaleManager.getLocale(locale)); 760 CmsResource page = cms.readResource(pageId, CmsResourceFilter.IGNORE_EXPIRATION); 761 CmsResource element = cms.readResource(originalElementId, CmsResourceFilter.IGNORE_EXPIRATION); 762 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(cms, page.getRootPath()); 763 String typeName = OpenCms.getResourceManager().getResourceType(element.getTypeId()).getTypeName(); 764 CmsResourceTypeConfig typeConfig = config.getResourceType(typeName); 765 if (typeConfig == null) { 766 LOG.error("copyElement: Type not configured in ADE configuration: " + typeName); 767 return originalElementId; 768 } else { 769 CmsResource newResource = typeConfig.createNewElement( 770 cms, 771 element, 772 CmsResource.getParentFolder(page.getRootPath())); 773 return newResource.getStructureId(); 774 } 775 } catch (Throwable e) { 776 error(e); 777 return null; // will never be reached 778 } 779 } 780 781 /** 782 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#createNewElement(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, java.lang.String, java.lang.String, org.opencms.util.CmsUUID, java.lang.String) 783 */ 784 public CmsContainerElement createNewElement( 785 CmsUUID pageStructureId, 786 CmsUUID detailContentId, 787 String clientId, 788 String resourceType, 789 CmsUUID modelResourceStructureId, 790 String locale) 791 throws CmsRpcException { 792 793 CmsContainerElement element = null; 794 try { 795 ensureSession(); 796 CmsObject cms = getCmsObject(); 797 CmsResource pageResource = cms.readResource( 798 pageStructureId, 799 CmsResourceFilter.ignoreExpirationOffline(cms)); 800 CmsADEConfigData configData = getConfigData(pageResource.getRootPath()); 801 CmsResourceTypeConfig typeConfig = configData.getResourceType(resourceType); 802 CmsObject cloneCms = OpenCms.initCmsObject(cms); 803 cloneCms.getRequestContext().setLocale(CmsLocaleManager.getLocale(locale)); 804 805 CmsResource modelResource = null; 806 if (modelResourceStructureId != null) { 807 modelResource = cms.readResource(modelResourceStructureId); 808 } 809 String pageFolderForElementCreation = CmsResource.getParentFolder(pageResource.getRootPath()); 810 if (detailContentId != null) { 811 try { 812 CmsResource detailResource = cms.readResource(detailContentId, CmsResourceFilter.IGNORE_EXPIRATION); 813 pageFolderForElementCreation = CmsResource.getParentFolder( 814 CmsDetailOnlyContainerUtil.getDetailOnlyPageName( 815 cloneCms, 816 pageResource, 817 detailResource.getRootPath(), 818 locale)); 819 } catch (Exception e) { 820 // pageFolderForElementCreation remains the folder of the detail page in this case 821 LOG.info(e.getLocalizedMessage(), e); 822 } 823 } 824 CmsResource newResource = typeConfig.createNewElement( 825 cloneCms, 826 modelResource, 827 pageFolderForElementCreation); 828 CmsContainerElementBean bean = getCachedElement(clientId, pageResource.getRootPath()); 829 Map<String, String> settings = new HashMap<String, String>(); 830 831 settings = bean.getIndividualSettings(); 832 833 CmsContainerElementBean newBean = new CmsContainerElementBean( 834 newResource.getStructureId(), 835 null, 836 settings, 837 typeConfig.isCopyInModels()); 838 String newClientId = newBean.editorHash(); 839 getSessionCache().setCacheContainerElement(newClientId, newBean); 840 element = new CmsContainerElement(); 841 element.setNewEditorDisabled(!CmsWorkplaceEditorManager.checkAcaciaEditorAvailable(cms, newResource)); 842 element.setClientId(newClientId); 843 element.setSitePath(cms.getSitePath(newResource)); 844 element.setResourceType(resourceType); 845 element.setIconClasses( 846 CmsIconUtil.getIconClasses(CmsIconUtil.getDisplayType(cms, newResource), null, false)); 847 element.setCreateNew(newBean.isCreateNew()); 848 } catch (CmsException e) { 849 error(e); 850 } 851 return element; 852 } 853 854 /** 855 * Reads the cached element-bean for the given client-side-id from cache.<p> 856 * 857 * @param clientId the client-side-id 858 * @param pageRootPath the container page root path 859 * 860 * @return the cached container element bean 861 * 862 * @throws CmsException in case reading the element resource fails 863 */ 864 public CmsContainerElementBean getCachedElement(String clientId, String pageRootPath) throws CmsException { 865 866 String id = clientId; 867 CmsContainerElementBean element = null; 868 element = getSessionCache().getCacheContainerElement(id); 869 if (element != null) { 870 return element; 871 } 872 if (id.contains(CmsADEManager.CLIENT_ID_SEPERATOR)) { 873 throw new CmsException(Messages.get().container(Messages.ERR_MISSING_CACHED_ELEMENT_0)); 874 } 875 // this is necessary if the element has not been cached yet 876 CmsResource resource = getCmsObject().readResource(convertToServerId(id), CmsResourceFilter.IGNORE_EXPIRATION); 877 CmsADEConfigData configData = getConfigData(pageRootPath); 878 CmsResourceTypeConfig typeConfig = configData.getResourceType( 879 OpenCms.getResourceManager().getResourceType(resource).getTypeName()); 880 element = new CmsContainerElementBean( 881 convertToServerId(id), 882 null, 883 null, 884 (typeConfig != null) && typeConfig.isCopyInModels()); 885 getSessionCache().setCacheContainerElement(element.editorHash(), element); 886 return element; 887 } 888 889 /** 890 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getContainerInfo() 891 */ 892 public CmsContainer getContainerInfo() { 893 894 throw new UnsupportedOperationException("This method is used for serialization only."); 895 } 896 897 /** 898 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getDeleteOptions(java.lang.String, org.opencms.util.CmsUUID, java.lang.String) 899 */ 900 public CmsDialogOptionsAndInfo getDeleteOptions(String clientId, CmsUUID pageId, String requestParams) 901 throws CmsRpcException { 902 903 try { 904 CmsResource pageResource = getCmsObject().readResource( 905 pageId, 906 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 907 CmsContainerElementBean element = getCachedElement(clientId, pageResource.getRootPath()); 908 element.initResource(getCmsObject()); 909 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 910 if (type instanceof CmsResourceTypeXmlContent) { 911 I_CmsEditHandler handler = ((CmsResourceTypeXmlContent)type).getEditHandler(getCmsObject()); 912 Map<String, String[]> params = CmsRequestUtil.createParameterMap( 913 CmsEncoder.decode(requestParams), 914 true, 915 CmsEncoder.ENCODING_UTF_8); 916 CmsDialogOptions options = handler.getDeleteOptions(getCmsObject(), element, pageId, params); 917 if (options != null) { 918 return new CmsDialogOptionsAndInfo( 919 options, 920 CmsVfsService.getPageInfo(getCmsObject(), element.getResource())); 921 } 922 } 923 } catch (CmsException e) { 924 error(e); 925 } 926 return null; 927 } 928 929 /** 930 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getEditOptions(java.lang.String, org.opencms.util.CmsUUID, java.lang.String, boolean) 931 */ 932 public CmsDialogOptionsAndInfo getEditOptions( 933 String clientId, 934 CmsUUID pageId, 935 String requestParams, 936 boolean isListElement) 937 throws CmsRpcException { 938 939 try { 940 CmsResource pageResource = getCmsObject().readResource( 941 pageId, 942 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 943 CmsContainerElementBean element = getCachedElement(clientId, pageResource.getRootPath()); 944 element.initResource(getCmsObject()); 945 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 946 if (type instanceof CmsResourceTypeXmlContent) { 947 I_CmsEditHandler handler = ((CmsResourceTypeXmlContent)type).getEditHandler(getCmsObject()); 948 Map<String, String[]> params = CmsRequestUtil.createParameterMap( 949 CmsEncoder.decode(requestParams), 950 true, 951 CmsEncoder.ENCODING_UTF_8); 952 CmsDialogOptions options = handler.getEditOptions( 953 getCmsObject(), 954 element, 955 pageId, 956 params, 957 isListElement); 958 if (options != null) { 959 return new CmsDialogOptionsAndInfo( 960 options, 961 CmsVfsService.getPageInfo(getCmsObject(), element.getResource())); 962 } 963 } 964 } catch (CmsException e) { 965 error(e); 966 } 967 return null; 968 } 969 970 /** 971 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getElementInfo() 972 */ 973 public CmsContainerElement getElementInfo() { 974 975 throw new UnsupportedOperationException("This method is used for serialization only."); 976 } 977 978 /** 979 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getElementsData(org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext, org.opencms.util.CmsUUID, java.lang.String, java.util.Collection, java.util.Collection, boolean, java.lang.String, java.lang.String) 980 */ 981 public Map<String, CmsContainerElementData> getElementsData( 982 CmsContainerPageRpcContext context, 983 CmsUUID detailContentId, 984 String reqParams, 985 Collection<String> clientIds, 986 Collection<CmsContainer> containers, 987 boolean allwaysCopy, 988 String dndSource, 989 String locale) 990 throws CmsRpcException { 991 992 Map<String, CmsContainerElementData> result = null; 993 try { 994 ensureSession(); 995 CmsResource pageResource = getCmsObject().readResource( 996 context.getPageStructureId(), 997 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 998 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration( 999 getCmsObject(), 1000 pageResource.getRootPath()); 1001 initRequestFromRpcContext(context); 1002 String containerpageUri = getCmsObject().getSitePath(pageResource); 1003 result = getElements( 1004 config, 1005 pageResource, 1006 clientIds, 1007 containerpageUri, 1008 detailContentId, 1009 containers, 1010 allwaysCopy, 1011 dndSource, 1012 CmsStringUtil.isNotEmptyOrWhitespaceOnly(dndSource), 1013 CmsLocaleManager.getLocale(locale)); 1014 } catch (Throwable e) { 1015 error(e); 1016 } 1017 return result; 1018 } 1019 1020 /** 1021 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getElementSettingsConfig(org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext, java.lang.String, java.lang.String, java.util.Collection, java.lang.String) 1022 */ 1023 public CmsElementSettingsConfig getElementSettingsConfig( 1024 CmsContainerPageRpcContext context, 1025 String clientId, 1026 String containerId, 1027 Collection<CmsContainer> containers, 1028 String locale) 1029 throws CmsRpcException { 1030 1031 try { 1032 ensureSession(); 1033 CmsObject cms = getCmsObject(); 1034 CmsResource pageResource = cms.readResource( 1035 context.getPageStructureId(), 1036 CmsResourceFilter.ignoreExpirationOffline(cms)); 1037 initRequestFromRpcContext(context); 1038 String containerpageUri = cms.getSitePath(pageResource); 1039 1040 CmsContainerPageBean pageBean = generateContainerPageForContainers( 1041 containers, 1042 cms.getRequestContext().addSiteRoot(containerpageUri)); 1043 1044 CmsElementUtil elemUtil = new CmsElementUtil( 1045 cms, 1046 containerpageUri, 1047 pageBean, 1048 null, 1049 getRequest(), 1050 getResponse(), 1051 false, 1052 CmsLocaleManager.getLocale(locale)); 1053 CmsContainerElementBean element = getCachedElement( 1054 clientId, 1055 cms.getRequestContext().addSiteRoot(containerpageUri)); 1056 if (element.getInstanceId() == null) { 1057 element = element.clone(); 1058 getSessionCache().setCacheContainerElement(element.editorHash(), element); 1059 } 1060 element.initResource(cms); 1061 return elemUtil.getElementSettingsConfig(pageResource, element, containerId, containers); 1062 } catch (Throwable e) { 1063 error(e); 1064 } 1065 return null; 1066 } 1067 1068 /** 1069 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getElementsLockedForPublishing(java.util.Set) 1070 */ 1071 public Set<CmsUUID> getElementsLockedForPublishing(Set<CmsUUID> idsToCheck) throws CmsRpcException { 1072 1073 try { 1074 CmsObject cms = getCmsObject(); 1075 Set<CmsUUID> result = new HashSet<>(); 1076 for (CmsUUID id : idsToCheck) { 1077 try { 1078 CmsResource resource = cms.readResource(id, CmsResourceFilter.ALL); 1079 CmsLock lock = cms.getLock(resource); 1080 if (!lock.getSystemLock().isUnlocked() 1081 && lock.getUserId().equals(cms.getRequestContext().getCurrentUser().getId())) { 1082 result.add(resource.getStructureId()); 1083 } 1084 } catch (CmsVfsResourceNotFoundException e) { 1085 LOG.debug(e.getLocalizedMessage(), e); 1086 } 1087 } 1088 return result; 1089 } catch (Exception e) { 1090 error(e); 1091 return null; 1092 } 1093 } 1094 1095 /** 1096 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getElementWithSettings(org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext, org.opencms.util.CmsUUID, java.lang.String, java.lang.String, java.util.Map, java.util.Collection, java.lang.String) 1097 */ 1098 public CmsContainerElementData getElementWithSettings( 1099 CmsContainerPageRpcContext context, 1100 CmsUUID detailContentId, 1101 String uriParams, 1102 String clientId, 1103 Map<String, String> settings, 1104 Collection<CmsContainer> containers, 1105 String locale) 1106 throws CmsRpcException { 1107 1108 CmsContainerElementData element = null; 1109 try { 1110 ensureSession(); 1111 CmsObject cms = getCmsObject(); 1112 CmsResource pageResource = cms.readResource( 1113 context.getPageStructureId(), 1114 CmsResourceFilter.ignoreExpirationOffline(cms)); 1115 initRequestFromRpcContext(context); 1116 String containerpageUri = cms.getSitePath(pageResource); 1117 Locale contentLocale = CmsLocaleManager.getLocale(locale); 1118 CmsElementUtil elemUtil = new CmsElementUtil( 1119 cms, 1120 containerpageUri, 1121 generateContainerPageForContainers(containers, pageResource.getRootPath()), 1122 detailContentId, 1123 getRequest(), 1124 getResponse(), 1125 false, 1126 contentLocale); 1127 1128 CmsContainerElementBean elementBean = getCachedElement(clientId, pageResource.getRootPath()); 1129 elementBean.initResource(cms); 1130 storeFormatterSelection(elementBean, settings); 1131 // make sure to keep the element instance id 1132 if (!settings.containsKey(CmsContainerElement.ELEMENT_INSTANCE_ID) 1133 && elementBean.getIndividualSettings().containsKey(CmsContainerElement.ELEMENT_INSTANCE_ID)) { 1134 settings.put( 1135 CmsContainerElement.ELEMENT_INSTANCE_ID, 1136 elementBean.getIndividualSettings().get(CmsContainerElement.ELEMENT_INSTANCE_ID)); 1137 } 1138 1139 elementBean = CmsContainerElementBean.cloneWithSettings( 1140 elementBean, 1141 convertSettingValues(elementBean.getResource(), settings, contentLocale)); 1142 getSessionCache().setCacheContainerElement(elementBean.editorHash(), elementBean); 1143 element = elemUtil.getElementData(pageResource, elementBean, containers); 1144 } catch (Throwable e) { 1145 error(e); 1146 } 1147 return element; 1148 } 1149 1150 /** 1151 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getFavoriteList(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, java.util.Collection, java.lang.String) 1152 */ 1153 public List<CmsContainerElementData> getFavoriteList( 1154 CmsUUID pageStructureId, 1155 CmsUUID detailContentId, 1156 Collection<CmsContainer> containers, 1157 String locale) 1158 throws CmsRpcException { 1159 1160 List<CmsContainerElementData> result = null; 1161 try { 1162 ensureSession(); 1163 CmsResource containerpage = getCmsObject().readResource( 1164 pageStructureId, 1165 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1166 String containerpageUri = getCmsObject().getSitePath(containerpage); 1167 result = getListElementsData( 1168 OpenCms.getADEManager().getFavoriteList(getCmsObject()), 1169 containerpageUri, 1170 detailContentId, 1171 containers, 1172 CmsLocaleManager.getLocale(locale)); 1173 } catch (Throwable e) { 1174 error(e); 1175 } 1176 return result; 1177 } 1178 1179 /** 1180 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getGalleryDataForPage(java.util.List, org.opencms.util.CmsUUID, java.lang.String, org.opencms.util.CmsUUID, java.lang.String, org.opencms.gwt.shared.CmsTemplateContextInfo) 1181 */ 1182 public CmsContainerPageGalleryData getGalleryDataForPage( 1183 final List<CmsContainer> containers, 1184 CmsUUID elementView, 1185 String uri, 1186 CmsUUID detailContentId, 1187 String locale, 1188 CmsTemplateContextInfo templateContextInfo) 1189 throws CmsRpcException { 1190 1191 CmsGalleryDataBean data = null; 1192 try { 1193 CmsObject cms = getCmsObject(); 1194 List<CmsResourceTypeBean> resTypeBeans = getGalleryTypesForView( 1195 cms, 1196 containers, 1197 elementView, 1198 uri, 1199 detailContentId, 1200 locale, 1201 templateContextInfo); 1202 CmsGalleryService srv = new CmsGalleryService(); 1203 srv.setCms(cms); 1204 srv.setRequest(getRequest()); 1205 data = srv.getInitialSettingsForContainerPage(resTypeBeans, uri, locale); 1206 CmsContainerPageGalleryData result = new CmsContainerPageGalleryData(); 1207 1208 CmsADESessionCache cache = CmsADESessionCache.getCache(getRequest(), cms); 1209 CmsGallerySearchBean search = cache.getLastPageEditorGallerySearch(); 1210 String subsite = OpenCms.getADEManager().getSubSiteRoot(cms, cms.addSiteRoot(uri)); 1211 1212 // The template context now influences the gallery search results, so use checksum of the template context provider and context as part of the cache key 1213 String providerSuffix = "null"; 1214 if (templateContextInfo != null) { 1215 String providerKey = templateContextInfo.getContextProvider(); 1216 I_CmsTemplateContextProvider provider = OpenCms.getTemplateContextManager().getTemplateContextProvider( 1217 providerKey); 1218 if (provider != null) { 1219 try { 1220 MessageDigest md5 = MessageDigest.getInstance("md5"); 1221 md5.update(providerKey.getBytes(StandardCharsets.UTF_8)); 1222 if (templateContextInfo.getCurrentContext() != null) { 1223 md5.update((byte)0); // 0 byte as separator 1224 md5.update(templateContextInfo.getCurrentContext().getBytes(StandardCharsets.UTF_8)); 1225 providerSuffix = Hex.encodeHexString(md5.digest()); 1226 } 1227 } catch (NoSuchAlgorithmException e) { 1228 // MD5 must be in standard library 1229 } 1230 } 1231 } 1232 1233 String searchStoreKey = elementView + "|" + subsite + "|" + locale + "|" + providerSuffix; 1234 data.getContextParameters().put("searchStoreKey", searchStoreKey); 1235 if ((search != null) && !search.getServerSearchTypes().contains(CmsResourceTypeFunctionConfig.TYPE_NAME)) { 1236 if (searchStoreKey.equals( 1237 search.getOriginalGalleryData().getContextParameters().get("searchStoreKey"))) { 1238 if (hasCompatibleSearchData(search.getOriginalGalleryData(), data, search)) { 1239 1240 CmsVfsEntryBean preloadData = null; 1241 if (search.getFolders() != null) { 1242 preloadData = CmsGalleryService.generateVfsPreloadData( 1243 getCmsObject(), 1244 CmsGalleryService.getVfsTreeState(getRequest(), data.getTreeToken()), 1245 search.getFolders()); 1246 } 1247 1248 // only restore last result list if the search was performed in a 'similar' context 1249 search.setTabId(GalleryTabId.cms_tab_results.toString()); 1250 search.setPage(1); 1251 search.setLastPage(0); 1252 data.setStartTab(GalleryTabId.cms_tab_results); 1253 search = srv.getSearch(search); 1254 data.setVfsPreloadData(preloadData); 1255 data.setIncludeExpiredDefault(search.isIncludeExpired()); 1256 result.setGallerySearch(search); 1257 } 1258 } 1259 } 1260 result.setGalleryData(data); 1261 return result; 1262 1263 } catch (Exception e) { 1264 error(e); 1265 return null; 1266 } 1267 } 1268 1269 /** 1270 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getGalleryTypesForMultipleViews(java.util.List, java.util.List, java.lang.String, org.opencms.util.CmsUUID, java.lang.String, org.opencms.gwt.shared.CmsTemplateContextInfo) 1271 */ 1272 public Map<CmsUUID, List<CmsResourceTypeBean>> getGalleryTypesForMultipleViews( 1273 final List<CmsContainer> containers, 1274 List<CmsUUID> views, 1275 String uri, 1276 CmsUUID detailContentId, 1277 String locale, 1278 CmsTemplateContextInfo templateContextInfo) 1279 throws CmsRpcException { 1280 1281 try { 1282 Map<CmsUUID, List<CmsResourceTypeBean>> result = new HashMap<>(); 1283 CmsObject cms = getCmsObject(); 1284 for (CmsUUID view : views) { 1285 List<CmsResourceTypeBean> typesForView = getGalleryTypesForView( 1286 cms, 1287 containers, 1288 view, 1289 uri, 1290 detailContentId, 1291 locale, 1292 templateContextInfo); 1293 result.put(view, typesForView); 1294 } 1295 return result; 1296 } catch (Exception e) { 1297 error(e); 1298 return null; 1299 } 1300 } 1301 1302 /** 1303 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getListElementCreationOptions(org.opencms.util.CmsUUID, java.lang.String) 1304 */ 1305 public CmsListElementCreationDialogData getListElementCreationOptions(CmsUUID structureId, String jsonListAddData) 1306 throws CmsRpcException { 1307 1308 CmsObject cms = getCmsObject(); 1309 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1310 CmsMessages msg = Messages.get().getBundle(locale); 1311 try { 1312 CmsUUID listId = structureId; 1313 1314 String jsonConfig = jsonListAddData; 1315 I_CmsAutoBeanFactory beanFactory = AutoBeanFactorySource.create(I_CmsAutoBeanFactory.class); 1316 AutoBean<I_CmsListAddMetadata> listAddData = AutoBeanCodex.decode( 1317 beanFactory, 1318 I_CmsListAddMetadata.class, 1319 jsonConfig); 1320 CmsListElementCreationDialogData result = new CmsListElementCreationDialogData(); 1321 result.setCaption(msg.key(Messages.GUI_LISTADD_CAPTION_0)); 1322 result.setPostCreateHandler(listAddData.as().getPostCreateHandler()); 1323 String uploadFolder = listAddData.as().getUploadFolder(); 1324 boolean isUpload = false; 1325 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(uploadFolder) && !"none".equals(uploadFolder)) { 1326 if (listAddData.as().getTypes().stream().anyMatch( 1327 type -> CmsResourceTypeBinary.getStaticTypeName().equals(type) 1328 || CmsResourceTypePlain.getStaticTypeName().equals(type) 1329 || CmsResourceTypeImage.getStaticTypeName().equals(type))) { 1330 1331 CmsResource uploadFolderResource = null; 1332 try { 1333 uploadFolderResource = cms.readResource(uploadFolder, CmsResourceFilter.IGNORE_EXPIRATION); 1334 if (cms.hasPermissions( 1335 uploadFolderResource, 1336 CmsPermissionSet.ACCESS_WRITE, 1337 false, 1338 CmsResourceFilter.IGNORE_EXPIRATION)) { 1339 isUpload = true; 1340 } 1341 } catch (CmsVfsResourceNotFoundException | CmsPermissionViolationException e) { 1342 LOG.debug(e.getLocalizedMessage(), e); 1343 } catch (Exception e) { 1344 LOG.error(e.getLocalizedMessage(), e); 1345 } 1346 } 1347 } 1348 if (isUpload) { 1349 result.setUploadFolder(uploadFolder); 1350 CmsListInfoBean listResourceInfo = CmsVfsService.getPageInfo( 1351 cms, 1352 cms.readResource(uploadFolder, CmsResourceFilter.IGNORE_EXPIRATION)); 1353 result.setListInfo(listResourceInfo); 1354 } else { 1355 CmsADEConfigData adeConfig = OpenCms.getADEManager().lookupConfiguration( 1356 cms, 1357 cms.getRequestContext().getRootUri()); 1358 CmsResource listResource = cms.readResource(listId, CmsResourceFilter.IGNORE_EXPIRATION); 1359 CmsListInfoBean listResourceInfo = CmsVfsService.getPageInfo(cms, listResource); 1360 result.setListInfo(listResourceInfo); 1361 List<String> createTypes = listAddData.as().getTypes(); 1362 Map<String, CmsResourceTypeConfig> typeMap = adeConfig.getTypesByName(); 1363 for (String type : createTypes) { 1364 try { 1365 CmsResourceTypeConfig currentType = typeMap.get(type); 1366 if (currentType != null) { 1367 if (adeConfig.getDirectEditPermissions(type).canCreate() 1368 && currentType.checkCreatable(cms, null)) { 1369 CmsListInfoBean typeInfo = new CmsListInfoBean(); 1370 CmsExplorerTypeSettings explorerType = OpenCms.getWorkplaceManager().getExplorerTypeSetting( 1371 type); 1372 String title = CmsWorkplaceMessages.getResourceTypeName(locale, type); 1373 typeInfo.setTitle(title); 1374 String description = CmsWorkplaceMessages.getResourceTypeDescription(locale, type); 1375 typeInfo.setSubTitle(description); 1376 typeInfo.setResourceType(type); 1377 typeInfo.setBigIconClasses(CmsIconUtil.getIconClasses(explorerType, null, false)); 1378 String newLink = CmsJspTagEdit.getNewLink( 1379 cms, 1380 OpenCms.getResourceManager().getResourceType(type), 1381 cms.getRequestContext().getUri()); 1382 CmsListElementCreationOption option = new CmsListElementCreationOption( 1383 type, 1384 typeInfo, 1385 newLink); 1386 result.add(option); 1387 } 1388 } 1389 } catch (Exception e) { 1390 LOG.error(e.getLocalizedMessage(), e); 1391 } 1392 } 1393 if (result.getOptions().size() == 0) { 1394 result.setMessage(msg.key(Messages.GUI_LISTADD_NO_TYPES_0)); 1395 } 1396 } 1397 1398 return result; 1399 } catch (Exception e) { 1400 error(e); 1401 return null; 1402 } 1403 } 1404 1405 /** 1406 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getNewElementData(org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext, org.opencms.util.CmsUUID, java.lang.String, java.lang.String, java.util.Collection, java.lang.String) 1407 */ 1408 public CmsContainerElementData getNewElementData( 1409 CmsContainerPageRpcContext context, 1410 CmsUUID detailContentId, 1411 String reqParams, 1412 String resourceType, 1413 Collection<CmsContainer> containers, 1414 String localeName) 1415 throws CmsRpcException { 1416 1417 CmsContainerElementData result = null; 1418 try { 1419 ensureSession(); 1420 CmsResource pageResource = getCmsObject().readResource( 1421 context.getPageStructureId(), 1422 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1423 initRequestFromRpcContext(context); 1424 String containerpageUri = getCmsObject().getSitePath(pageResource); 1425 Locale locale = CmsLocaleManager.getLocale(localeName); 1426 result = getNewElement( 1427 getServerIdString(resourceType), 1428 containerpageUri, 1429 detailContentId, 1430 containers, 1431 locale); 1432 1433 CmsListInfoBean info = new CmsListInfoBean(); 1434 // type title and subtitle 1435 String realType = getServerIdString(resourceType); 1436 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()); 1437 info.setTitle(CmsWorkplaceMessages.getResourceTypeName(wpLocale, realType)); 1438 info.setSubTitle(CmsWorkplaceMessages.getResourceTypeDescription(wpLocale, realType)); 1439 info.setBigIconClasses(CmsIconUtil.getIconClasses(realType, null, false)); 1440 result.setListInfo(info); 1441 } catch (Throwable e) { 1442 error(e); 1443 } 1444 return result; 1445 } 1446 1447 /** 1448 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getNewOptions(java.lang.String, org.opencms.util.CmsUUID, java.lang.String) 1449 */ 1450 public CmsDialogOptionsAndInfo getNewOptions(String clientId, CmsUUID pageStructureId, String requestParams) 1451 throws CmsRpcException { 1452 1453 try { 1454 CmsResource pageResource = getCmsObject().readResource( 1455 pageStructureId, 1456 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1457 CmsContainerElementBean element = getCachedElement(clientId, pageResource.getRootPath()); 1458 element.initResource(getCmsObject()); 1459 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 1460 if (type instanceof CmsResourceTypeXmlContent) { 1461 I_CmsEditHandler handler = ((CmsResourceTypeXmlContent)type).getEditHandler(getCmsObject()); 1462 Map<String, String[]> params = CmsRequestUtil.createParameterMap( 1463 CmsEncoder.decode(requestParams), 1464 true, 1465 CmsEncoder.ENCODING_UTF_8); 1466 CmsDialogOptions options = handler.getNewOptions(getCmsObject(), element, pageStructureId, params); 1467 if (options != null) { 1468 return new CmsDialogOptionsAndInfo( 1469 options, 1470 CmsVfsService.getPageInfo(getCmsObject(), element.getResource())); 1471 } 1472 } 1473 } catch (CmsException e) { 1474 error(e); 1475 } 1476 return null; 1477 1478 } 1479 1480 /** 1481 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getRecentList(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, java.util.Collection, java.lang.String) 1482 */ 1483 public List<CmsContainerElementData> getRecentList( 1484 CmsUUID pageStructureId, 1485 CmsUUID detailContentId, 1486 Collection<CmsContainer> containers, 1487 String locale) 1488 throws CmsRpcException { 1489 1490 List<CmsContainerElementData> result = null; 1491 try { 1492 ensureSession(); 1493 CmsResource containerpage = getCmsObject().readResource( 1494 pageStructureId, 1495 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1496 String containerpageUri = getCmsObject().getSitePath(containerpage); 1497 result = getListElementsData( 1498 OpenCms.getADEManager().getRecentList(getCmsObject()), 1499 containerpageUri, 1500 detailContentId, 1501 containers, 1502 CmsLocaleManager.getLocale(locale)); 1503 } catch (Throwable e) { 1504 error(e); 1505 } 1506 return result; 1507 } 1508 1509 /** 1510 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getRemovedElementStatus(java.lang.String, org.opencms.util.CmsUUID, org.opencms.util.CmsUUID) 1511 */ 1512 public CmsRemovedElementStatus getRemovedElementStatus(String id, CmsUUID contextId, CmsUUID containerpageId) 1513 throws CmsRpcException { 1514 1515 if ((id == null) || !id.matches(CmsUUID.UUID_REGEX + ".*$")) { 1516 return new CmsRemovedElementStatus(null, null, false, null); 1517 } 1518 try { 1519 CmsUUID structureId = convertToServerId(id); 1520 return internalGetRemovedElementStatus(structureId, contextId, containerpageId); 1521 } catch (CmsException e) { 1522 error(e); 1523 return null; 1524 } 1525 } 1526 1527 /** 1528 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getReuseInfo(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, org.opencms.util.CmsUUID) 1529 */ 1530 public CmsReuseInfo getReuseInfo(CmsUUID pageId, CmsUUID detailId, CmsUUID elementId) throws CmsRpcException { 1531 1532 try { 1533 CmsObject cms = getCmsObject(); 1534 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1535 CmsResource detailResource = null; 1536 CmsResource element = cms.readResource(elementId, CmsResourceFilter.IGNORE_EXPIRATION); 1537 if (detailId != null) { 1538 detailResource = cms.readResource(detailId, CmsResourceFilter.IGNORE_EXPIRATION); 1539 } 1540 Set<CmsUUID> idsForCurrentPage = CmsElementUtil.getPageAndDetailOnlyIds( 1541 getCmsObject(), 1542 pageId, 1543 detailResource); 1544 List<CmsResource> allUses = OpenCms.getADEManager().getOfflineElementUses(element).filter( 1545 res -> !idsForCurrentPage.contains(res.getStructureId())).collect(Collectors.toList()); 1546 List<CmsResourceListInfo> infos = new ArrayList<>(); 1547 int visibleCount = 0; 1548 for (CmsResource use : allUses) { 1549 try { 1550 // make sure resource is visible to current user, otherwise continue with next resource 1551 cms.readResource(use.getStructureId(), CmsResourceFilter.IGNORE_EXPIRATION.addRequireVisible()); 1552 visibleCount += 1; 1553 CmsResourceListInfo info = new CmsResourceListInfo(); 1554 CmsVfsService.addPageInfo(cms, use, info); 1555 info.setStructureId(use.getStructureId()); 1556 infos.add(info); 1557 if (visibleCount >= MAX_VISIBLE_ELEMENT_USES) { 1558 break; 1559 } 1560 } catch (CmsVfsResourceNotFoundException | CmsPermissionViolationException e) { 1561 // ignore 1562 } catch (Exception e) { 1563 LOG.error(e.getLocalizedMessage(), e); 1564 } 1565 } 1566 CmsListInfoBean elementInfo = CmsVfsService.getPageInfo(cms, element); 1567 String message; 1568 CmsMessages messages = Messages.get().getBundle(locale); 1569 if (allUses.size() > 0) { 1570 message = messages.key(Messages.GUI_REUSE_CHECK_WARNING_TEXT_1, "" + allUses.size()); 1571 } else { 1572 message = ""; 1573 } 1574 String title = messages.key(Messages.GUI_REUSE_CHECK_TITLE_0); 1575 if (allUses.size() > infos.size()) { 1576 message = message + "\n" + messages.key(Messages.GUI_REUSE_CHECK_ONLY_SHOW_N_1, infos.size()); 1577 } 1578 CmsReuseInfo result = new CmsReuseInfo(elementInfo, infos, message, title, allUses.size()); 1579 return result; 1580 } catch (Exception e) { 1581 error(e); 1582 return null; 1583 } 1584 } 1585 1586 /** 1587 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#handleDelete(java.lang.String, java.lang.String, org.opencms.util.CmsUUID, java.lang.String) 1588 */ 1589 public void handleDelete(String clientId, String deleteOption, CmsUUID pageId, String requestParams) 1590 throws CmsRpcException { 1591 1592 try { 1593 CmsResource pageResource = getCmsObject().readResource( 1594 pageId, 1595 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1596 CmsContainerElementBean element = getCachedElement(clientId, pageResource.getRootPath()); 1597 element.initResource(getCmsObject()); 1598 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 1599 if (type instanceof CmsResourceTypeXmlContent) { 1600 I_CmsEditHandler handler = ((CmsResourceTypeXmlContent)type).getEditHandler(getCmsObject()); 1601 Map<String, String[]> params = CmsRequestUtil.createParameterMap( 1602 CmsEncoder.decode(requestParams), 1603 true, 1604 CmsEncoder.ENCODING_UTF_8); 1605 handler.handleDelete(getCmsObject(), element, deleteOption, pageId, params); 1606 } 1607 } catch (CmsException e) { 1608 error(e); 1609 } 1610 } 1611 1612 /** 1613 * Internal helper method to get the status of a removed element.<p> 1614 * 1615 * @param structureId the structure id of the removed element 1616 * @param contextId the id of the resource used to look up the sitemap configuration 1617 * @param containerpageId the id of the page to exclude from the relation check, or null if no page should be excluded 1618 * 1619 * @return the status of the removed element 1620 * 1621 * @throws CmsException in case reading the resource fails 1622 */ 1623 public CmsRemovedElementStatus internalGetRemovedElementStatus( 1624 CmsUUID structureId, 1625 CmsUUID contextId, 1626 CmsUUID containerpageId) 1627 throws CmsException { 1628 1629 CmsObject cms = getCmsObject(); 1630 CmsResource elementResource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1631 boolean hasWritePermissions = cms.hasPermissions( 1632 elementResource, 1633 CmsPermissionSet.ACCESS_WRITE, 1634 false, 1635 CmsResourceFilter.ALL); 1636 boolean isSystemResource = elementResource.getRootPath().startsWith(CmsResource.VFS_FOLDER_SYSTEM + "/"); 1637 CmsRelationFilter relationFilter = CmsRelationFilter.relationsToStructureId(structureId); 1638 List<CmsRelation> relationsToElement = cms.readRelations(relationFilter); 1639 Iterator<CmsRelation> iter = relationsToElement.iterator(); 1640 1641 // ignore XML_STRONG (i.e. container element) relations from the container page, this must be checked on the client side. 1642 while (iter.hasNext()) { 1643 CmsRelation relation = iter.next(); 1644 if ((containerpageId != null) 1645 && containerpageId.equals(relation.getSourceId()) 1646 && relation.getType().equals(CmsRelationType.XML_STRONG)) { 1647 iter.remove(); 1648 } 1649 } 1650 ElementDeleteMode elementDeleteMode = null; 1651 if (contextId != null) { 1652 CmsResource contextResource = cms.readResource(contextId, CmsResourceFilter.IGNORE_EXPIRATION); 1653 CmsADEConfigData adeConfig = OpenCms.getADEManager().lookupConfiguration( 1654 cms, 1655 contextResource.getRootPath()); 1656 CmsResourceTypeConfig typeConfig = adeConfig.getResourceType( 1657 OpenCms.getResourceManager().getResourceType(elementResource).getTypeName()); 1658 1659 if (typeConfig != null) { 1660 elementDeleteMode = typeConfig.getElementDeleteMode(); 1661 } 1662 } else { 1663 elementDeleteMode = ElementDeleteMode.askKeep; 1664 } 1665 boolean hasNoRelations = relationsToElement.isEmpty(); 1666 boolean deletionCandidate = hasNoRelations && hasWritePermissions && !isSystemResource; 1667 CmsListInfoBean elementInfo = CmsVfsService.getPageInfo(cms, elementResource); 1668 return new CmsRemovedElementStatus(structureId, elementInfo, deletionCandidate, elementDeleteMode); 1669 } 1670 1671 /** 1672 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#loadClipboardTab() 1673 */ 1674 public int loadClipboardTab() { 1675 1676 Integer clipboardTab = (Integer)(getRequest().getSession().getAttribute(ATTR_CLIPBOARD_TAB)); 1677 if (clipboardTab == null) { 1678 clipboardTab = Integer.valueOf(0); 1679 } 1680 return clipboardTab.intValue(); 1681 } 1682 1683 /** 1684 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#prefetch() 1685 */ 1686 public CmsCntPageData prefetch() throws CmsRpcException { 1687 1688 CmsCntPageData data = null; 1689 CmsObject cms = getCmsObject(); 1690 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1691 HttpServletRequest request = getRequest(); 1692 1693 try { 1694 Map<String, String> sessionStorageData = new HashMap<>(); 1695 CmsTemplateContextInfo info = OpenCms.getTemplateContextManager().getContextInfoBean(cms, request); 1696 CmsResource containerPage = getContainerpage(cms); 1697 Set<String> detailTypes = getDetailTypes(cms, containerPage); 1698 boolean isEditingModelGroup = isEditingModelGroups(cms, containerPage); 1699 boolean isModelPage = isModelPage(cms, containerPage); 1700 if (isModelPage) { 1701 // the model edit confirm dialog should only be shown once per session, disable it after first model editing 1702 getRequest().getSession().setAttribute( 1703 CmsVfsSitemapService.ATTR_SHOW_MODEL_EDIT_CONFIRM, 1704 Boolean.FALSE); 1705 } 1706 1707 TemplateBean templateBean = (TemplateBean)getRequest().getAttribute( 1708 CmsTemplateContextManager.ATTR_TEMPLATE_BEAN); 1709 CmsADESessionCache sessionCache = CmsADESessionCache.getCache(getRequest(), cms); 1710 sessionCache.setTemplateBean(containerPage.getRootPath(), templateBean); 1711 long lastModified = containerPage.getDateLastModified(); 1712 String editorUri = OpenCms.getWorkplaceManager().getEditorHandler().getEditorUri( 1713 cms, 1714 CmsResourceTypeXmlContent.getStaticTypeName(), 1715 "User agent", 1716 false); 1717 boolean useClassicEditor = (editorUri == null) || !editorUri.contains("acacia"); 1718 CmsResource detailResource = CmsDetailPageResourceHandler.getDetailResource(request); 1719 String noEditReason; 1720 String detailContainerPage = null; 1721 CmsQuickLaunchLocationCache locationCache = CmsQuickLaunchLocationCache.getLocationCache( 1722 request.getSession()); 1723 CmsUUID detailContainerPageId = null; 1724 if (detailResource != null) { 1725 locationCache.setPageEditorResource(cms, cms.getRequestContext().getSiteRoot(), detailResource); 1726 CmsObject rootCms = OpenCms.initCmsObject(cms); 1727 rootCms.getRequestContext().setSiteRoot(""); 1728 String detailResourcePath = detailResource.getRootPath(); 1729 String locale = cms.getRequestContext().getLocale().toString(); 1730 detailContainerPage = CmsDetailOnlyContainerUtil.getDetailOnlyPageName( 1731 cms, 1732 containerPage, 1733 detailResourcePath, 1734 locale); 1735 1736 if (rootCms.existsResource(detailContainerPage, CmsResourceFilter.IGNORE_EXPIRATION)) { 1737 detailContainerPageId = rootCms.readResource( 1738 detailContainerPage, 1739 CmsResourceFilter.IGNORE_EXPIRATION).getStructureId(); 1740 noEditReason = getNoEditReason( 1741 rootCms, 1742 rootCms.readResource(detailContainerPage, CmsResourceFilter.IGNORE_EXPIRATION)); 1743 } else { 1744 String permissionFolder = CmsResource.getFolderPath(detailContainerPage); 1745 while (!rootCms.existsResource(permissionFolder, CmsResourceFilter.IGNORE_EXPIRATION)) { 1746 permissionFolder = CmsResource.getParentFolder(permissionFolder); 1747 } 1748 noEditReason = getNoEditReason( 1749 rootCms, 1750 rootCms.readResource(permissionFolder, CmsResourceFilter.IGNORE_EXPIRATION)); 1751 } 1752 } else { 1753 if (!isModelPage && !isEditingModelGroup) { 1754 locationCache.setPageEditorResource(cms, cms.getRequestContext().getSiteRoot(), containerPage); 1755 sessionStorageData.put( 1756 CmsGwtConstants.LAST_CONTAINER_PAGE_ID, 1757 containerPage.getStructureId().toString()); 1758 } 1759 noEditReason = getNoEditReason(cms, containerPage); 1760 } 1761 1762 String sitemapPath = ""; 1763 boolean sitemapManager = OpenCms.getRoleManager().hasRole(cms, CmsRole.EDITOR); 1764 if (sitemapManager) { 1765 sitemapPath = CmsADEManager.PATH_SITEMAP_EDITOR_JSP; 1766 } 1767 CmsCntPageData.ElementReuseMode reuseMode = ElementReuseMode.reuse; 1768 String reuseModeString = getWorkplaceSettings().getUserSettings().getAdditionalPreference( 1769 "elementReuseMode", 1770 true); 1771 1772 try { 1773 reuseMode = ElementReuseMode.valueOf(reuseModeString); 1774 } catch (Exception e) { 1775 LOG.info("Invalid reuse mode : " + reuseModeString, e); 1776 } 1777 InitialElementViewProvider viewHelper = new InitialElementViewProvider(); 1778 viewHelper.init(getSessionCache().getElementView(), containerPage, info); 1779 CmsLocaleGroup group = cms.getLocaleGroupService().readLocaleGroup(containerPage); 1780 Locale mainLocale = null; 1781 1782 if (group.isRealGroup() && !cms.getRequestContext().getLocale().equals(group.getMainLocale())) { 1783 mainLocale = group.getMainLocale(); 1784 } 1785 CmsSiteManagerImpl siteManager = OpenCms.getSiteManager(); 1786 String ownRoot = siteManager.getSiteRoot(containerPage.getRootPath()); 1787 Map<String, CmsLocaleLinkBean> localeLinkBeans = null; 1788 if (group.isRealGroup()) { 1789 localeLinkBeans = Maps.newHashMap(); 1790 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1791 for (Map.Entry<Locale, CmsResource> entry : group.getResourcesByLocale().entrySet()) { 1792 String otherRoot = siteManager.getSiteRoot(entry.getValue().getRootPath()); 1793 if ((otherRoot != null) && otherRoot.equals(ownRoot)) { 1794 String theLink = OpenCms.getLinkManager().substituteLinkForUnknownTarget( 1795 cms, 1796 cms.getRequestContext().removeSiteRoot(entry.getValue().getRootPath())); 1797 localeLinkBeans.put(entry.getKey().getDisplayLanguage(locale), CmsLocaleLinkBean.link(theLink)); 1798 } else { 1799 localeLinkBeans.put( 1800 entry.getKey().getDisplayLanguage(locale), 1801 CmsLocaleLinkBean.error( 1802 Messages.get().getBundle(locale).key(Messages.GUI_SHOWLOCALE_WRONG_SITE_0))); 1803 } 1804 } 1805 } 1806 1807 String onlineLink = null; 1808 CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(cms.getRequestContext().getSiteRoot()); 1809 if ((site != null) && !OpenCms.getSiteManager().getWorkplaceServer().equals(site.getUrl())) { 1810 if (detailResource != null) { 1811 onlineLink = OpenCms.getLinkManager().getOnlineLink( 1812 cms, 1813 cms.getSitePath(detailResource), 1814 cms.getSitePath(containerPage), 1815 false); 1816 } else { 1817 onlineLink = OpenCms.getLinkManager().getOnlineLink(cms, cms.getSitePath(containerPage)); 1818 } 1819 } 1820 1821 String modelGroupElementId = null; 1822 if (isEditingModelGroup) { 1823 CmsProperty modelElementProp = cms.readPropertyObject( 1824 containerPage, 1825 CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS, 1826 false); 1827 if (!modelElementProp.isNullProperty() && CmsUUID.isValidUUID(modelElementProp.getValue())) { 1828 modelGroupElementId = modelElementProp.getValue(); 1829 } 1830 } 1831 String title = null; 1832 if (isModelPage || isEditingModelGroup) { 1833 title = Messages.get().getBundle(wpLocale).key(Messages.GUI_TITLE_MODEL_0); 1834 1835 } 1836 ElementDeleteMode deleteMode = OpenCms.getWorkplaceManager().getElementDeleteMode(); 1837 if (deleteMode == null) { 1838 deleteMode = ElementDeleteMode.askDelete; 1839 } 1840 CmsListInfoBean pageInfo = CmsVfsService.getPageInfo(cms, containerPage); 1841 data = new CmsCntPageData( 1842 onlineLink, 1843 noEditReason, 1844 CmsRequestUtil.encodeParams(request), 1845 sitemapPath, 1846 sitemapManager, 1847 detailResource != null ? detailResource.getStructureId() : null, 1848 detailContainerPage, 1849 detailContainerPageId, 1850 detailTypes, 1851 lastModified, 1852 getLockInfo(containerPage), 1853 pageInfo, 1854 cms.getRequestContext().getLocale().toString(), 1855 useClassicEditor, 1856 info, 1857 isEditSmallElements(request, cms), 1858 Lists.newArrayList(viewHelper.getViewMap().values()), 1859 viewHelper.getDefaultView(), 1860 reuseMode, 1861 deleteMode, 1862 isModelPage, 1863 isEditingModelGroup, 1864 modelGroupElementId, 1865 mainLocale != null ? mainLocale.toString() : null, 1866 localeLinkBeans, 1867 title, 1868 System.currentTimeMillis()); 1869 boolean allowSettingsInEditor = true; 1870 CmsModule baseModule = OpenCms.getModuleManager().getModule("org.opencms.base"); 1871 if (baseModule != null) { 1872 String param = baseModule.getParameter("allowSettingsInEditor"); 1873 allowSettingsInEditor = CmsStringUtil.isEmptyOrWhitespaceOnly(param) 1874 || Boolean.valueOf(param).booleanValue(); 1875 } 1876 data.setAllowSettingsInEditor(allowSettingsInEditor); 1877 String placementModeEnabledStr = (String)OpenCms.getRuntimeProperty( 1878 PARAM_PAGE_EDITOR_PLACEMENT_MODE_ENABLED); 1879 boolean placementModeEnabled = (placementModeEnabledStr == null) 1880 || Boolean.parseBoolean(placementModeEnabledStr); 1881 data.setPlacementModeEnabled(placementModeEnabled); 1882 data.setSessionStorageData(sessionStorageData); 1883 } catch (Throwable e) { 1884 error(e); 1885 } 1886 return data; 1887 } 1888 1889 /** 1890 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#prepareForEdit(java.lang.String, java.lang.String, org.opencms.util.CmsUUID, java.lang.String) 1891 */ 1892 public CmsUUID prepareForEdit(String clientId, String editOption, CmsUUID pageId, String requestParams) 1893 throws CmsRpcException { 1894 1895 try { 1896 CmsResource pageResource = getCmsObject().readResource( 1897 pageId, 1898 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1899 CmsContainerElementBean element = getCachedElement(clientId, pageResource.getRootPath()); 1900 element.initResource(getCmsObject()); 1901 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 1902 if (type instanceof CmsResourceTypeXmlContent) { 1903 I_CmsEditHandler handler = ((CmsResourceTypeXmlContent)type).getEditHandler(getCmsObject()); 1904 Map<String, String[]> params = CmsRequestUtil.createParameterMap( 1905 CmsEncoder.decode(requestParams), 1906 true, 1907 CmsEncoder.ENCODING_UTF_8); 1908 return handler.prepareForEdit(getCmsObject(), element, editOption, pageId, params); 1909 } 1910 } catch (CmsException e) { 1911 error(e); 1912 } 1913 return null; 1914 } 1915 1916 /** 1917 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#replaceElement(org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext, org.opencms.util.CmsUUID, java.lang.String, java.lang.String, java.lang.String, java.util.Collection, java.lang.String) 1918 */ 1919 public CmsContainerElementData replaceElement( 1920 CmsContainerPageRpcContext context, 1921 CmsUUID detailContentId, 1922 String reqParams, 1923 String clientId, 1924 String replaceId, 1925 Collection<CmsContainer> containers, 1926 String locale) 1927 throws CmsRpcException { 1928 1929 CmsContainerElementData element = null; 1930 try { 1931 ensureSession(); 1932 CmsObject cms = getCmsObject(); 1933 CmsResource pageResource = cms.readResource( 1934 context.getPageStructureId(), 1935 CmsResourceFilter.ignoreExpirationOffline(cms)); 1936 initRequestFromRpcContext(context); 1937 String containerpageUri = cms.getSitePath(pageResource); 1938 Locale contentLocale = CmsLocaleManager.getLocale(locale); 1939 CmsElementUtil elemUtil = new CmsElementUtil( 1940 cms, 1941 containerpageUri, 1942 generateContainerPageForContainers(containers, pageResource.getRootPath()), 1943 detailContentId, 1944 getRequest(), 1945 getResponse(), 1946 false, 1947 contentLocale); 1948 1949 CmsContainerElementBean elementBean = getCachedElement(clientId, pageResource.getRootPath()); 1950 Map<String, String> settings = new HashMap<String, String>(elementBean.getIndividualSettings()); 1951 settings.remove(CmsContainerElement.ELEMENT_INSTANCE_ID); 1952 CmsContainerElementBean replaceBean = new CmsContainerElementBean( 1953 new CmsUUID(replaceId), 1954 elementBean.getFormatterId(), 1955 settings, 1956 elementBean.isCreateNew()); 1957 getSessionCache().setCacheContainerElement(replaceBean.editorHash(), replaceBean); 1958 element = elemUtil.getElementData(pageResource, replaceBean, containers); 1959 } catch (Throwable e) { 1960 error(e); 1961 } 1962 return element; 1963 } 1964 1965 /** 1966 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveClipboardTab(int) 1967 */ 1968 public void saveClipboardTab(int tabIndex) { 1969 1970 getRequest().getSession().setAttribute(ATTR_CLIPBOARD_TAB, Integer.valueOf(tabIndex)); 1971 } 1972 1973 /** 1974 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveContainerpage(org.opencms.util.CmsUUID, java.util.List) 1975 */ 1976 public CmsPageSaveStatus saveContainerpage(CmsUUID pageStructureId, List<CmsContainer> containers) 1977 throws CmsRpcException { 1978 1979 CmsObject cms = getCmsObject(); 1980 try { 1981 ensureSession(); 1982 CmsResource containerpage = cms.readResource( 1983 pageStructureId, 1984 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1985 ensureLock(containerpage); 1986 String containerpageUri = cms.getSitePath(containerpage); 1987 saveContainers(cms, containerpage, containerpageUri, containers); 1988 } catch (Throwable e) { 1989 error(e); 1990 } 1991 return new CmsPageSaveStatus(pageStructureId, System.currentTimeMillis()); 1992 } 1993 1994 /** 1995 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveDetailContainers(org.opencms.util.CmsUUID, java.lang.String, java.util.List) 1996 */ 1997 public CmsPageSaveStatus saveDetailContainers( 1998 CmsUUID detailId, 1999 String detailContainerResource, 2000 List<CmsContainer> containers) 2001 throws CmsRpcException { 2002 2003 CmsObject cms = getCmsObject(); 2004 CmsUUID id = null; 2005 try { 2006 ensureSession(); 2007 CmsObject rootCms = OpenCms.initCmsObject(cms); 2008 rootCms.getRequestContext().setSiteRoot(""); 2009 CmsResource containerpage; 2010 containerpage = CmsDetailOnlyContainerUtil.readOrCreateDetailOnlyPage( 2011 rootCms, 2012 detailId, 2013 detailContainerResource); 2014 id = containerpage.getStructureId(); 2015 saveContainers(rootCms, containerpage, detailContainerResource, containers); 2016 } catch (Throwable e) { 2017 error(e); 2018 } 2019 return new CmsPageSaveStatus(id, System.currentTimeMillis()); 2020 } 2021 2022 /** 2023 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveElementSettings(org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext, org.opencms.util.CmsUUID, java.lang.String, java.lang.String, java.util.Map, java.util.List, java.lang.String) 2024 */ 2025 public CmsContainerElementData saveElementSettings( 2026 CmsContainerPageRpcContext context, 2027 CmsUUID detailContentId, 2028 String reqParams, 2029 String clientId, 2030 Map<String, String> settings, 2031 List<CmsContainer> containers, 2032 String locale) 2033 throws CmsRpcException { 2034 2035 CmsContainerElementData element = null; 2036 try { 2037 ensureSession(); 2038 CmsObject cms = getCmsObject(); 2039 CmsResource pageResource = cms.readResource( 2040 context.getPageStructureId(), 2041 CmsResourceFilter.ignoreExpirationOffline(cms)); 2042 initRequestFromRpcContext(context); 2043 Locale contentLocale = CmsLocaleManager.getLocale(locale); 2044 CmsContainerElementBean elementBean = getCachedElement(clientId, pageResource.getRootPath()); 2045 elementBean.initResource(cms); 2046 storeFormatterSelection(elementBean, settings); 2047 // make sure to keep the element instance id 2048 if (!settings.containsKey(CmsContainerElement.ELEMENT_INSTANCE_ID) 2049 && elementBean.getIndividualSettings().containsKey(CmsContainerElement.ELEMENT_INSTANCE_ID)) { 2050 settings.put( 2051 CmsContainerElement.ELEMENT_INSTANCE_ID, 2052 elementBean.getIndividualSettings().get(CmsContainerElement.ELEMENT_INSTANCE_ID)); 2053 } 2054 if (elementBean.getIndividualSettings().containsKey(CmsContainerElement.SETTING_PAGE_ID)) { 2055 settings.put( 2056 CmsContainerElement.SETTING_PAGE_ID, 2057 elementBean.getIndividualSettings().get(CmsContainerElement.SETTING_PAGE_ID)); 2058 } 2059 if (!isEditingModelGroups(cms, pageResource)) { 2060 // in case of model group state set to 'noGroup', the group will be dissolved and former group id forgotten 2061 if (!(settings.containsKey(CmsContainerElement.MODEL_GROUP_STATE) 2062 && (ModelGroupState.noGroup == ModelGroupState.evaluate( 2063 settings.get(CmsContainerElement.MODEL_GROUP_STATE))))) { 2064 if (elementBean.getIndividualSettings().containsKey(CmsContainerElement.MODEL_GROUP_ID)) { 2065 // make sure to keep the model group id 2066 settings.put( 2067 CmsContainerElement.MODEL_GROUP_ID, 2068 elementBean.getIndividualSettings().get(CmsContainerElement.MODEL_GROUP_ID)); 2069 } 2070 if (elementBean.getIndividualSettings().containsKey(CmsContainerElement.MODEL_GROUP_STATE)) { 2071 settings.put( 2072 CmsContainerElement.MODEL_GROUP_STATE, 2073 elementBean.getIndividualSettings().get(CmsContainerElement.MODEL_GROUP_STATE)); 2074 } 2075 } 2076 } 2077 elementBean = CmsContainerElementBean.cloneWithSettings( 2078 elementBean, 2079 convertSettingValues(elementBean.getResource(), settings, contentLocale)); 2080 getSessionCache().setCacheContainerElement(elementBean.editorHash(), elementBean); 2081 2082 // update client id within container data 2083 for (CmsContainer container : containers) { 2084 for (CmsContainerElement child : container.getElements()) { 2085 if (child.getClientId().equals(clientId)) { 2086 child.setClientId(elementBean.editorHash()); 2087 } 2088 } 2089 } 2090 if (detailContentId == null) { 2091 saveContainers(cms, pageResource, cms.getSitePath(pageResource), containers); 2092 } else { 2093 List<CmsContainer> detailContainers = new ArrayList<CmsContainer>(); 2094 for (CmsContainer container : containers) { 2095 if (container.isDetailOnly()) { 2096 detailContainers.add(container); 2097 } 2098 } 2099 CmsObject rootCms = OpenCms.initCmsObject(cms); 2100 rootCms.getRequestContext().setSiteRoot(""); 2101 CmsResource detailResource = rootCms.readResource(detailContentId, CmsResourceFilter.IGNORE_EXPIRATION); 2102 String detailRootPath = detailResource.getRootPath(); 2103 CmsResource detailContainerPage = rootCms.readResource( 2104 CmsDetailOnlyContainerUtil.getDetailOnlyPageName(cms, pageResource, detailRootPath, locale)); 2105 2106 ensureLock(detailContainerPage); 2107 saveContainers(rootCms, detailContainerPage, detailContainerPage.getRootPath(), detailContainers); 2108 } 2109 String containerpageUri = cms.getSitePath(pageResource); 2110 CmsElementUtil elemUtil = new CmsElementUtil( 2111 cms, 2112 containerpageUri, 2113 generateContainerPageForContainers(containers, pageResource.getRootPath()), 2114 detailContentId, 2115 getRequest(), 2116 getResponse(), 2117 false, 2118 contentLocale); 2119 element = elemUtil.getElementData(pageResource, elementBean, containers); 2120 } catch (Throwable e) { 2121 error(e); 2122 } 2123 return element; 2124 } 2125 2126 /** 2127 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveFavoriteList(java.util.List, java.lang.String) 2128 */ 2129 public void saveFavoriteList(List<String> clientIds, String uri) throws CmsRpcException { 2130 2131 try { 2132 ensureSession(); 2133 OpenCms.getADEManager().saveFavoriteList( 2134 getCmsObject(), 2135 getCachedElements(clientIds, getCmsObject().getRequestContext().addSiteRoot(uri))); 2136 } catch (Throwable e) { 2137 error(e); 2138 } 2139 } 2140 2141 /** 2142 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveGroupContainer(org.opencms.ade.containerpage.shared.CmsContainerPageRpcContext, org.opencms.util.CmsUUID, java.lang.String, org.opencms.ade.containerpage.shared.CmsGroupContainer, java.util.Collection, java.lang.String) 2143 */ 2144 public CmsGroupContainerSaveResult saveGroupContainer( 2145 CmsContainerPageRpcContext context, 2146 2147 CmsUUID detailContentId, 2148 String reqParams, 2149 CmsGroupContainer groupContainer, 2150 Collection<CmsContainer> containers, 2151 String locale) 2152 throws CmsRpcException { 2153 2154 CmsObject cms = getCmsObject(); 2155 List<CmsRemovedElementStatus> removedElements = null; 2156 try { 2157 CmsPair<CmsContainerElement, List<CmsRemovedElementStatus>> saveResult = internalSaveGroupContainer( 2158 cms, 2159 context.getPageStructureId(), 2160 groupContainer); 2161 removedElements = saveResult.getSecond(); 2162 } catch (Throwable e) { 2163 error(e); 2164 } 2165 Collection<String> ids = new ArrayList<String>(); 2166 ids.add(groupContainer.getClientId()); 2167 // update offline indices 2168 OpenCms.getSearchManager().updateOfflineIndexes(); 2169 return new CmsGroupContainerSaveResult( 2170 getElementsData(context, detailContentId, reqParams, ids, containers, false, null, locale), 2171 removedElements); 2172 } 2173 2174 /** 2175 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveInheritanceContainer(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, org.opencms.ade.containerpage.shared.CmsInheritanceContainer, java.util.Collection, java.lang.String) 2176 */ 2177 public Map<String, CmsContainerElementData> saveInheritanceContainer( 2178 CmsUUID pageStructureId, 2179 CmsUUID detailContentId, 2180 CmsInheritanceContainer inheritanceContainer, 2181 Collection<CmsContainer> containers, 2182 String locale) 2183 throws CmsRpcException { 2184 2185 try { 2186 CmsObject cms = getCmsObject(); 2187 CmsADEConfigData rpcConfig = OpenCms.getADEManager().lookupConfiguration( 2188 cms, 2189 cms.getRequestContext().getRootUri()); 2190 CmsResource containerPage = cms.readResource( 2191 pageStructureId, 2192 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 2193 String sitePath = cms.getSitePath(containerPage); 2194 Locale requestedLocale = CmsLocaleManager.getLocale(locale); 2195 CmsResource referenceResource = null; 2196 if (inheritanceContainer.isNew()) { 2197 CmsADEConfigData config = getConfigData(containerPage.getRootPath()); 2198 CmsResourceTypeConfig typeConfig = config.getResourceType( 2199 CmsResourceTypeXmlContainerPage.INHERIT_CONTAINER_TYPE_NAME); 2200 referenceResource = typeConfig.createNewElement(cms, containerPage.getRootPath()); 2201 inheritanceContainer.setClientId(referenceResource.getStructureId().toString()); 2202 } 2203 if (referenceResource == null) { 2204 CmsUUID id = convertToServerId(inheritanceContainer.getClientId()); 2205 referenceResource = cms.readResource(id, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 2206 } 2207 ensureLock(referenceResource); 2208 saveInheritanceGroup(referenceResource, inheritanceContainer); 2209 tryUnlock(referenceResource); 2210 List<CmsContainerElementBean> elements = new ArrayList<CmsContainerElementBean>(); 2211 for (CmsContainerElement clientElement : inheritanceContainer.getElements()) { 2212 CmsContainerElementBean elementBean = getCachedElement( 2213 clientElement.getClientId(), 2214 containerPage.getRootPath()); 2215 elementBean = CmsContainerElementBean.cloneWithSettings( 2216 elementBean, 2217 elementBean.getIndividualSettings()); 2218 CmsInheritanceInfo inheritanceInfo = clientElement.getInheritanceInfo(); 2219 // if a local elements misses the key it was newly added 2220 if (inheritanceInfo.isNew() && CmsStringUtil.isEmptyOrWhitespaceOnly(inheritanceInfo.getKey())) { 2221 // generating new key 2222 inheritanceInfo.setKey(CmsResource.getFolderPath(sitePath) + new CmsUUID().toString()); 2223 } 2224 elementBean.setInheritanceInfo(inheritanceInfo); 2225 elements.add(elementBean); 2226 } 2227 cms.getRequestContext().setLocale(requestedLocale); 2228 if (inheritanceContainer.getElementsChanged()) { 2229 OpenCms.getADEManager().saveInheritedContainer( 2230 cms, 2231 containerPage, 2232 inheritanceContainer.getName(), 2233 true, 2234 elements); 2235 } 2236 return getElements( 2237 rpcConfig, 2238 containerPage, 2239 new ArrayList<String>(Collections.singletonList(inheritanceContainer.getClientId())), 2240 sitePath, 2241 detailContentId, 2242 containers, 2243 false, 2244 null, 2245 false, 2246 requestedLocale); 2247 } catch (Exception e) { 2248 error(e); 2249 } 2250 return null; 2251 } 2252 2253 /** 2254 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveRecentList(java.util.List, java.lang.String) 2255 */ 2256 public void saveRecentList(List<String> clientIds, String uri) throws CmsRpcException { 2257 2258 try { 2259 ensureSession(); 2260 OpenCms.getADEManager().saveRecentList( 2261 getCmsObject(), 2262 getCachedElements(clientIds, getCmsObject().getRequestContext().addSiteRoot(uri))); 2263 } catch (Throwable e) { 2264 error(e); 2265 } 2266 } 2267 2268 /** 2269 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#setEditSmallElements(boolean) 2270 */ 2271 public void setEditSmallElements(boolean editSmallElements) throws CmsRpcException { 2272 2273 try { 2274 CmsObject cms = getCmsObject(); 2275 CmsUser user = cms.getRequestContext().getCurrentUser(); 2276 user.getAdditionalInfo().put(ADDINFO_EDIT_SMALL_ELEMENTS, "" + editSmallElements); 2277 cms.writeUser(user); 2278 } catch (Throwable t) { 2279 error(t); 2280 } 2281 } 2282 2283 /** 2284 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#setElementView(org.opencms.util.CmsUUID) 2285 */ 2286 public void setElementView(CmsUUID elementView) { 2287 2288 getSessionCache().setElementView(elementView); 2289 } 2290 2291 /** 2292 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#setLastPage(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID) 2293 */ 2294 public void setLastPage(CmsUUID pageId, CmsUUID detailId) throws CmsRpcException { 2295 2296 try { 2297 HttpServletRequest req = getRequest(); 2298 CmsObject cms = getCmsObject(); 2299 CmsADESessionCache cache = CmsADESessionCache.getCache(req, cms); 2300 cache.setLastPage(cms, pageId, detailId); 2301 } catch (Exception e) { 2302 error(e); 2303 } 2304 2305 } 2306 2307 /** 2308 * Sets the session cache.<p> 2309 * 2310 * @param cache the session cache 2311 */ 2312 public void setSessionCache(CmsADESessionCache cache) { 2313 2314 m_sessionCache = cache; 2315 } 2316 2317 /** 2318 * Helper method for collecting the type information for the galleries in the container page editor. 2319 * 2320 * 2321 * @param cms the CMS context 2322 * @param containers the page containers 2323 * @param elementView the element view 2324 * @param uri the page URI 2325 * @param detailContentId the detail content id 2326 * @param locale the content locale 2327 * @param contextInfo the template context information 2328 * 2329 * @return the type beans 2330 * 2331 * @throws CmsRpcException in case something goes wrong 2332 */ 2333 protected List<CmsResourceTypeBean> getGalleryTypesForView( 2334 CmsObject cms, 2335 final List<CmsContainer> containers, 2336 CmsUUID elementView, 2337 String uri, 2338 CmsUUID detailContentId, 2339 String locale, 2340 CmsTemplateContextInfo templateContextInfo) 2341 throws CmsException { 2342 2343 String pageFolderRootPath = cms.getRequestContext().addSiteRoot(uri); 2344 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(cms, pageFolderRootPath); 2345 Map<String, CmsResourceTypeConfig> typesByName = config.getTypesByName(); 2346 final String templateContextStr = (templateContextInfo != null) 2347 && (templateContextInfo.getCurrentContext() != null) ? templateContextInfo.getCurrentContext() : null; 2348 CmsAddDialogTypeHelper typeHelper = new CmsAddDialogTypeHelper(CmsResourceTypeConfig.AddMenuType.ade) { 2349 2350 @Override 2351 protected boolean exclude(CmsResourceTypeBean type) { 2352 2353 CmsResourceTypeConfig typeConfig = typesByName.get(type.getType()); 2354 if ((typeConfig != null) 2355 && (templateContextStr != null) 2356 && !typeConfig.isAvailableInTemplate(templateContextStr)) { 2357 return true; 2358 } 2359 return false; 2360 2361 } 2362 }; 2363 if (detailContentId != null) { 2364 try { 2365 CmsResource page = cms.readResource(uri, CmsResourceFilter.IGNORE_EXPIRATION); 2366 CmsResource detailContent = cms.readResource(detailContentId, CmsResourceFilter.IGNORE_EXPIRATION); 2367 pageFolderRootPath = CmsResource.getParentFolder( 2368 CmsDetailOnlyContainerUtil.getDetailOnlyPageName( 2369 cms, 2370 page, 2371 detailContent.getRootPath(), 2372 "" + locale)); 2373 } catch (Exception e) { 2374 LOG.error(e.getLocalizedMessage(), e); 2375 } 2376 } 2377 List<CmsResourceTypeBean> resTypeBeans = typeHelper.getResourceTypes( 2378 cms, 2379 cms.getRequestContext().addSiteRoot(uri), 2380 pageFolderRootPath, 2381 uri, 2382 OpenCms.getADEManager().getElementViews(cms).get(elementView), 2383 new I_CmsResourceTypeEnabledCheck() { 2384 2385 public boolean checkEnabled(CmsObject paramCms, CmsADEConfigData config2, I_CmsResourceType resType) { 2386 2387 boolean isModelGroup = CmsResourceTypeXmlContainerPage.MODEL_GROUP_TYPE_NAME.equals( 2388 resType.getTypeName()); 2389 return isModelGroup || config2.hasFormatters(paramCms, resType, containers); 2390 } 2391 }); 2392 return resTypeBeans; 2393 } 2394 2395 /** 2396 * Gets the settings which should be updated for an element in the DND case.<p> 2397 * 2398 * @param config the sitemap configuration 2399 * @param originalSettings the original settings 2400 * @param formatterConfig the formatter configuration for the element 2401 * @param containers the containers 2402 * @param dndContainer the id of the DND origin container 2403 * 2404 * @return the map of settings to update 2405 */ 2406 Map<String, String> getSettingsToChangeForDnd( 2407 CmsADEConfigData config, 2408 Map<String, String> originalSettings, 2409 CmsFormatterConfiguration formatterConfig, 2410 Collection<CmsContainer> containers, 2411 String dndContainer) { 2412 2413 Map<String, String> result = Maps.newHashMap(); 2414 2415 if (dndContainer == null) { 2416 return result; 2417 } 2418 String key = CmsFormatterConfig.getSettingsKeyForContainer(dndContainer); 2419 String formatterId = originalSettings.get(key); 2420 if (formatterId == null) { 2421 return result; 2422 } 2423 for (CmsContainer container : containers) { 2424 if (container.getName().equals(dndContainer)) { 2425 continue; 2426 } 2427 2428 Map<String, I_CmsFormatterBean> formatterSelection = formatterConfig.getFormatterSelection( 2429 container.getType(), 2430 container.getWidth()); 2431 I_CmsFormatterBean currentBean = config.findFormatter(formatterId); 2432 if (currentBean != null) { 2433 if (CmsFormatterConfiguration.matchFormatter(currentBean, container.getType(), container.getWidth())) { 2434 String newKey = CmsFormatterConfig.getSettingsKeyForContainer(container.getName()); 2435 result.put(newKey, currentBean.getKeyOrId()); 2436 } 2437 } else if (formatterSelection.containsKey(formatterId)) { 2438 // for backwards compatibility with schema-configured formatters 2439 String newKey = CmsFormatterConfig.getSettingsKeyForContainer(container.getName()); 2440 result.put(newKey, formatterId); 2441 } 2442 } 2443 return result; 2444 } 2445 2446 /** 2447 * Creates a new container element bean from an existing one, but changes some of the individual settings in the copy.<p> 2448 * 2449 * @param element the original container element 2450 * @param settingsToOverride the map of settings to change 2451 * 2452 * @return the new container element bean with the changed settings 2453 */ 2454 CmsContainerElementBean overrideSettings(CmsContainerElementBean element, Map<String, String> settingsToOverride) { 2455 2456 Map<String, String> settings = Maps.newHashMap(element.getIndividualSettings()); 2457 settings.putAll(settingsToOverride); 2458 CmsContainerElementBean result = new CmsContainerElementBean( 2459 element.getId(), 2460 element.getFormatterId(), 2461 settings, 2462 element.isCreateNew()); 2463 return result; 2464 } 2465 2466 /** 2467 * Adds the formatter to the recently used formatter list.<p> 2468 * 2469 * @param elementBean the element bean 2470 * @param settings the changed settings 2471 */ 2472 void storeFormatterSelection(CmsContainerElementBean elementBean, Map<String, String> settings) { 2473 2474 Entry<String, String> previousFormatterEntry = null; 2475 for (Entry<String, String> entry : elementBean.getIndividualSettings().entrySet()) { 2476 if (entry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY)) { 2477 previousFormatterEntry = entry; 2478 break; 2479 } 2480 } 2481 Entry<String, String> formatterEntry = null; 2482 for (Entry<String, String> entry : settings.entrySet()) { 2483 if (entry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY)) { 2484 formatterEntry = entry; 2485 break; 2486 } 2487 } 2488 if ((formatterEntry != null) 2489 && ((previousFormatterEntry == null) 2490 || !formatterEntry.getKey().equals(previousFormatterEntry.getKey()) 2491 || !formatterEntry.getValue().equals(previousFormatterEntry.getValue()))) { 2492 String idString = formatterEntry.getValue(); 2493 if (idString != null) { 2494 // the formatter setting has changed 2495 I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(elementBean.getResource()); 2496 if (!(resType instanceof CmsResourceTypeFunctionConfig)) { 2497 getSessionCache().addRecentFormatter(resType.getTypeName(), idString); 2498 } 2499 } 2500 } 2501 } 2502 2503 /** 2504 * Converts the given setting values according to the setting configuration of the given resource.<p> 2505 * 2506 * @param resource the resource 2507 * @param settings the settings to convert 2508 * @param locale the locale used for accessing the element settings 2509 * 2510 * @return the converted settings 2511 * @throws CmsException if something goes wrong 2512 */ 2513 private Map<String, String> convertSettingValues(CmsResource resource, Map<String, String> settings, Locale locale) 2514 throws CmsException { 2515 2516 CmsObject cms = getCmsObject(); 2517 Locale origLocale = cms.getRequestContext().getLocale(); 2518 try { 2519 cms.getRequestContext().setLocale(locale); 2520 Map<String, CmsXmlContentProperty> settingsConf = OpenCms.getADEManager().getElementSettings(cms, resource); 2521 Map<String, String> changedSettings = new HashMap<String, String>(); 2522 if (settings != null) { 2523 for (Map.Entry<String, String> entry : settings.entrySet()) { 2524 String settingName = entry.getKey(); 2525 String settingType = "string"; 2526 if (settingsConf.get(settingName) != null) { 2527 settingType = settingsConf.get(settingName).getType(); 2528 } 2529 changedSettings.put( 2530 settingName, 2531 CmsXmlContentPropertyHelper.getPropValueIds(getCmsObject(), settingType, entry.getValue())); 2532 } 2533 } 2534 return changedSettings; 2535 } finally { 2536 cms.getRequestContext().setLocale(origLocale); 2537 } 2538 } 2539 2540 /** 2541 * Generates the XML container page bean for the given containers.<p> 2542 * 2543 * @param containers the containers 2544 * @param containerpageRootPath the container page root path 2545 * 2546 * @return the container page bean 2547 * @throws CmsException in case generating the page data fails 2548 */ 2549 private CmsContainerPageBean generateContainerPageForContainers( 2550 Collection<CmsContainer> containers, 2551 String containerpageRootPath) 2552 throws CmsException { 2553 2554 List<CmsContainerBean> containerBeans = new ArrayList<CmsContainerBean>(); 2555 for (CmsContainer container : containers) { 2556 CmsContainerBean containerBean = getContainerBeanToSave(container, containerpageRootPath); 2557 containerBeans.add(containerBean); 2558 } 2559 CmsContainerPageBean page = new CmsContainerPageBean(containerBeans); 2560 return page; 2561 } 2562 2563 /** 2564 * Returns a list of container elements from a list with client id's.<p> 2565 * 2566 * @param clientIds list of client id's 2567 * @param pageRootPath the container page root path 2568 * 2569 * @return a list of element beans 2570 * @throws CmsException in case reading the element resource fails 2571 */ 2572 private List<CmsContainerElementBean> getCachedElements(List<String> clientIds, String pageRootPath) 2573 throws CmsException { 2574 2575 List<CmsContainerElementBean> result = new ArrayList<CmsContainerElementBean>(); 2576 for (String id : clientIds) { 2577 try { 2578 result.add(getCachedElement(id, pageRootPath)); 2579 } catch (CmsIllegalArgumentException e) { 2580 log(e.getLocalizedMessage(), e); 2581 } 2582 } 2583 return result; 2584 } 2585 2586 /** 2587 * Returns the configuration data of the current container page context.<p> 2588 * 2589 * @param pageRootPath the container page root path 2590 * 2591 * @return the configuration data of the current container page context 2592 */ 2593 private CmsADEConfigData getConfigData(String pageRootPath) { 2594 2595 if (m_configData == null) { 2596 m_configData = OpenCms.getADEManager().lookupConfiguration(getCmsObject(), pageRootPath); 2597 } 2598 return m_configData; 2599 } 2600 2601 /** 2602 * Helper method for converting a CmsContainer to a CmsContainerBean when saving a container page.<p> 2603 * 2604 * @param container the container for which the CmsContainerBean should be created 2605 * @param containerpageRootPath the container page root path 2606 * 2607 * @return a container bean 2608 * 2609 * @throws CmsException in case generating the container data fails 2610 */ 2611 private CmsContainerBean getContainerBeanToSave(CmsContainer container, String containerpageRootPath) 2612 throws CmsException { 2613 2614 CmsObject cms = getCmsObject(); 2615 List<CmsContainerElementBean> elements = new ArrayList<CmsContainerElementBean>(); 2616 for (CmsContainerElement elementData : container.getElements()) { 2617 if (!elementData.isNew()) { 2618 CmsContainerElementBean newElementBean = getContainerElementBeanToSave( 2619 cms, 2620 containerpageRootPath, 2621 container, 2622 elementData); 2623 if (newElementBean != null) { 2624 elements.add(newElementBean); 2625 } 2626 } 2627 } 2628 CmsContainerBean result = CmsElementUtil.clientToServerContainer(container, elements); 2629 return result; 2630 } 2631 2632 /** 2633 * Converts container page element data to a bean which can be saved in a container page.<p> 2634 * 2635 * @param cms the current CMS context 2636 * @param containerpageRootPath the container page root path 2637 * @param container the container containing the element 2638 * @param elementData the data for the single element 2639 * 2640 * @return the container element bean 2641 * 2642 * @throws CmsException if something goes wrong 2643 */ 2644 private CmsContainerElementBean getContainerElementBeanToSave( 2645 CmsObject cms, 2646 String containerpageRootPath, 2647 CmsContainer container, 2648 CmsContainerElement elementData) 2649 throws CmsException { 2650 2651 String elementClientId = elementData.getClientId(); 2652 boolean hasUuidPrefix = (elementClientId != null) && elementClientId.matches(CmsUUID.UUID_REGEX + ".*$"); 2653 boolean isCreateNew = elementData.isCreateNew(); 2654 if (elementData.isNew() && !hasUuidPrefix) { 2655 2656 // Due to the changed save system without the save button, we need to make sure that new elements 2657 // are only created once. This must happen when the user first edits a new element. But we still 2658 // want to save changes to non-new elements on the page, so we skip new elements while saving. 2659 return null; 2660 } 2661 CmsContainerElementBean element = getCachedElement(elementData.getClientId(), containerpageRootPath); 2662 2663 CmsResource resource; 2664 if (element.getResource() == null) { 2665 element.initResource(cms); 2666 resource = element.getResource(); 2667 } else { 2668 // make sure resource is readable, this is necessary for new content elements 2669 if (element.getId().isNullUUID()) { 2670 // in memory only element, can not be read nor saved 2671 return null; 2672 } 2673 resource = cms.readResource(element.getId(), CmsResourceFilter.IGNORE_EXPIRATION); 2674 } 2675 2676 // check if there is a valid formatter 2677 int containerWidth = container.getWidth(); 2678 CmsADEConfigData config = getConfigData(containerpageRootPath); 2679 CmsFormatterConfiguration formatters = config.getFormatters(cms, resource); 2680 String containerType = null; 2681 containerType = container.getType(); 2682 I_CmsFormatterBean formatter = null; 2683 String formatterConfigId = null; 2684 formatterConfigId = element.getFormatterKey(container.getName()); 2685 if (formatterConfigId != null) { 2686 I_CmsFormatterBean dynamicFmt = config.findFormatter(formatterConfigId); 2687 if (dynamicFmt != null) { 2688 formatter = dynamicFmt; 2689 } else if (formatterConfigId.startsWith(CmsFormatterConfig.SCHEMA_FORMATTER_ID) 2690 && CmsUUID.isValidUUID(formatterConfigId.substring(CmsFormatterConfig.SCHEMA_FORMATTER_ID.length()))) { 2691 formatter = formatters.getFormatterSelection(containerType, containerWidth).get(formatterConfigId); 2692 } 2693 } 2694 if (formatter == null) { 2695 formatter = CmsElementUtil.getFormatterForContainer(cms, element, container, config, getSessionCache()); 2696 if (formatter != null) { 2697 formatterConfigId = formatter.isFromFormatterConfigFile() 2698 ? formatter.getId() 2699 : CmsFormatterConfig.SCHEMA_FORMATTER_ID + formatter.getJspStructureId().toString(); 2700 } 2701 } 2702 CmsContainerElementBean newElementBean = null; 2703 if (formatter != null) { 2704 Map<String, String> settings = new HashMap<String, String>(element.getIndividualSettings()); 2705 String formatterKey = CmsFormatterConfig.getSettingsKeyForContainer(container.getName()); 2706 settings.put(formatterKey, formatterConfigId); 2707 // remove not used formatter settings 2708 Iterator<Entry<String, String>> entries = settings.entrySet().iterator(); 2709 while (entries.hasNext()) { 2710 Entry<String, String> entry = entries.next(); 2711 if (entry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY) 2712 && !entry.getKey().equals(formatterKey)) { 2713 entries.remove(); 2714 } 2715 } 2716 2717 newElementBean = new CmsContainerElementBean( 2718 element.getId(), 2719 formatter.getJspStructureId(), 2720 settings, 2721 isCreateNew); 2722 } 2723 return newElementBean; 2724 } 2725 2726 /** 2727 * Returns the requested container-page resource.<p> 2728 * 2729 * @param cms the current cms object 2730 * 2731 * @return the container-page resource 2732 * 2733 * @throws CmsException if the resource could not be read for any reason 2734 */ 2735 private CmsResource getContainerpage(CmsObject cms) throws CmsException { 2736 2737 String currentUri = cms.getRequestContext().getUri(); 2738 CmsResource containerPage = cms.readResource(currentUri, CmsResourceFilter.ignoreExpirationOffline(cms)); 2739 if (!CmsResourceTypeXmlContainerPage.isContainerPage(containerPage)) { 2740 // container page is used as template 2741 String cntPagePath = cms.readPropertyObject( 2742 containerPage, 2743 CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS, 2744 true).getValue(""); 2745 try { 2746 containerPage = cms.readResource(cntPagePath, CmsResourceFilter.ignoreExpirationOffline(cms)); 2747 } catch (CmsException e) { 2748 if (!LOG.isDebugEnabled()) { 2749 LOG.warn(e.getLocalizedMessage()); 2750 } 2751 LOG.debug(e.getLocalizedMessage(), e); 2752 } 2753 } 2754 return containerPage; 2755 } 2756 2757 /** 2758 * Gets the (potentially empty) set of types for which the container page is registered as a detail page. 2759 * 2760 * @param cms the CMS context 2761 * @param containerPage a container page resource 2762 * 2763 * @return the set of names of types for which the container page is a detail page 2764 */ 2765 private Set<String> getDetailTypes(CmsObject cms, CmsResource containerPage) { 2766 2767 List<CmsDetailPageInfo> infos = OpenCms.getADEManager().getAllDetailPages(cms); 2768 Set<CmsUUID> ids = new HashSet<>(); 2769 ids.add(containerPage.getStructureId()); 2770 Set<String> result = new HashSet<>(); 2771 if (containerPage.isFile()) { 2772 try { 2773 CmsResource folder = cms.readParentFolder(containerPage.getStructureId()); 2774 if (folder != null) { 2775 ids.add(folder.getStructureId()); 2776 } 2777 } catch (CmsException e) { 2778 LOG.error(e.getLocalizedMessage(), e); 2779 } 2780 } 2781 for (CmsDetailPageInfo info : infos) { 2782 if (ids.contains(info.getId())) { 2783 result.add(info.getType()); 2784 } 2785 } 2786 2787 return result; 2788 2789 } 2790 2791 /** 2792 * Returns the data of the given elements.<p> 2793 * 2794 * @param config the sitemap configuration 2795 * @param page the current container page 2796 * @param clientIds the list of IDs of the elements to retrieve the data for 2797 * @param uriParam the current URI 2798 * @param detailContentId the detail content structure id 2799 * @param containers the containers for which the element data should be fetched 2800 * @param allwaysCopy <code>true</code> in case reading data for a clipboard element used as a copy group 2801 * @param dndOriginContainer the container from which an element was dragged (null if this method is not called for DND) 2802 * @param isDragMode if the page is in drag mode 2803 * @param locale the locale to use 2804 * 2805 * @return the elements data 2806 * 2807 * @throws CmsException if something really bad happens 2808 */ 2809 private Map<String, CmsContainerElementData> getElements( 2810 CmsADEConfigData config, 2811 CmsResource page, 2812 Collection<String> clientIds, 2813 String uriParam, 2814 CmsUUID detailContentId, 2815 Collection<CmsContainer> containers, 2816 boolean allwaysCopy, 2817 String dndOriginContainer, 2818 boolean isDragMode, 2819 Locale locale) 2820 throws CmsException { 2821 2822 CmsObject cms = getCmsObject(); 2823 CmsContainerPageBean pageBean = generateContainerPageForContainers( 2824 containers, 2825 cms.getRequestContext().addSiteRoot(uriParam)); 2826 Map<String, CmsContainerElementBean> idMapping = new HashMap<String, CmsContainerElementBean>(); 2827 for (String elemId : clientIds) { 2828 if ((elemId == null)) { 2829 continue; 2830 } 2831 CmsContainerElementBean element = getCachedElement(elemId, cms.getRequestContext().addSiteRoot(uriParam)); 2832 if (element.getInstanceId() == null) { 2833 element = element.clone(); 2834 getSessionCache().setCacheContainerElement(element.editorHash(), element); 2835 } 2836 element.initResource(cms); 2837 idMapping.put(elemId, element); 2838 } 2839 List<String> foundGroups = new ArrayList<String>(); 2840 if (CmsContainerElement.MENU_CONTAINER_ID.equals(dndOriginContainer)) { 2841 // this indicates the element is added to the page and not being repositioned, check for model group data 2842 CmsModelGroupHelper modelHelper = new CmsModelGroupHelper( 2843 cms, 2844 getConfigData(uriParam), 2845 getSessionCache(), 2846 isEditingModelGroups(cms, page)); 2847 String createElementContext = CmsResource.getParentFolder(page.getRootPath()); 2848 if (detailContentId != null) { 2849 try { 2850 CmsResource detailContent = cms.readResource(detailContentId, CmsResourceFilter.IGNORE_EXPIRATION); 2851 createElementContext = CmsResource.getParentFolder( 2852 CmsDetailOnlyContainerUtil.getDetailOnlyPageName( 2853 cms, 2854 page, 2855 detailContent.getRootPath(), 2856 "" + locale)); 2857 } catch (Exception e) { 2858 LOG.error(e.getLocalizedMessage(), e); 2859 } 2860 } 2861 pageBean = modelHelper.prepareforModelGroupContent( 2862 idMapping, 2863 foundGroups, 2864 pageBean, 2865 allwaysCopy, 2866 locale, 2867 createElementContext); 2868 } 2869 2870 CmsElementUtil elemUtil = new CmsElementUtil( 2871 cms, 2872 uriParam, 2873 pageBean, 2874 detailContentId, 2875 getRequest(), 2876 getResponse(), 2877 isDragMode, 2878 locale); 2879 Map<String, CmsContainerElementData> result = new HashMap<String, CmsContainerElementData>(); 2880 Set<String> ids = new HashSet<String>(); 2881 for (Entry<String, CmsContainerElementBean> entry : idMapping.entrySet()) { 2882 CmsContainerElementBean element = entry.getValue(); 2883 String dndId = null; 2884 if (ids.contains(element.editorHash())) { 2885 continue; 2886 } 2887 if ((dndOriginContainer != null) && !CmsContainerElement.MENU_CONTAINER_ID.equals(dndOriginContainer)) { 2888 CmsFormatterConfiguration formatterConfig = elemUtil.getFormatterConfiguration(element.getResource()); 2889 Map<String, String> dndSettings = getSettingsToChangeForDnd( 2890 config, 2891 element.getIndividualSettings(), 2892 formatterConfig, 2893 containers, 2894 dndOriginContainer); 2895 if (!dndSettings.isEmpty()) { 2896 CmsContainerElementBean dndElementBean = overrideSettings(element, dndSettings); 2897 getSessionCache().setCacheContainerElement(dndElementBean.editorHash(), dndElementBean); 2898 element = dndElementBean; 2899 dndId = dndElementBean.editorHash(); 2900 Map<String, CmsContainerElementData> dndResults = getElements( 2901 config, 2902 page, 2903 Arrays.asList(dndId), 2904 uriParam, 2905 detailContentId, 2906 containers, 2907 false, 2908 null, 2909 isDragMode, 2910 locale); 2911 result.putAll(dndResults); 2912 } 2913 } 2914 2915 CmsContainerElementData elementData = elemUtil.getElementData(page, element, containers); 2916 if (elementData == null) { 2917 continue; 2918 } 2919 getSessionCache().setCacheContainerElement(element.editorHash(), element); 2920 elementData.setDndId(dndId); 2921 result.put(entry.getKey(), elementData); 2922 if (elementData.isGroupContainer() || elementData.isInheritContainer()) { 2923 // this is a group-container 2924 CmsResource elementRes = cms.readResource(element.getId()); 2925 List<CmsContainerElementBean> subElements = elementData.isGroupContainer() 2926 ? getGroupContainerElements(elementRes) 2927 : getInheritedElements(elementRes, locale, uriParam); 2928 // adding all sub-items to the elements data 2929 for (CmsContainerElementBean subElement : subElements) { 2930 getSessionCache().setCacheContainerElement(subElement.editorHash(), subElement); 2931 if (!ids.contains(subElement.editorHash())) { 2932 CmsContainerElementData subItemData = elemUtil.getElementData(page, subElement, containers); 2933 ids.add(subElement.editorHash()); 2934 result.put(subElement.editorHash(), subItemData); 2935 } 2936 } 2937 } 2938 ids.add(element.editorHash()); 2939 } 2940 for (CmsContainerElementData elementData : result.values()) { 2941 elementData.setGroup(foundGroups.contains(elementData.getClientId())); 2942 } 2943 return result; 2944 } 2945 2946 /** 2947 * Helper method for converting a CmsGroupContainer to a CmsGroupContainerBean when saving a group container.<p> 2948 * 2949 * @param groupContainer the group-container data 2950 * @param containerPage the container page 2951 * @param locale the locale to use 2952 * 2953 * @return the group-container bean 2954 */ 2955 private CmsGroupContainerBean getGroupContainerBean( 2956 CmsGroupContainer groupContainer, 2957 CmsResource containerPage, 2958 String locale) { 2959 2960 CmsObject cms = getCmsObject(); 2961 List<CmsContainerElementBean> elements = new ArrayList<CmsContainerElementBean>(); 2962 for (CmsContainerElement elementData : groupContainer.getElements()) { 2963 try { 2964 if (elementData.isNew()) { 2965 elementData = createNewElement( 2966 containerPage.getStructureId(), 2967 null, 2968 elementData.getClientId(), 2969 elementData.getResourceType(), 2970 null, 2971 locale); 2972 } 2973 CmsContainerElementBean element = getCachedElement( 2974 elementData.getClientId(), 2975 containerPage.getRootPath()); 2976 2977 // make sure resource is readable, 2978 if (cms.existsResource(element.getId(), CmsResourceFilter.IGNORE_EXPIRATION)) { 2979 elements.add(element); 2980 } 2981 2982 } catch (Exception e) { 2983 log(e.getLocalizedMessage(), e); 2984 } 2985 } 2986 return new CmsGroupContainerBean( 2987 groupContainer.getTitle(), 2988 groupContainer.getDescription(), 2989 elements, 2990 groupContainer.getTypes()); 2991 } 2992 2993 /** 2994 * Returns the sub-elements of this group container resource.<p> 2995 * 2996 * @param resource the group container resource 2997 * 2998 * @return the sub-elements 2999 * 3000 * @throws CmsException if something goes wrong reading the resource 3001 */ 3002 private List<CmsContainerElementBean> getGroupContainerElements(CmsResource resource) throws CmsException { 3003 3004 CmsXmlGroupContainer xmlGroupContainer = CmsXmlGroupContainerFactory.unmarshal( 3005 getCmsObject(), 3006 resource, 3007 getRequest()); 3008 CmsGroupContainerBean groupContainer = xmlGroupContainer.getGroupContainer(getCmsObject()); 3009 return groupContainer.getElements(); 3010 } 3011 3012 /** 3013 * Gets the structure ids of group container elements from an unmarshalled group container for a single locale.<p> 3014 * 3015 * @param groupContainer the group container 3016 * @param locale the locale for which we want the element ids 3017 * 3018 * @return the group container's element ids for the given locale 3019 */ 3020 private Set<CmsUUID> getGroupElementIds(CmsXmlGroupContainer groupContainer, Locale locale) { 3021 3022 Set<CmsUUID> idSet = new HashSet<CmsUUID>(); 3023 CmsGroupContainerBean groupContainerBean = groupContainer.getGroupContainer(getCmsObject()); 3024 if (groupContainerBean != null) { 3025 for (CmsContainerElementBean element : groupContainerBean.getElements()) { 3026 idSet.add(element.getId()); 3027 } 3028 } 3029 return idSet; 3030 3031 } 3032 3033 /** 3034 * Returns the sub-elements of this inherit container resource.<p> 3035 * 3036 * @param resource the inherit container resource 3037 * @param locale the requested locale 3038 * @param uriParam the current URI 3039 * 3040 * @return the sub-elements 3041 * 3042 * @throws CmsException if something goes wrong reading the resource 3043 */ 3044 private List<CmsContainerElementBean> getInheritedElements(CmsResource resource, Locale locale, String uriParam) 3045 throws CmsException { 3046 3047 CmsObject cms = getCmsObject(); 3048 cms.getRequestContext().setLocale(locale); 3049 CmsInheritanceReferenceParser parser = new CmsInheritanceReferenceParser(cms); 3050 parser.parse(resource); 3051 CmsInheritanceReference ref = parser.getReference(locale); 3052 if (ref == null) { 3053 // new inheritance reference, return an empty list 3054 return Collections.emptyList(); 3055 } 3056 String name = ref.getName(); 3057 CmsADEManager adeManager = OpenCms.getADEManager(); 3058 CmsInheritedContainerState result = adeManager.getInheritedContainerState(cms, cms.addSiteRoot(uriParam), name); 3059 return result.getElements(true); 3060 } 3061 3062 /** 3063 * Returns the data of the given elements.<p> 3064 * 3065 * @param listElements the list of element beans to retrieve the data for 3066 * @param containerpageUri the current URI 3067 * @param detailContentId the detail content structure id 3068 * @param containers the containers which exist on the container page 3069 * @param locale the locale to use 3070 * 3071 * @return the elements data 3072 * 3073 * @throws CmsException if something really bad happens 3074 */ 3075 private List<CmsContainerElementData> getListElementsData( 3076 List<CmsContainerElementBean> listElements, 3077 String containerpageUri, 3078 CmsUUID detailContentId, 3079 Collection<CmsContainer> containers, 3080 Locale locale) 3081 throws CmsException { 3082 3083 CmsObject cms = getCmsObject(); 3084 CmsElementUtil elemUtil = new CmsElementUtil( 3085 cms, 3086 containerpageUri, 3087 generateContainerPageForContainers(containers, cms.getRequestContext().addSiteRoot(containerpageUri)), 3088 detailContentId, 3089 getRequest(), 3090 getResponse(), 3091 true, 3092 locale); 3093 CmsADESessionCache cache = getSessionCache(); 3094 List<CmsContainerElementData> result = new ArrayList<CmsContainerElementData>(); 3095 for (CmsContainerElementBean element : listElements) { 3096 // checking if resource exists 3097 if (cms.existsResource(element.getId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireFile())) { 3098 try { 3099 CmsContainerElementBean clone = element.clone(); 3100 // Because ensureNewInstanceId() just generates a new UUID, 3101 // the key for the element cache will not collide with anything else, so 3102 // we do not need to set the SYSTEM::pageId setting for disambiguation here. 3103 clone.ensureNewInstanceId(); 3104 cache.setCacheContainerElement(clone.editorHash(), clone); 3105 CmsContainerElementData elementData = elemUtil.getElementData( 3106 elemUtil.getPage(), 3107 clone, 3108 containers); 3109 result.add(elementData); 3110 } catch (CmsVfsResourceNotFoundException e) { 3111 // model group id not found, or other resources 3112 LOG.info(e.getLocalizedMessage(), e); 3113 } 3114 } 3115 } 3116 return result; 3117 } 3118 3119 /** 3120 * Returns the lock information to the given resource.<p> 3121 * 3122 * @param resource the resource 3123 * 3124 * @return lock information, if the page is locked by another user 3125 * 3126 * @throws CmsException if something goes wrong reading the lock owner user 3127 */ 3128 private String getLockInfo(CmsResource resource) throws CmsException { 3129 3130 CmsObject cms = getCmsObject(); 3131 CmsResourceUtil resourceUtil = new CmsResourceUtil(cms, resource); 3132 CmsLock lock = resourceUtil.getLock(); 3133 String lockInfo = null; 3134 if (!lock.isLockableBy(cms.getRequestContext().getCurrentUser())) { 3135 if (lock.getType() == CmsLockType.PUBLISH) { 3136 lockInfo = Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 3137 Messages.GUI_LOCKED_FOR_PUBLISH_0); 3138 } else { 3139 CmsUser lockOwner = cms.readUser(lock.getUserId()); 3140 lockInfo = Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 3141 Messages.GUI_LOCKED_BY_1, 3142 lockOwner.getFullName()); 3143 } 3144 } 3145 return lockInfo; 3146 } 3147 3148 /** 3149 * Returns the element data for a new element not existing in the VFS yet.<p> 3150 * 3151 * @param resourceTypeName the resource type name 3152 * @param uriParam the request parameters 3153 * @param detailContentId the detail content structure id 3154 * @param containers the containers of the template 3155 * @param locale the current locale 3156 * 3157 * @return the element data 3158 * 3159 * @throws CmsException if something goes wrong 3160 */ 3161 private CmsContainerElementData getNewElement( 3162 String resourceTypeName, 3163 String uriParam, 3164 CmsUUID detailContentId, 3165 Collection<CmsContainer> containers, 3166 Locale locale) 3167 throws CmsException { 3168 3169 CmsObject cms = getCmsObject(); 3170 CmsElementUtil elemUtil = new CmsElementUtil( 3171 cms, 3172 uriParam, 3173 generateContainerPageForContainers(containers, cms.getRequestContext().addSiteRoot(uriParam)), 3174 detailContentId, 3175 getRequest(), 3176 getResponse(), 3177 true, 3178 locale); 3179 CmsADEConfigData configData = getConfigData(cms.getRequestContext().addSiteRoot(uriParam)); 3180 CmsResourceTypeConfig typeConfig = configData.getResourceType(resourceTypeName); 3181 CmsContainerElementBean elementBean = CmsContainerElementBean.createElementForResourceType( 3182 cms, 3183 OpenCms.getResourceManager().getResourceType(resourceTypeName), 3184 "/", 3185 Collections.<String, String> emptyMap(), 3186 typeConfig.isCopyInModels(), 3187 locale); 3188 CmsContainerElementData data = elemUtil.getElementData(elemUtil.getPage(), elementBean, containers); 3189 data.setClientId(elementBean.editorHash()); 3190 getSessionCache().setCacheContainerElement(resourceTypeName, elementBean); 3191 getSessionCache().setCacheContainerElement(elementBean.editorHash(), elementBean); 3192 return data; 3193 } 3194 3195 /** 3196 * Returns the no-edit reason for the given resource.<p> 3197 * 3198 * @param cms the current cms object 3199 * @param containerPage the resource 3200 * 3201 * @return the no-edit reason, empty if editing is allowed 3202 * 3203 * @throws CmsException is something goes wrong 3204 */ 3205 private String getNoEditReason(CmsObject cms, CmsResource containerPage) throws CmsException { 3206 3207 return new CmsResourceUtil(cms, containerPage).getNoEditReason( 3208 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms), 3209 !cms.getRequestContext().getCurrentProject().isOnlineProject()); 3210 } 3211 3212 /** 3213 * Returns the session cache.<p> 3214 * 3215 * @return the session cache 3216 */ 3217 private CmsADESessionCache getSessionCache() { 3218 3219 if (m_sessionCache == null) { 3220 m_sessionCache = CmsADESessionCache.getCache(getRequest(), getCmsObject()); 3221 } 3222 return m_sessionCache; 3223 } 3224 3225 /** 3226 * Returns the workplace settings of the current user.<p> 3227 * 3228 * @return the workplace settings 3229 */ 3230 private CmsWorkplaceSettings getWorkplaceSettings() { 3231 3232 if (m_workplaceSettings == null) { 3233 m_workplaceSettings = CmsWorkplace.getWorkplaceSettings(getCmsObject(), getRequest()); 3234 } 3235 return m_workplaceSettings; 3236 } 3237 3238 /** 3239 * Checks if results for the stored gallery data can be restored for the new gallery data.<p> 3240 * 3241 * @param originalGalleryData the original gallery data 3242 * @param data the new gallery data 3243 * @param search the search bean 3244 * 3245 * @return true if the original and new gallery data are compatible, i.e. we can restore the search results 3246 */ 3247 private boolean hasCompatibleSearchData( 3248 CmsGalleryDataBean originalGalleryData, 3249 CmsGalleryDataBean data, 3250 CmsGallerySearchBean search) { 3251 3252 Set<String> originalUsableTypes = Sets.newHashSet(); 3253 Set<String> usableTypes = Sets.newHashSet(); 3254 for (CmsResourceTypeBean type : originalGalleryData.getTypes()) { 3255 if (!type.isDeactivated()) { 3256 originalUsableTypes.add(type.getType()); 3257 } 3258 } 3259 for (CmsResourceTypeBean type : data.getTypes()) { 3260 if (!type.isDeactivated()) { 3261 usableTypes.add(type.getType()); 3262 } 3263 } 3264 if (!usableTypes.containsAll(originalUsableTypes)) { 3265 return false; 3266 } 3267 return true; 3268 } 3269 3270 /** 3271 * Initializes request attributes using data from the RPC context.<p> 3272 * 3273 * @param context the RPC context 3274 */ 3275 private void initRequestFromRpcContext(CmsContainerPageRpcContext context) { 3276 3277 if (context.getTemplateContext() != null) { 3278 getRequest().setAttribute( 3279 CmsTemplateContextManager.ATTR_RPC_CONTEXT_OVERRIDE, 3280 context.getTemplateContext()); 3281 } 3282 } 3283 3284 /** 3285 * Internal method for saving a group container.<p> 3286 * 3287 * @param cms the cms context 3288 * @param pageStructureId the container page structure id 3289 * @param groupContainer the group container to save 3290 * 3291 * @return the container element representing the group container 3292 * 3293 * @throws CmsException if something goes wrong 3294 * @throws CmsXmlException if the XML processing goes wrong 3295 */ 3296 private CmsPair<CmsContainerElement, List<CmsRemovedElementStatus>> internalSaveGroupContainer( 3297 CmsObject cms, 3298 CmsUUID pageStructureId, 3299 CmsGroupContainer groupContainer) 3300 throws CmsException, CmsXmlException { 3301 3302 ensureSession(); 3303 CmsResource pageResource = getCmsObject().readResource(pageStructureId, CmsResourceFilter.IGNORE_EXPIRATION); 3304 CmsResource groupContainerResource = null; 3305 if (groupContainer.isNew()) { 3306 CmsADEConfigData config = getConfigData(pageResource.getRootPath()); 3307 CmsResourceTypeConfig typeConfig = config.getResourceType( 3308 CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME); 3309 groupContainerResource = typeConfig.createNewElement(getCmsObject(), pageResource.getRootPath()); 3310 String resourceName = cms.getSitePath(groupContainerResource); 3311 groupContainer.setSitePath(resourceName); 3312 groupContainer.setClientId(groupContainerResource.getStructureId().toString()); 3313 } 3314 if (groupContainerResource == null) { 3315 CmsUUID id = convertToServerId(groupContainer.getClientId()); 3316 groupContainerResource = cms.readResource(id, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 3317 } 3318 CmsGroupContainerBean groupContainerBean = getGroupContainerBean( 3319 groupContainer, 3320 pageResource, 3321 Locale.ENGLISH.toString()); 3322 3323 cms.lockResourceTemporary(groupContainerResource); 3324 CmsFile groupContainerFile = cms.readFile(groupContainerResource); 3325 Locale locale = Locale.ENGLISH; 3326 CmsXmlGroupContainer xmlGroupContainer = CmsXmlGroupContainerFactory.unmarshal(cms, groupContainerFile); 3327 Set<CmsUUID> oldElementIds = getGroupElementIds(xmlGroupContainer, locale); 3328 xmlGroupContainer.clearLocales(); 3329 xmlGroupContainer.save(cms, groupContainerBean, locale); 3330 cms.unlockResource(groupContainerResource); 3331 Set<CmsUUID> newElementIds = getGroupElementIds(xmlGroupContainer, locale); 3332 Set<CmsUUID> removedElementIds = Sets.difference(oldElementIds, newElementIds); 3333 List<CmsRemovedElementStatus> deletionCandidateStatuses = new ArrayList<CmsRemovedElementStatus>(); 3334 for (CmsUUID removedId : removedElementIds) { 3335 CmsRemovedElementStatus status = internalGetRemovedElementStatus(removedId, null, null); 3336 if (status.isDeletionCandidate()) { 3337 deletionCandidateStatuses.add(status); 3338 } 3339 } 3340 CmsContainerElement element = new CmsContainerElement(); 3341 element.setClientId(groupContainerFile.getStructureId().toString()); 3342 element.setSitePath(cms.getSitePath(groupContainerFile)); 3343 element.setResourceType(CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME); 3344 return CmsPair.create(element, deletionCandidateStatuses); 3345 } 3346 3347 /** 3348 * Checks if small elements in a container page should be initially editable.<p> 3349 * 3350 * @param request the current request 3351 * @param cms the current CMS context 3352 * @return true if small elements should be initially editable 3353 */ 3354 private boolean isEditSmallElements(HttpServletRequest request, CmsObject cms) { 3355 3356 CmsUser user = cms.getRequestContext().getCurrentUser(); 3357 String editSmallElementsStr = (String)(user.getAdditionalInfo().get(ADDINFO_EDIT_SMALL_ELEMENTS)); 3358 if (editSmallElementsStr == null) { 3359 return true; 3360 } else { 3361 return Boolean.valueOf(editSmallElementsStr).booleanValue(); 3362 } 3363 } 3364 3365 /** 3366 * Checks if a page is a model page.<p> 3367 * 3368 * @param cms the CMS context to use 3369 * @param containerPage the page to check 3370 * 3371 * @return true if the resource is a model page 3372 */ 3373 private boolean isModelPage(CmsObject cms, CmsResource containerPage) { 3374 3375 CmsADEConfigData config = getConfigData(containerPage.getRootPath()); 3376 for (CmsModelPageConfig modelConfig : config.getModelPages()) { 3377 if (modelConfig.getResource().getStructureId().equals(containerPage.getStructureId())) { 3378 return true; 3379 } 3380 } 3381 return false; 3382 } 3383 3384 /** 3385 * Saves the given containers to the container page resource.<p> 3386 * 3387 * @param cms the cms context 3388 * @param containerpage the container page resource 3389 * @param containerpageUri the container page site path 3390 * @param containers the container to save 3391 * 3392 * @throws CmsException if something goes wrong writing the file 3393 */ 3394 private void saveContainers( 3395 CmsObject cms, 3396 CmsResource containerpage, 3397 String containerpageUri, 3398 List<CmsContainer> containers) 3399 throws CmsException { 3400 3401 CmsContainerPageBean page = generateContainerPageForContainers(containers, containerpage.getRootPath()); 3402 3403 CmsModelGroupHelper modelHelper = new CmsModelGroupHelper( 3404 getCmsObject(), 3405 getConfigData(containerpage.getRootPath()), 3406 getSessionCache(), 3407 isEditingModelGroups(cms, containerpage)); 3408 if (isEditingModelGroups(cms, containerpage)) { 3409 page = modelHelper.saveModelGroups(page, containerpage); 3410 } else { 3411 page = modelHelper.removeModelGroupContainers(page); 3412 } 3413 CmsXmlContainerPage xmlCnt = CmsXmlContainerPageFactory.unmarshal( 3414 cms, 3415 cms.readFile(containerpageUri, CmsResourceFilter.ignoreExpirationOffline(cms))); 3416 xmlCnt.save(cms, page); 3417 } 3418 3419 /** 3420 * Saves the inheritance group.<p> 3421 * 3422 * @param resource the inheritance group resource 3423 * @param inheritanceContainer the inherited group container data 3424 * 3425 * @throws CmsException if something goes wrong 3426 */ 3427 private void saveInheritanceGroup(CmsResource resource, CmsInheritanceContainer inheritanceContainer) 3428 throws CmsException { 3429 3430 CmsObject cms = getCmsObject(); 3431 CmsFile file = cms.readFile(resource); 3432 CmsXmlContent document = CmsXmlContentFactory.unmarshal(cms, file); 3433 3434 for (Locale docLocale : document.getLocales()) { 3435 document.removeLocale(docLocale); 3436 } 3437 Locale locale = Locale.ENGLISH; 3438 document.addLocale(cms, locale); 3439 document.getValue("Title", locale).setStringValue(cms, inheritanceContainer.getTitle()); 3440 document.getValue("Description", locale).setStringValue(cms, inheritanceContainer.getDescription()); 3441 document.getValue("ConfigName", locale).setStringValue(cms, inheritanceContainer.getName()); 3442 byte[] content = document.marshal(); 3443 file.setContents(content); 3444 cms.writeFile(file); 3445 } 3446 3447 /** 3448 * Update favorite or recent list with the given element.<p> 3449 * 3450 * @param containerPage the edited container page 3451 * @param clientId the elements client id 3452 * @param list the list to update 3453 * 3454 * @return the updated list 3455 * 3456 * @throws CmsException in case reading the element resource fails 3457 */ 3458 private List<CmsContainerElementBean> updateFavoriteRecentList( 3459 CmsResource containerPage, 3460 String clientId, 3461 List<CmsContainerElementBean> list) 3462 throws CmsException { 3463 3464 try { 3465 CmsContainerElementBean element = getCachedElement(clientId, containerPage.getRootPath()); 3466 Map<String, String> settings = new HashMap<String, String>(element.getIndividualSettings()); 3467 String formatterID = null; 3468 Iterator<Entry<String, String>> entries = settings.entrySet().iterator(); 3469 while (entries.hasNext()) { 3470 Entry<String, String> entry = entries.next(); 3471 if (entry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY)) { 3472 formatterID = entry.getValue(); 3473 entries.remove(); 3474 } 3475 } 3476 settings.put(CmsFormatterConfig.FORMATTER_SETTINGS_KEY, formatterID); 3477 settings.put(SOURCE_CONTAINERPAGE_ID_SETTING, containerPage.getStructureId().toString()); 3478 settings.remove(CmsContainerElement.SETTING_PAGE_ID); 3479 element = CmsContainerElementBean.cloneWithSettings(element, settings); 3480 Iterator<CmsContainerElementBean> listIt = list.iterator(); 3481 while (listIt.hasNext()) { 3482 CmsContainerElementBean listElem = listIt.next(); 3483 if (element.getInstanceId().equals(listElem.getInstanceId())) { 3484 listIt.remove(); 3485 } 3486 } 3487 list.add(0, element); 3488 return list; 3489 } catch (CmsVfsResourceNotFoundException e) { 3490 LOG.warn(e.getLocalizedMessage(), e); 3491 return list; 3492 } 3493 } 3494 3495}