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 /** Runtime property key to enable / disable placement mode. */ 317 public static final String PARAM_PAGE_EDITOR_PLACEMENT_MODE_ENABLED = "pageEditor.placementMode.enabled"; 318 319 /** Additional info key for storing the "edit small elements" setting on the user. */ 320 public static final String ADDINFO_EDIT_SMALL_ELEMENTS = "EDIT_SMALL_ELEMENTS"; 321 322 /** Session attribute name used to store the selected clipboard tab. */ 323 public static final String ATTR_CLIPBOARD_TAB = "clipboardtab"; 324 325 /** The model group pages path fragment. */ 326 public static final String MODEL_GROUP_PATH_FRAGMENT = "/.content/.modelgroups/"; 327 328 /** The source container page id settings key. */ 329 public static final String SOURCE_CONTAINERPAGE_ID_SETTING = "source_containerpage_id"; 330 331 /** Static reference to the log. */ 332 static final Log LOG = CmsLog.getLog(CmsContainerpageService.class); 333 334 /** Serial version UID. */ 335 private static final long serialVersionUID = -6188370638303594280L; 336 337 /** Maximum number of reuse locations to display in the reuse warning dialog. */ 338 public static final int MAX_VISIBLE_ELEMENT_USES = 100; 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 String pageFolderRootPath = cms.getRequestContext().addSiteRoot(uri); 1195 CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(cms, pageFolderRootPath); 1196 Map<String, CmsResourceTypeConfig> typesByName = config.getTypesByName(); 1197 final String templateContextStr = (templateContextInfo != null) 1198 && (templateContextInfo.getCurrentContext() != null) ? templateContextInfo.getCurrentContext() : null; 1199 CmsAddDialogTypeHelper typeHelper = new CmsAddDialogTypeHelper(CmsResourceTypeConfig.AddMenuType.ade) { 1200 1201 @Override 1202 protected boolean exclude(CmsResourceTypeBean type) { 1203 1204 CmsResourceTypeConfig typeConfig = typesByName.get(type.getType()); 1205 if ((typeConfig != null) 1206 && (templateContextStr != null) 1207 && !typeConfig.isAvailableInTemplate(templateContextStr)) { 1208 return true; 1209 } 1210 return false; 1211 1212 } 1213 }; 1214 if (detailContentId != null) { 1215 try { 1216 CmsResource page = cms.readResource(uri, CmsResourceFilter.IGNORE_EXPIRATION); 1217 CmsResource detailContent = cms.readResource(detailContentId, CmsResourceFilter.IGNORE_EXPIRATION); 1218 pageFolderRootPath = CmsResource.getParentFolder( 1219 CmsDetailOnlyContainerUtil.getDetailOnlyPageName( 1220 cms, 1221 page, 1222 detailContent.getRootPath(), 1223 "" + locale)); 1224 } catch (Exception e) { 1225 LOG.error(e.getLocalizedMessage(), e); 1226 } 1227 } 1228 List<CmsResourceTypeBean> resTypeBeans = typeHelper.getResourceTypes( 1229 cms, 1230 cms.getRequestContext().addSiteRoot(uri), 1231 pageFolderRootPath, 1232 uri, 1233 OpenCms.getADEManager().getElementViews(cms).get(elementView), 1234 new I_CmsResourceTypeEnabledCheck() { 1235 1236 public boolean checkEnabled( 1237 CmsObject paramCms, 1238 CmsADEConfigData config2, 1239 I_CmsResourceType resType) { 1240 1241 boolean isModelGroup = CmsResourceTypeXmlContainerPage.MODEL_GROUP_TYPE_NAME.equals( 1242 resType.getTypeName()); 1243 return isModelGroup || config2.hasFormatters(paramCms, resType, containers); 1244 } 1245 }); 1246 CmsGalleryService srv = new CmsGalleryService(); 1247 srv.setCms(cms); 1248 srv.setRequest(getRequest()); 1249 data = srv.getInitialSettingsForContainerPage(resTypeBeans, uri, locale); 1250 CmsContainerPageGalleryData result = new CmsContainerPageGalleryData(); 1251 1252 CmsADESessionCache cache = CmsADESessionCache.getCache(getRequest(), cms); 1253 CmsGallerySearchBean search = cache.getLastPageEditorGallerySearch(); 1254 String subsite = OpenCms.getADEManager().getSubSiteRoot(cms, cms.addSiteRoot(uri)); 1255 1256 // 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 1257 String providerSuffix = "null"; 1258 if (templateContextInfo != null) { 1259 String providerKey = templateContextInfo.getContextProvider(); 1260 I_CmsTemplateContextProvider provider = OpenCms.getTemplateContextManager().getTemplateContextProvider( 1261 providerKey); 1262 if (provider != null) { 1263 try { 1264 MessageDigest md5 = MessageDigest.getInstance("md5"); 1265 md5.update(providerKey.getBytes(StandardCharsets.UTF_8)); 1266 if (templateContextInfo.getCurrentContext() != null) { 1267 md5.update((byte)0); // 0 byte as separator 1268 md5.update(templateContextInfo.getCurrentContext().getBytes(StandardCharsets.UTF_8)); 1269 providerSuffix = Hex.encodeHexString(md5.digest()); 1270 } 1271 } catch (NoSuchAlgorithmException e) { 1272 // MD5 must be in standard library 1273 } 1274 } 1275 } 1276 1277 String searchStoreKey = elementView + "|" + subsite + "|" + locale + "|" + providerSuffix; 1278 data.getContextParameters().put("searchStoreKey", searchStoreKey); 1279 if ((search != null) && !search.getServerSearchTypes().contains(CmsResourceTypeFunctionConfig.TYPE_NAME)) { 1280 if (searchStoreKey.equals( 1281 search.getOriginalGalleryData().getContextParameters().get("searchStoreKey"))) { 1282 if (hasCompatibleSearchData(search.getOriginalGalleryData(), data, search)) { 1283 1284 CmsVfsEntryBean preloadData = null; 1285 if (search.getFolders() != null) { 1286 preloadData = CmsGalleryService.generateVfsPreloadData( 1287 getCmsObject(), 1288 CmsGalleryService.getVfsTreeState(getRequest(), data.getTreeToken()), 1289 search.getFolders()); 1290 } 1291 1292 // only restore last result list if the search was performed in a 'similar' context 1293 search.setTabId(GalleryTabId.cms_tab_results.toString()); 1294 search.setPage(1); 1295 search.setLastPage(0); 1296 data.setStartTab(GalleryTabId.cms_tab_results); 1297 search = srv.getSearch(search); 1298 data.setVfsPreloadData(preloadData); 1299 data.setIncludeExpiredDefault(search.isIncludeExpired()); 1300 result.setGallerySearch(search); 1301 } 1302 } 1303 } 1304 result.setGalleryData(data); 1305 return result; 1306 1307 } catch (Exception e) { 1308 error(e); 1309 return null; 1310 } 1311 } 1312 1313 /** 1314 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getListElementCreationOptions(org.opencms.util.CmsUUID, java.lang.String) 1315 */ 1316 public CmsListElementCreationDialogData getListElementCreationOptions(CmsUUID structureId, String jsonListAddData) 1317 throws CmsRpcException { 1318 1319 CmsObject cms = getCmsObject(); 1320 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1321 CmsMessages msg = Messages.get().getBundle(locale); 1322 try { 1323 CmsUUID listId = structureId; 1324 1325 String jsonConfig = jsonListAddData; 1326 I_CmsAutoBeanFactory beanFactory = AutoBeanFactorySource.create(I_CmsAutoBeanFactory.class); 1327 AutoBean<I_CmsListAddMetadata> listAddData = AutoBeanCodex.decode( 1328 beanFactory, 1329 I_CmsListAddMetadata.class, 1330 jsonConfig); 1331 CmsListElementCreationDialogData result = new CmsListElementCreationDialogData(); 1332 result.setCaption(msg.key(Messages.GUI_LISTADD_CAPTION_0)); 1333 result.setPostCreateHandler(listAddData.as().getPostCreateHandler()); 1334 String uploadFolder = listAddData.as().getUploadFolder(); 1335 boolean isUpload = false; 1336 if (!CmsStringUtil.isEmptyOrWhitespaceOnly(uploadFolder) && !"none".equals(uploadFolder)) { 1337 if (listAddData.as().getTypes().stream().anyMatch( 1338 type -> CmsResourceTypeBinary.getStaticTypeName().equals(type) 1339 || CmsResourceTypePlain.getStaticTypeName().equals(type) 1340 || CmsResourceTypeImage.getStaticTypeName().equals(type))) { 1341 1342 CmsResource uploadFolderResource = null; 1343 try { 1344 uploadFolderResource = cms.readResource(uploadFolder, CmsResourceFilter.IGNORE_EXPIRATION); 1345 if (cms.hasPermissions( 1346 uploadFolderResource, 1347 CmsPermissionSet.ACCESS_WRITE, 1348 false, 1349 CmsResourceFilter.IGNORE_EXPIRATION)) { 1350 isUpload = true; 1351 } 1352 } catch (CmsVfsResourceNotFoundException | CmsPermissionViolationException e) { 1353 LOG.debug(e.getLocalizedMessage(), e); 1354 } catch (Exception e) { 1355 LOG.error(e.getLocalizedMessage(), e); 1356 } 1357 } 1358 } 1359 if (isUpload) { 1360 result.setUploadFolder(uploadFolder); 1361 CmsListInfoBean listResourceInfo = CmsVfsService.getPageInfo( 1362 cms, 1363 cms.readResource(uploadFolder, CmsResourceFilter.IGNORE_EXPIRATION)); 1364 result.setListInfo(listResourceInfo); 1365 } else { 1366 CmsADEConfigData adeConfig = OpenCms.getADEManager().lookupConfiguration( 1367 cms, 1368 cms.getRequestContext().getRootUri()); 1369 CmsResource listResource = cms.readResource(listId, CmsResourceFilter.IGNORE_EXPIRATION); 1370 CmsListInfoBean listResourceInfo = CmsVfsService.getPageInfo(cms, listResource); 1371 result.setListInfo(listResourceInfo); 1372 List<String> createTypes = listAddData.as().getTypes(); 1373 Map<String, CmsResourceTypeConfig> typeMap = adeConfig.getTypesByName(); 1374 for (String type : createTypes) { 1375 try { 1376 CmsResourceTypeConfig currentType = typeMap.get(type); 1377 if (currentType != null) { 1378 if (adeConfig.getDirectEditPermissions(type).canCreate() 1379 && currentType.checkCreatable(cms, null)) { 1380 CmsListInfoBean typeInfo = new CmsListInfoBean(); 1381 CmsExplorerTypeSettings explorerType = OpenCms.getWorkplaceManager().getExplorerTypeSetting( 1382 type); 1383 String title = CmsWorkplaceMessages.getResourceTypeName(locale, type); 1384 typeInfo.setTitle(title); 1385 String description = CmsWorkplaceMessages.getResourceTypeDescription(locale, type); 1386 typeInfo.setSubTitle(description); 1387 typeInfo.setResourceType(type); 1388 typeInfo.setBigIconClasses(CmsIconUtil.getIconClasses(explorerType, null, false)); 1389 String newLink = CmsJspTagEdit.getNewLink( 1390 cms, 1391 OpenCms.getResourceManager().getResourceType(type), 1392 cms.getRequestContext().getUri()); 1393 CmsListElementCreationOption option = new CmsListElementCreationOption( 1394 type, 1395 typeInfo, 1396 newLink); 1397 result.add(option); 1398 } 1399 } 1400 } catch (Exception e) { 1401 LOG.error(e.getLocalizedMessage(), e); 1402 } 1403 } 1404 if (result.getOptions().size() == 0) { 1405 result.setMessage(msg.key(Messages.GUI_LISTADD_NO_TYPES_0)); 1406 } 1407 } 1408 1409 return result; 1410 } catch (Exception e) { 1411 error(e); 1412 return null; 1413 } 1414 } 1415 1416 /** 1417 * @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) 1418 */ 1419 public CmsContainerElementData getNewElementData( 1420 CmsContainerPageRpcContext context, 1421 CmsUUID detailContentId, 1422 String reqParams, 1423 String resourceType, 1424 Collection<CmsContainer> containers, 1425 String localeName) 1426 throws CmsRpcException { 1427 1428 CmsContainerElementData result = null; 1429 try { 1430 ensureSession(); 1431 CmsResource pageResource = getCmsObject().readResource( 1432 context.getPageStructureId(), 1433 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1434 initRequestFromRpcContext(context); 1435 String containerpageUri = getCmsObject().getSitePath(pageResource); 1436 Locale locale = CmsLocaleManager.getLocale(localeName); 1437 result = getNewElement( 1438 getServerIdString(resourceType), 1439 containerpageUri, 1440 detailContentId, 1441 containers, 1442 locale); 1443 1444 CmsListInfoBean info = new CmsListInfoBean(); 1445 // type title and subtitle 1446 String realType = getServerIdString(resourceType); 1447 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(getCmsObject()); 1448 info.setTitle(CmsWorkplaceMessages.getResourceTypeName(wpLocale, realType)); 1449 info.setSubTitle(CmsWorkplaceMessages.getResourceTypeDescription(wpLocale, realType)); 1450 info.setBigIconClasses(CmsIconUtil.getIconClasses(realType, null, false)); 1451 result.setListInfo(info); 1452 } catch (Throwable e) { 1453 error(e); 1454 } 1455 return result; 1456 } 1457 1458 /** 1459 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getNewOptions(java.lang.String, org.opencms.util.CmsUUID, java.lang.String) 1460 */ 1461 public CmsDialogOptionsAndInfo getNewOptions(String clientId, CmsUUID pageStructureId, String requestParams) 1462 throws CmsRpcException { 1463 1464 try { 1465 CmsResource pageResource = getCmsObject().readResource( 1466 pageStructureId, 1467 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1468 CmsContainerElementBean element = getCachedElement(clientId, pageResource.getRootPath()); 1469 element.initResource(getCmsObject()); 1470 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 1471 if (type instanceof CmsResourceTypeXmlContent) { 1472 I_CmsEditHandler handler = ((CmsResourceTypeXmlContent)type).getEditHandler(getCmsObject()); 1473 Map<String, String[]> params = CmsRequestUtil.createParameterMap( 1474 CmsEncoder.decode(requestParams), 1475 true, 1476 CmsEncoder.ENCODING_UTF_8); 1477 CmsDialogOptions options = handler.getNewOptions(getCmsObject(), element, pageStructureId, params); 1478 if (options != null) { 1479 return new CmsDialogOptionsAndInfo( 1480 options, 1481 CmsVfsService.getPageInfo(getCmsObject(), element.getResource())); 1482 } 1483 } 1484 } catch (CmsException e) { 1485 error(e); 1486 } 1487 return null; 1488 1489 } 1490 1491 /** 1492 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getRecentList(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, java.util.Collection, java.lang.String) 1493 */ 1494 public List<CmsContainerElementData> getRecentList( 1495 CmsUUID pageStructureId, 1496 CmsUUID detailContentId, 1497 Collection<CmsContainer> containers, 1498 String locale) 1499 throws CmsRpcException { 1500 1501 List<CmsContainerElementData> result = null; 1502 try { 1503 ensureSession(); 1504 CmsResource containerpage = getCmsObject().readResource( 1505 pageStructureId, 1506 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1507 String containerpageUri = getCmsObject().getSitePath(containerpage); 1508 result = getListElementsData( 1509 OpenCms.getADEManager().getRecentList(getCmsObject()), 1510 containerpageUri, 1511 detailContentId, 1512 containers, 1513 CmsLocaleManager.getLocale(locale)); 1514 } catch (Throwable e) { 1515 error(e); 1516 } 1517 return result; 1518 } 1519 1520 /** 1521 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getRemovedElementStatus(java.lang.String, org.opencms.util.CmsUUID, org.opencms.util.CmsUUID) 1522 */ 1523 public CmsRemovedElementStatus getRemovedElementStatus(String id, CmsUUID contextId, CmsUUID containerpageId) 1524 throws CmsRpcException { 1525 1526 if ((id == null) || !id.matches(CmsUUID.UUID_REGEX + ".*$")) { 1527 return new CmsRemovedElementStatus(null, null, false, null); 1528 } 1529 try { 1530 CmsUUID structureId = convertToServerId(id); 1531 return internalGetRemovedElementStatus(structureId, contextId, containerpageId); 1532 } catch (CmsException e) { 1533 error(e); 1534 return null; 1535 } 1536 } 1537 1538 /** 1539 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#getReuseInfo(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID, org.opencms.util.CmsUUID) 1540 */ 1541 public CmsReuseInfo getReuseInfo(CmsUUID pageId, CmsUUID detailId, CmsUUID elementId) throws CmsRpcException { 1542 1543 try { 1544 CmsObject cms = getCmsObject(); 1545 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1546 CmsResource detailResource = null; 1547 CmsResource element = cms.readResource(elementId, CmsResourceFilter.IGNORE_EXPIRATION); 1548 if (detailId != null) { 1549 detailResource = cms.readResource(detailId, CmsResourceFilter.IGNORE_EXPIRATION); 1550 } 1551 Set<CmsUUID> idsForCurrentPage = CmsElementUtil.getPageAndDetailOnlyIds( 1552 getCmsObject(), 1553 pageId, 1554 detailResource); 1555 List<CmsResource> allUses = OpenCms.getADEManager().getOfflineElementUses(element).filter( 1556 res -> !idsForCurrentPage.contains(res.getStructureId())).collect(Collectors.toList()); 1557 List<CmsResourceListInfo> infos = new ArrayList<>(); 1558 int visibleCount = 0; 1559 for (CmsResource use : allUses) { 1560 try { 1561 // make sure resource is visible to current user, otherwise continue with next resource 1562 cms.readResource(use.getStructureId(), CmsResourceFilter.IGNORE_EXPIRATION.addRequireVisible()); 1563 visibleCount += 1; 1564 CmsResourceListInfo info = new CmsResourceListInfo(); 1565 CmsVfsService.addPageInfo(cms, use, info); 1566 info.setStructureId(use.getStructureId()); 1567 infos.add(info); 1568 if (visibleCount >= MAX_VISIBLE_ELEMENT_USES) { 1569 break; 1570 } 1571 } catch (CmsVfsResourceNotFoundException | CmsPermissionViolationException e) { 1572 // ignore 1573 } catch (Exception e) { 1574 LOG.error(e.getLocalizedMessage(), e); 1575 } 1576 } 1577 CmsListInfoBean elementInfo = CmsVfsService.getPageInfo(cms, element); 1578 String message; 1579 CmsMessages messages = Messages.get().getBundle(locale); 1580 if (allUses.size() > 0) { 1581 message = messages.key(Messages.GUI_REUSE_CHECK_WARNING_TEXT_1, "" + allUses.size()); 1582 } else { 1583 message = ""; 1584 } 1585 String title = messages.key(Messages.GUI_REUSE_CHECK_TITLE_0); 1586 if (allUses.size() > infos.size()) { 1587 message = message + "\n" + messages.key(Messages.GUI_REUSE_CHECK_ONLY_SHOW_N_1, infos.size()); 1588 } 1589 CmsReuseInfo result = new CmsReuseInfo(elementInfo, infos, message, title, allUses.size()); 1590 return result; 1591 } catch (Exception e) { 1592 error(e); 1593 return null; 1594 } 1595 } 1596 1597 /** 1598 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#handleDelete(java.lang.String, java.lang.String, org.opencms.util.CmsUUID, java.lang.String) 1599 */ 1600 public void handleDelete(String clientId, String deleteOption, CmsUUID pageId, String requestParams) 1601 throws CmsRpcException { 1602 1603 try { 1604 CmsResource pageResource = getCmsObject().readResource( 1605 pageId, 1606 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1607 CmsContainerElementBean element = getCachedElement(clientId, pageResource.getRootPath()); 1608 element.initResource(getCmsObject()); 1609 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 1610 if (type instanceof CmsResourceTypeXmlContent) { 1611 I_CmsEditHandler handler = ((CmsResourceTypeXmlContent)type).getEditHandler(getCmsObject()); 1612 Map<String, String[]> params = CmsRequestUtil.createParameterMap( 1613 CmsEncoder.decode(requestParams), 1614 true, 1615 CmsEncoder.ENCODING_UTF_8); 1616 handler.handleDelete(getCmsObject(), element, deleteOption, pageId, params); 1617 } 1618 } catch (CmsException e) { 1619 error(e); 1620 } 1621 } 1622 1623 /** 1624 * Internal helper method to get the status of a removed element.<p> 1625 * 1626 * @param structureId the structure id of the removed element 1627 * @param contextId the id of the resource used to look up the sitemap configuration 1628 * @param containerpageId the id of the page to exclude from the relation check, or null if no page should be excluded 1629 * 1630 * @return the status of the removed element 1631 * 1632 * @throws CmsException in case reading the resource fails 1633 */ 1634 public CmsRemovedElementStatus internalGetRemovedElementStatus( 1635 CmsUUID structureId, 1636 CmsUUID contextId, 1637 CmsUUID containerpageId) 1638 throws CmsException { 1639 1640 CmsObject cms = getCmsObject(); 1641 CmsResource elementResource = cms.readResource(structureId, CmsResourceFilter.IGNORE_EXPIRATION); 1642 boolean hasWritePermissions = cms.hasPermissions( 1643 elementResource, 1644 CmsPermissionSet.ACCESS_WRITE, 1645 false, 1646 CmsResourceFilter.ALL); 1647 boolean isSystemResource = elementResource.getRootPath().startsWith(CmsResource.VFS_FOLDER_SYSTEM + "/"); 1648 CmsRelationFilter relationFilter = CmsRelationFilter.relationsToStructureId(structureId); 1649 List<CmsRelation> relationsToElement = cms.readRelations(relationFilter); 1650 Iterator<CmsRelation> iter = relationsToElement.iterator(); 1651 1652 // ignore XML_STRONG (i.e. container element) relations from the container page, this must be checked on the client side. 1653 while (iter.hasNext()) { 1654 CmsRelation relation = iter.next(); 1655 if ((containerpageId != null) 1656 && containerpageId.equals(relation.getSourceId()) 1657 && relation.getType().equals(CmsRelationType.XML_STRONG)) { 1658 iter.remove(); 1659 } 1660 } 1661 ElementDeleteMode elementDeleteMode = null; 1662 if (contextId != null) { 1663 CmsResource contextResource = cms.readResource(contextId, CmsResourceFilter.IGNORE_EXPIRATION); 1664 CmsADEConfigData adeConfig = OpenCms.getADEManager().lookupConfiguration( 1665 cms, 1666 contextResource.getRootPath()); 1667 CmsResourceTypeConfig typeConfig = adeConfig.getResourceType( 1668 OpenCms.getResourceManager().getResourceType(elementResource).getTypeName()); 1669 1670 if (typeConfig != null) { 1671 elementDeleteMode = typeConfig.getElementDeleteMode(); 1672 } 1673 } else { 1674 elementDeleteMode = ElementDeleteMode.askKeep; 1675 } 1676 boolean hasNoRelations = relationsToElement.isEmpty(); 1677 boolean deletionCandidate = hasNoRelations && hasWritePermissions && !isSystemResource; 1678 CmsListInfoBean elementInfo = CmsVfsService.getPageInfo(cms, elementResource); 1679 return new CmsRemovedElementStatus(structureId, elementInfo, deletionCandidate, elementDeleteMode); 1680 } 1681 1682 /** 1683 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#loadClipboardTab() 1684 */ 1685 public int loadClipboardTab() { 1686 1687 Integer clipboardTab = (Integer)(getRequest().getSession().getAttribute(ATTR_CLIPBOARD_TAB)); 1688 if (clipboardTab == null) { 1689 clipboardTab = Integer.valueOf(0); 1690 } 1691 return clipboardTab.intValue(); 1692 } 1693 1694 /** 1695 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#prefetch() 1696 */ 1697 public CmsCntPageData prefetch() throws CmsRpcException { 1698 1699 CmsCntPageData data = null; 1700 CmsObject cms = getCmsObject(); 1701 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1702 HttpServletRequest request = getRequest(); 1703 1704 try { 1705 Map<String, String> sessionStorageData = new HashMap<>(); 1706 CmsTemplateContextInfo info = OpenCms.getTemplateContextManager().getContextInfoBean(cms, request); 1707 CmsResource containerPage = getContainerpage(cms); 1708 Set<String> detailTypes = getDetailTypes(cms, containerPage); 1709 boolean isEditingModelGroup = isEditingModelGroups(cms, containerPage); 1710 boolean isModelPage = isModelPage(cms, containerPage); 1711 if (isModelPage) { 1712 // the model edit confirm dialog should only be shown once per session, disable it after first model editing 1713 getRequest().getSession().setAttribute( 1714 CmsVfsSitemapService.ATTR_SHOW_MODEL_EDIT_CONFIRM, 1715 Boolean.FALSE); 1716 } 1717 1718 TemplateBean templateBean = (TemplateBean)getRequest().getAttribute( 1719 CmsTemplateContextManager.ATTR_TEMPLATE_BEAN); 1720 CmsADESessionCache sessionCache = CmsADESessionCache.getCache(getRequest(), cms); 1721 sessionCache.setTemplateBean(containerPage.getRootPath(), templateBean); 1722 long lastModified = containerPage.getDateLastModified(); 1723 String editorUri = OpenCms.getWorkplaceManager().getEditorHandler().getEditorUri( 1724 cms, 1725 CmsResourceTypeXmlContent.getStaticTypeName(), 1726 "User agent", 1727 false); 1728 boolean useClassicEditor = (editorUri == null) || !editorUri.contains("acacia"); 1729 CmsResource detailResource = CmsDetailPageResourceHandler.getDetailResource(request); 1730 String noEditReason; 1731 String detailContainerPage = null; 1732 CmsQuickLaunchLocationCache locationCache = CmsQuickLaunchLocationCache.getLocationCache( 1733 request.getSession()); 1734 CmsUUID detailContainerPageId = null; 1735 if (detailResource != null) { 1736 locationCache.setPageEditorResource(cms, cms.getRequestContext().getSiteRoot(), detailResource); 1737 CmsObject rootCms = OpenCms.initCmsObject(cms); 1738 rootCms.getRequestContext().setSiteRoot(""); 1739 String detailResourcePath = detailResource.getRootPath(); 1740 String locale = cms.getRequestContext().getLocale().toString(); 1741 detailContainerPage = CmsDetailOnlyContainerUtil.getDetailOnlyPageName( 1742 cms, 1743 containerPage, 1744 detailResourcePath, 1745 locale); 1746 1747 if (rootCms.existsResource(detailContainerPage, CmsResourceFilter.IGNORE_EXPIRATION)) { 1748 detailContainerPageId = rootCms.readResource( 1749 detailContainerPage, 1750 CmsResourceFilter.IGNORE_EXPIRATION).getStructureId(); 1751 noEditReason = getNoEditReason( 1752 rootCms, 1753 rootCms.readResource(detailContainerPage, CmsResourceFilter.IGNORE_EXPIRATION)); 1754 } else { 1755 String permissionFolder = CmsResource.getFolderPath(detailContainerPage); 1756 while (!rootCms.existsResource(permissionFolder, CmsResourceFilter.IGNORE_EXPIRATION)) { 1757 permissionFolder = CmsResource.getParentFolder(permissionFolder); 1758 } 1759 noEditReason = getNoEditReason( 1760 rootCms, 1761 rootCms.readResource(permissionFolder, CmsResourceFilter.IGNORE_EXPIRATION)); 1762 } 1763 } else { 1764 if (!isModelPage && !isEditingModelGroup) { 1765 locationCache.setPageEditorResource(cms, cms.getRequestContext().getSiteRoot(), containerPage); 1766 sessionStorageData.put( 1767 CmsGwtConstants.LAST_CONTAINER_PAGE_ID, 1768 containerPage.getStructureId().toString()); 1769 } 1770 noEditReason = getNoEditReason(cms, containerPage); 1771 } 1772 1773 String sitemapPath = ""; 1774 boolean sitemapManager = OpenCms.getRoleManager().hasRole(cms, CmsRole.EDITOR); 1775 if (sitemapManager) { 1776 sitemapPath = CmsADEManager.PATH_SITEMAP_EDITOR_JSP; 1777 } 1778 CmsCntPageData.ElementReuseMode reuseMode = ElementReuseMode.reuse; 1779 String reuseModeString = getWorkplaceSettings().getUserSettings().getAdditionalPreference( 1780 "elementReuseMode", 1781 true); 1782 1783 try { 1784 reuseMode = ElementReuseMode.valueOf(reuseModeString); 1785 } catch (Exception e) { 1786 LOG.info("Invalid reuse mode : " + reuseModeString, e); 1787 } 1788 InitialElementViewProvider viewHelper = new InitialElementViewProvider(); 1789 viewHelper.init(getSessionCache().getElementView(), containerPage, info); 1790 CmsLocaleGroup group = cms.getLocaleGroupService().readLocaleGroup(containerPage); 1791 Locale mainLocale = null; 1792 1793 if (group.isRealGroup() && !cms.getRequestContext().getLocale().equals(group.getMainLocale())) { 1794 mainLocale = group.getMainLocale(); 1795 } 1796 CmsSiteManagerImpl siteManager = OpenCms.getSiteManager(); 1797 String ownRoot = siteManager.getSiteRoot(containerPage.getRootPath()); 1798 Map<String, CmsLocaleLinkBean> localeLinkBeans = null; 1799 if (group.isRealGroup()) { 1800 localeLinkBeans = Maps.newHashMap(); 1801 Locale locale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms); 1802 for (Map.Entry<Locale, CmsResource> entry : group.getResourcesByLocale().entrySet()) { 1803 String otherRoot = siteManager.getSiteRoot(entry.getValue().getRootPath()); 1804 if ((otherRoot != null) && otherRoot.equals(ownRoot)) { 1805 String theLink = OpenCms.getLinkManager().substituteLinkForUnknownTarget( 1806 cms, 1807 cms.getRequestContext().removeSiteRoot(entry.getValue().getRootPath())); 1808 localeLinkBeans.put(entry.getKey().getDisplayLanguage(locale), CmsLocaleLinkBean.link(theLink)); 1809 } else { 1810 localeLinkBeans.put( 1811 entry.getKey().getDisplayLanguage(locale), 1812 CmsLocaleLinkBean.error( 1813 Messages.get().getBundle(locale).key(Messages.GUI_SHOWLOCALE_WRONG_SITE_0))); 1814 } 1815 } 1816 } 1817 1818 String onlineLink = null; 1819 CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(cms.getRequestContext().getSiteRoot()); 1820 if ((site != null) && !OpenCms.getSiteManager().getWorkplaceServer().equals(site.getUrl())) { 1821 if (detailResource != null) { 1822 onlineLink = OpenCms.getLinkManager().getOnlineLink( 1823 cms, 1824 cms.getSitePath(detailResource), 1825 cms.getSitePath(containerPage), 1826 false); 1827 } else { 1828 onlineLink = OpenCms.getLinkManager().getOnlineLink(cms, cms.getSitePath(containerPage)); 1829 } 1830 } 1831 1832 String modelGroupElementId = null; 1833 if (isEditingModelGroup) { 1834 CmsProperty modelElementProp = cms.readPropertyObject( 1835 containerPage, 1836 CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS, 1837 false); 1838 if (!modelElementProp.isNullProperty() && CmsUUID.isValidUUID(modelElementProp.getValue())) { 1839 modelGroupElementId = modelElementProp.getValue(); 1840 } 1841 } 1842 String title = null; 1843 if (isModelPage || isEditingModelGroup) { 1844 title = Messages.get().getBundle(wpLocale).key(Messages.GUI_TITLE_MODEL_0); 1845 1846 } 1847 ElementDeleteMode deleteMode = OpenCms.getWorkplaceManager().getElementDeleteMode(); 1848 if (deleteMode == null) { 1849 deleteMode = ElementDeleteMode.askDelete; 1850 } 1851 CmsListInfoBean pageInfo = CmsVfsService.getPageInfo(cms, containerPage); 1852 data = new CmsCntPageData( 1853 onlineLink, 1854 noEditReason, 1855 CmsRequestUtil.encodeParams(request), 1856 sitemapPath, 1857 sitemapManager, 1858 detailResource != null ? detailResource.getStructureId() : null, 1859 detailContainerPage, 1860 detailContainerPageId, 1861 detailTypes, 1862 lastModified, 1863 getLockInfo(containerPage), 1864 pageInfo, 1865 cms.getRequestContext().getLocale().toString(), 1866 useClassicEditor, 1867 info, 1868 isEditSmallElements(request, cms), 1869 Lists.newArrayList(viewHelper.getViewMap().values()), 1870 viewHelper.getDefaultView(), 1871 reuseMode, 1872 deleteMode, 1873 isModelPage, 1874 isEditingModelGroup, 1875 modelGroupElementId, 1876 mainLocale != null ? mainLocale.toString() : null, 1877 localeLinkBeans, 1878 title, 1879 System.currentTimeMillis()); 1880 boolean allowSettingsInEditor = true; 1881 CmsModule baseModule = OpenCms.getModuleManager().getModule("org.opencms.base"); 1882 if (baseModule != null) { 1883 String param = baseModule.getParameter("allowSettingsInEditor"); 1884 allowSettingsInEditor = CmsStringUtil.isEmptyOrWhitespaceOnly(param) 1885 || Boolean.valueOf(param).booleanValue(); 1886 } 1887 data.setAllowSettingsInEditor(allowSettingsInEditor); 1888 String placementModeEnabledStr = (String)OpenCms.getRuntimeProperty( 1889 PARAM_PAGE_EDITOR_PLACEMENT_MODE_ENABLED); 1890 boolean placementModeEnabled = (placementModeEnabledStr == null) 1891 || Boolean.parseBoolean(placementModeEnabledStr); 1892 data.setPlacementModeEnabled(placementModeEnabled); 1893 data.setSessionStorageData(sessionStorageData); 1894 } catch (Throwable e) { 1895 error(e); 1896 } 1897 return data; 1898 } 1899 1900 /** 1901 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#prepareForEdit(java.lang.String, java.lang.String, org.opencms.util.CmsUUID, java.lang.String) 1902 */ 1903 public CmsUUID prepareForEdit(String clientId, String editOption, CmsUUID pageId, String requestParams) 1904 throws CmsRpcException { 1905 1906 try { 1907 CmsResource pageResource = getCmsObject().readResource( 1908 pageId, 1909 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1910 CmsContainerElementBean element = getCachedElement(clientId, pageResource.getRootPath()); 1911 element.initResource(getCmsObject()); 1912 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 1913 if (type instanceof CmsResourceTypeXmlContent) { 1914 I_CmsEditHandler handler = ((CmsResourceTypeXmlContent)type).getEditHandler(getCmsObject()); 1915 Map<String, String[]> params = CmsRequestUtil.createParameterMap( 1916 CmsEncoder.decode(requestParams), 1917 true, 1918 CmsEncoder.ENCODING_UTF_8); 1919 return handler.prepareForEdit(getCmsObject(), element, editOption, pageId, params); 1920 } 1921 } catch (CmsException e) { 1922 error(e); 1923 } 1924 return null; 1925 } 1926 1927 /** 1928 * @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) 1929 */ 1930 public CmsContainerElementData replaceElement( 1931 CmsContainerPageRpcContext context, 1932 CmsUUID detailContentId, 1933 String reqParams, 1934 String clientId, 1935 String replaceId, 1936 Collection<CmsContainer> containers, 1937 String locale) 1938 throws CmsRpcException { 1939 1940 CmsContainerElementData element = null; 1941 try { 1942 ensureSession(); 1943 CmsObject cms = getCmsObject(); 1944 CmsResource pageResource = cms.readResource( 1945 context.getPageStructureId(), 1946 CmsResourceFilter.ignoreExpirationOffline(cms)); 1947 initRequestFromRpcContext(context); 1948 String containerpageUri = cms.getSitePath(pageResource); 1949 Locale contentLocale = CmsLocaleManager.getLocale(locale); 1950 CmsElementUtil elemUtil = new CmsElementUtil( 1951 cms, 1952 containerpageUri, 1953 generateContainerPageForContainers(containers, pageResource.getRootPath()), 1954 detailContentId, 1955 getRequest(), 1956 getResponse(), 1957 false, 1958 contentLocale); 1959 1960 CmsContainerElementBean elementBean = getCachedElement(clientId, pageResource.getRootPath()); 1961 Map<String, String> settings = new HashMap<String, String>(elementBean.getIndividualSettings()); 1962 settings.remove(CmsContainerElement.ELEMENT_INSTANCE_ID); 1963 CmsContainerElementBean replaceBean = new CmsContainerElementBean( 1964 new CmsUUID(replaceId), 1965 elementBean.getFormatterId(), 1966 settings, 1967 elementBean.isCreateNew()); 1968 getSessionCache().setCacheContainerElement(replaceBean.editorHash(), replaceBean); 1969 element = elemUtil.getElementData(pageResource, replaceBean, containers); 1970 } catch (Throwable e) { 1971 error(e); 1972 } 1973 return element; 1974 } 1975 1976 /** 1977 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveClipboardTab(int) 1978 */ 1979 public void saveClipboardTab(int tabIndex) { 1980 1981 getRequest().getSession().setAttribute(ATTR_CLIPBOARD_TAB, Integer.valueOf(tabIndex)); 1982 } 1983 1984 /** 1985 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveContainerpage(org.opencms.util.CmsUUID, java.util.List) 1986 */ 1987 public CmsPageSaveStatus saveContainerpage(CmsUUID pageStructureId, List<CmsContainer> containers) 1988 throws CmsRpcException { 1989 1990 CmsObject cms = getCmsObject(); 1991 try { 1992 ensureSession(); 1993 CmsResource containerpage = cms.readResource( 1994 pageStructureId, 1995 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 1996 ensureLock(containerpage); 1997 String containerpageUri = cms.getSitePath(containerpage); 1998 saveContainers(cms, containerpage, containerpageUri, containers); 1999 } catch (Throwable e) { 2000 error(e); 2001 } 2002 return new CmsPageSaveStatus(pageStructureId, System.currentTimeMillis()); 2003 } 2004 2005 /** 2006 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveDetailContainers(org.opencms.util.CmsUUID, java.lang.String, java.util.List) 2007 */ 2008 public CmsPageSaveStatus saveDetailContainers( 2009 CmsUUID detailId, 2010 String detailContainerResource, 2011 List<CmsContainer> containers) 2012 throws CmsRpcException { 2013 2014 CmsObject cms = getCmsObject(); 2015 CmsUUID id = null; 2016 try { 2017 ensureSession(); 2018 CmsObject rootCms = OpenCms.initCmsObject(cms); 2019 rootCms.getRequestContext().setSiteRoot(""); 2020 CmsResource containerpage; 2021 containerpage = CmsDetailOnlyContainerUtil.readOrCreateDetailOnlyPage( 2022 rootCms, 2023 detailId, 2024 detailContainerResource); 2025 id = containerpage.getStructureId(); 2026 saveContainers(rootCms, containerpage, detailContainerResource, containers); 2027 } catch (Throwable e) { 2028 error(e); 2029 } 2030 return new CmsPageSaveStatus(id, System.currentTimeMillis()); 2031 } 2032 2033 /** 2034 * @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) 2035 */ 2036 public CmsContainerElementData saveElementSettings( 2037 CmsContainerPageRpcContext context, 2038 CmsUUID detailContentId, 2039 String reqParams, 2040 String clientId, 2041 Map<String, String> settings, 2042 List<CmsContainer> containers, 2043 String locale) 2044 throws CmsRpcException { 2045 2046 CmsContainerElementData element = null; 2047 try { 2048 ensureSession(); 2049 CmsObject cms = getCmsObject(); 2050 CmsResource pageResource = cms.readResource( 2051 context.getPageStructureId(), 2052 CmsResourceFilter.ignoreExpirationOffline(cms)); 2053 initRequestFromRpcContext(context); 2054 Locale contentLocale = CmsLocaleManager.getLocale(locale); 2055 CmsContainerElementBean elementBean = getCachedElement(clientId, pageResource.getRootPath()); 2056 elementBean.initResource(cms); 2057 storeFormatterSelection(elementBean, settings); 2058 // make sure to keep the element instance id 2059 if (!settings.containsKey(CmsContainerElement.ELEMENT_INSTANCE_ID) 2060 && elementBean.getIndividualSettings().containsKey(CmsContainerElement.ELEMENT_INSTANCE_ID)) { 2061 settings.put( 2062 CmsContainerElement.ELEMENT_INSTANCE_ID, 2063 elementBean.getIndividualSettings().get(CmsContainerElement.ELEMENT_INSTANCE_ID)); 2064 } 2065 if (elementBean.getIndividualSettings().containsKey(CmsContainerElement.SETTING_PAGE_ID)) { 2066 settings.put( 2067 CmsContainerElement.SETTING_PAGE_ID, 2068 elementBean.getIndividualSettings().get(CmsContainerElement.SETTING_PAGE_ID)); 2069 } 2070 if (!isEditingModelGroups(cms, pageResource)) { 2071 // in case of model group state set to 'noGroup', the group will be dissolved and former group id forgotten 2072 if (!(settings.containsKey(CmsContainerElement.MODEL_GROUP_STATE) 2073 && (ModelGroupState.noGroup == ModelGroupState.evaluate( 2074 settings.get(CmsContainerElement.MODEL_GROUP_STATE))))) { 2075 if (elementBean.getIndividualSettings().containsKey(CmsContainerElement.MODEL_GROUP_ID)) { 2076 // make sure to keep the model group id 2077 settings.put( 2078 CmsContainerElement.MODEL_GROUP_ID, 2079 elementBean.getIndividualSettings().get(CmsContainerElement.MODEL_GROUP_ID)); 2080 } 2081 if (elementBean.getIndividualSettings().containsKey(CmsContainerElement.MODEL_GROUP_STATE)) { 2082 settings.put( 2083 CmsContainerElement.MODEL_GROUP_STATE, 2084 elementBean.getIndividualSettings().get(CmsContainerElement.MODEL_GROUP_STATE)); 2085 } 2086 } 2087 } 2088 elementBean = CmsContainerElementBean.cloneWithSettings( 2089 elementBean, 2090 convertSettingValues(elementBean.getResource(), settings, contentLocale)); 2091 getSessionCache().setCacheContainerElement(elementBean.editorHash(), elementBean); 2092 2093 // update client id within container data 2094 for (CmsContainer container : containers) { 2095 for (CmsContainerElement child : container.getElements()) { 2096 if (child.getClientId().equals(clientId)) { 2097 child.setClientId(elementBean.editorHash()); 2098 } 2099 } 2100 } 2101 if (detailContentId == null) { 2102 saveContainers(cms, pageResource, cms.getSitePath(pageResource), containers); 2103 } else { 2104 List<CmsContainer> detailContainers = new ArrayList<CmsContainer>(); 2105 for (CmsContainer container : containers) { 2106 if (container.isDetailOnly()) { 2107 detailContainers.add(container); 2108 } 2109 } 2110 CmsObject rootCms = OpenCms.initCmsObject(cms); 2111 rootCms.getRequestContext().setSiteRoot(""); 2112 CmsResource detailResource = rootCms.readResource(detailContentId, CmsResourceFilter.IGNORE_EXPIRATION); 2113 String detailRootPath = detailResource.getRootPath(); 2114 CmsResource detailContainerPage = rootCms.readResource( 2115 CmsDetailOnlyContainerUtil.getDetailOnlyPageName(cms, pageResource, detailRootPath, locale)); 2116 2117 ensureLock(detailContainerPage); 2118 saveContainers(rootCms, detailContainerPage, detailContainerPage.getRootPath(), detailContainers); 2119 } 2120 String containerpageUri = cms.getSitePath(pageResource); 2121 CmsElementUtil elemUtil = new CmsElementUtil( 2122 cms, 2123 containerpageUri, 2124 generateContainerPageForContainers(containers, pageResource.getRootPath()), 2125 detailContentId, 2126 getRequest(), 2127 getResponse(), 2128 false, 2129 contentLocale); 2130 element = elemUtil.getElementData(pageResource, elementBean, containers); 2131 } catch (Throwable e) { 2132 error(e); 2133 } 2134 return element; 2135 } 2136 2137 /** 2138 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveFavoriteList(java.util.List, java.lang.String) 2139 */ 2140 public void saveFavoriteList(List<String> clientIds, String uri) throws CmsRpcException { 2141 2142 try { 2143 ensureSession(); 2144 OpenCms.getADEManager().saveFavoriteList( 2145 getCmsObject(), 2146 getCachedElements(clientIds, getCmsObject().getRequestContext().addSiteRoot(uri))); 2147 } catch (Throwable e) { 2148 error(e); 2149 } 2150 } 2151 2152 /** 2153 * @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) 2154 */ 2155 public CmsGroupContainerSaveResult saveGroupContainer( 2156 CmsContainerPageRpcContext context, 2157 2158 CmsUUID detailContentId, 2159 String reqParams, 2160 CmsGroupContainer groupContainer, 2161 Collection<CmsContainer> containers, 2162 String locale) 2163 throws CmsRpcException { 2164 2165 CmsObject cms = getCmsObject(); 2166 List<CmsRemovedElementStatus> removedElements = null; 2167 try { 2168 CmsPair<CmsContainerElement, List<CmsRemovedElementStatus>> saveResult = internalSaveGroupContainer( 2169 cms, 2170 context.getPageStructureId(), 2171 groupContainer); 2172 removedElements = saveResult.getSecond(); 2173 } catch (Throwable e) { 2174 error(e); 2175 } 2176 Collection<String> ids = new ArrayList<String>(); 2177 ids.add(groupContainer.getClientId()); 2178 // update offline indices 2179 OpenCms.getSearchManager().updateOfflineIndexes(); 2180 return new CmsGroupContainerSaveResult( 2181 getElementsData(context, detailContentId, reqParams, ids, containers, false, null, locale), 2182 removedElements); 2183 } 2184 2185 /** 2186 * @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) 2187 */ 2188 public Map<String, CmsContainerElementData> saveInheritanceContainer( 2189 CmsUUID pageStructureId, 2190 CmsUUID detailContentId, 2191 CmsInheritanceContainer inheritanceContainer, 2192 Collection<CmsContainer> containers, 2193 String locale) 2194 throws CmsRpcException { 2195 2196 try { 2197 CmsObject cms = getCmsObject(); 2198 CmsADEConfigData rpcConfig = OpenCms.getADEManager().lookupConfiguration( 2199 cms, 2200 cms.getRequestContext().getRootUri()); 2201 CmsResource containerPage = cms.readResource( 2202 pageStructureId, 2203 CmsResourceFilter.ignoreExpirationOffline(getCmsObject())); 2204 String sitePath = cms.getSitePath(containerPage); 2205 Locale requestedLocale = CmsLocaleManager.getLocale(locale); 2206 CmsResource referenceResource = null; 2207 if (inheritanceContainer.isNew()) { 2208 CmsADEConfigData config = getConfigData(containerPage.getRootPath()); 2209 CmsResourceTypeConfig typeConfig = config.getResourceType( 2210 CmsResourceTypeXmlContainerPage.INHERIT_CONTAINER_TYPE_NAME); 2211 referenceResource = typeConfig.createNewElement(cms, containerPage.getRootPath()); 2212 inheritanceContainer.setClientId(referenceResource.getStructureId().toString()); 2213 } 2214 if (referenceResource == null) { 2215 CmsUUID id = convertToServerId(inheritanceContainer.getClientId()); 2216 referenceResource = cms.readResource(id, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 2217 } 2218 ensureLock(referenceResource); 2219 saveInheritanceGroup(referenceResource, inheritanceContainer); 2220 tryUnlock(referenceResource); 2221 List<CmsContainerElementBean> elements = new ArrayList<CmsContainerElementBean>(); 2222 for (CmsContainerElement clientElement : inheritanceContainer.getElements()) { 2223 CmsContainerElementBean elementBean = getCachedElement( 2224 clientElement.getClientId(), 2225 containerPage.getRootPath()); 2226 elementBean = CmsContainerElementBean.cloneWithSettings( 2227 elementBean, 2228 elementBean.getIndividualSettings()); 2229 CmsInheritanceInfo inheritanceInfo = clientElement.getInheritanceInfo(); 2230 // if a local elements misses the key it was newly added 2231 if (inheritanceInfo.isNew() && CmsStringUtil.isEmptyOrWhitespaceOnly(inheritanceInfo.getKey())) { 2232 // generating new key 2233 inheritanceInfo.setKey(CmsResource.getFolderPath(sitePath) + new CmsUUID().toString()); 2234 } 2235 elementBean.setInheritanceInfo(inheritanceInfo); 2236 elements.add(elementBean); 2237 } 2238 cms.getRequestContext().setLocale(requestedLocale); 2239 if (inheritanceContainer.getElementsChanged()) { 2240 OpenCms.getADEManager().saveInheritedContainer( 2241 cms, 2242 containerPage, 2243 inheritanceContainer.getName(), 2244 true, 2245 elements); 2246 } 2247 return getElements( 2248 rpcConfig, 2249 containerPage, 2250 new ArrayList<String>(Collections.singletonList(inheritanceContainer.getClientId())), 2251 sitePath, 2252 detailContentId, 2253 containers, 2254 false, 2255 null, 2256 false, 2257 requestedLocale); 2258 } catch (Exception e) { 2259 error(e); 2260 } 2261 return null; 2262 } 2263 2264 /** 2265 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#saveRecentList(java.util.List, java.lang.String) 2266 */ 2267 public void saveRecentList(List<String> clientIds, String uri) throws CmsRpcException { 2268 2269 try { 2270 ensureSession(); 2271 OpenCms.getADEManager().saveRecentList( 2272 getCmsObject(), 2273 getCachedElements(clientIds, getCmsObject().getRequestContext().addSiteRoot(uri))); 2274 } catch (Throwable e) { 2275 error(e); 2276 } 2277 } 2278 2279 /** 2280 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#setEditSmallElements(boolean) 2281 */ 2282 public void setEditSmallElements(boolean editSmallElements) throws CmsRpcException { 2283 2284 try { 2285 CmsObject cms = getCmsObject(); 2286 CmsUser user = cms.getRequestContext().getCurrentUser(); 2287 user.getAdditionalInfo().put(ADDINFO_EDIT_SMALL_ELEMENTS, "" + editSmallElements); 2288 cms.writeUser(user); 2289 } catch (Throwable t) { 2290 error(t); 2291 } 2292 } 2293 2294 /** 2295 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#setElementView(org.opencms.util.CmsUUID) 2296 */ 2297 public void setElementView(CmsUUID elementView) { 2298 2299 getSessionCache().setElementView(elementView); 2300 } 2301 2302 /** 2303 * @see org.opencms.ade.containerpage.shared.rpc.I_CmsContainerpageService#setLastPage(org.opencms.util.CmsUUID, org.opencms.util.CmsUUID) 2304 */ 2305 public void setLastPage(CmsUUID pageId, CmsUUID detailId) throws CmsRpcException { 2306 2307 try { 2308 HttpServletRequest req = getRequest(); 2309 CmsObject cms = getCmsObject(); 2310 CmsADESessionCache cache = CmsADESessionCache.getCache(req, cms); 2311 cache.setLastPage(cms, pageId, detailId); 2312 } catch (Exception e) { 2313 error(e); 2314 } 2315 2316 } 2317 2318 /** 2319 * Sets the session cache.<p> 2320 * 2321 * @param cache the session cache 2322 */ 2323 public void setSessionCache(CmsADESessionCache cache) { 2324 2325 m_sessionCache = cache; 2326 } 2327 2328 /** 2329 * Gets the settings which should be updated for an element in the DND case.<p> 2330 * 2331 * @param config the sitemap configuration 2332 * @param originalSettings the original settings 2333 * @param formatterConfig the formatter configuration for the element 2334 * @param containers the containers 2335 * @param dndContainer the id of the DND origin container 2336 * 2337 * @return the map of settings to update 2338 */ 2339 Map<String, String> getSettingsToChangeForDnd( 2340 CmsADEConfigData config, 2341 Map<String, String> originalSettings, 2342 CmsFormatterConfiguration formatterConfig, 2343 Collection<CmsContainer> containers, 2344 String dndContainer) { 2345 2346 Map<String, String> result = Maps.newHashMap(); 2347 2348 if (dndContainer == null) { 2349 return result; 2350 } 2351 String key = CmsFormatterConfig.getSettingsKeyForContainer(dndContainer); 2352 String formatterId = originalSettings.get(key); 2353 if (formatterId == null) { 2354 return result; 2355 } 2356 for (CmsContainer container : containers) { 2357 if (container.getName().equals(dndContainer)) { 2358 continue; 2359 } 2360 2361 Map<String, I_CmsFormatterBean> formatterSelection = formatterConfig.getFormatterSelection( 2362 container.getType(), 2363 container.getWidth()); 2364 I_CmsFormatterBean currentBean = config.findFormatter(formatterId); 2365 if (currentBean != null) { 2366 if (CmsFormatterConfiguration.matchFormatter(currentBean, container.getType(), container.getWidth())) { 2367 String newKey = CmsFormatterConfig.getSettingsKeyForContainer(container.getName()); 2368 result.put(newKey, currentBean.getKeyOrId()); 2369 } 2370 } else if (formatterSelection.containsKey(formatterId)) { 2371 // for backwards compatibility with schema-configured formatters 2372 String newKey = CmsFormatterConfig.getSettingsKeyForContainer(container.getName()); 2373 result.put(newKey, formatterId); 2374 } 2375 } 2376 return result; 2377 } 2378 2379 /** 2380 * Creates a new container element bean from an existing one, but changes some of the individual settings in the copy.<p> 2381 * 2382 * @param element the original container element 2383 * @param settingsToOverride the map of settings to change 2384 * 2385 * @return the new container element bean with the changed settings 2386 */ 2387 CmsContainerElementBean overrideSettings(CmsContainerElementBean element, Map<String, String> settingsToOverride) { 2388 2389 Map<String, String> settings = Maps.newHashMap(element.getIndividualSettings()); 2390 settings.putAll(settingsToOverride); 2391 CmsContainerElementBean result = new CmsContainerElementBean( 2392 element.getId(), 2393 element.getFormatterId(), 2394 settings, 2395 element.isCreateNew()); 2396 return result; 2397 } 2398 2399 /** 2400 * Adds the formatter to the recently used formatter list.<p> 2401 * 2402 * @param elementBean the element bean 2403 * @param settings the changed settings 2404 */ 2405 void storeFormatterSelection(CmsContainerElementBean elementBean, Map<String, String> settings) { 2406 2407 Entry<String, String> previousFormatterEntry = null; 2408 for (Entry<String, String> entry : elementBean.getIndividualSettings().entrySet()) { 2409 if (entry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY)) { 2410 previousFormatterEntry = entry; 2411 break; 2412 } 2413 } 2414 Entry<String, String> formatterEntry = null; 2415 for (Entry<String, String> entry : settings.entrySet()) { 2416 if (entry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY)) { 2417 formatterEntry = entry; 2418 break; 2419 } 2420 } 2421 if ((formatterEntry != null) 2422 && ((previousFormatterEntry == null) 2423 || !formatterEntry.getKey().equals(previousFormatterEntry.getKey()) 2424 || !formatterEntry.getValue().equals(previousFormatterEntry.getValue()))) { 2425 String idString = formatterEntry.getValue(); 2426 if (idString != null) { 2427 // the formatter setting has changed 2428 I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(elementBean.getResource()); 2429 if (!(resType instanceof CmsResourceTypeFunctionConfig)) { 2430 getSessionCache().addRecentFormatter(resType.getTypeName(), idString); 2431 } 2432 } 2433 } 2434 } 2435 2436 /** 2437 * Converts the given setting values according to the setting configuration of the given resource.<p> 2438 * 2439 * @param resource the resource 2440 * @param settings the settings to convert 2441 * @param locale the locale used for accessing the element settings 2442 * 2443 * @return the converted settings 2444 * @throws CmsException if something goes wrong 2445 */ 2446 private Map<String, String> convertSettingValues(CmsResource resource, Map<String, String> settings, Locale locale) 2447 throws CmsException { 2448 2449 CmsObject cms = getCmsObject(); 2450 Locale origLocale = cms.getRequestContext().getLocale(); 2451 try { 2452 cms.getRequestContext().setLocale(locale); 2453 Map<String, CmsXmlContentProperty> settingsConf = OpenCms.getADEManager().getElementSettings(cms, resource); 2454 Map<String, String> changedSettings = new HashMap<String, String>(); 2455 if (settings != null) { 2456 for (Map.Entry<String, String> entry : settings.entrySet()) { 2457 String settingName = entry.getKey(); 2458 String settingType = "string"; 2459 if (settingsConf.get(settingName) != null) { 2460 settingType = settingsConf.get(settingName).getType(); 2461 } 2462 changedSettings.put( 2463 settingName, 2464 CmsXmlContentPropertyHelper.getPropValueIds(getCmsObject(), settingType, entry.getValue())); 2465 } 2466 } 2467 return changedSettings; 2468 } finally { 2469 cms.getRequestContext().setLocale(origLocale); 2470 } 2471 } 2472 2473 /** 2474 * Generates the XML container page bean for the given containers.<p> 2475 * 2476 * @param containers the containers 2477 * @param containerpageRootPath the container page root path 2478 * 2479 * @return the container page bean 2480 * @throws CmsException in case generating the page data fails 2481 */ 2482 private CmsContainerPageBean generateContainerPageForContainers( 2483 Collection<CmsContainer> containers, 2484 String containerpageRootPath) 2485 throws CmsException { 2486 2487 List<CmsContainerBean> containerBeans = new ArrayList<CmsContainerBean>(); 2488 for (CmsContainer container : containers) { 2489 CmsContainerBean containerBean = getContainerBeanToSave(container, containerpageRootPath); 2490 containerBeans.add(containerBean); 2491 } 2492 CmsContainerPageBean page = new CmsContainerPageBean(containerBeans); 2493 return page; 2494 } 2495 2496 /** 2497 * Returns a list of container elements from a list with client id's.<p> 2498 * 2499 * @param clientIds list of client id's 2500 * @param pageRootPath the container page root path 2501 * 2502 * @return a list of element beans 2503 * @throws CmsException in case reading the element resource fails 2504 */ 2505 private List<CmsContainerElementBean> getCachedElements(List<String> clientIds, String pageRootPath) 2506 throws CmsException { 2507 2508 List<CmsContainerElementBean> result = new ArrayList<CmsContainerElementBean>(); 2509 for (String id : clientIds) { 2510 try { 2511 result.add(getCachedElement(id, pageRootPath)); 2512 } catch (CmsIllegalArgumentException e) { 2513 log(e.getLocalizedMessage(), e); 2514 } 2515 } 2516 return result; 2517 } 2518 2519 /** 2520 * Returns the configuration data of the current container page context.<p> 2521 * 2522 * @param pageRootPath the container page root path 2523 * 2524 * @return the configuration data of the current container page context 2525 */ 2526 private CmsADEConfigData getConfigData(String pageRootPath) { 2527 2528 if (m_configData == null) { 2529 m_configData = OpenCms.getADEManager().lookupConfiguration(getCmsObject(), pageRootPath); 2530 } 2531 return m_configData; 2532 } 2533 2534 /** 2535 * Helper method for converting a CmsContainer to a CmsContainerBean when saving a container page.<p> 2536 * 2537 * @param container the container for which the CmsContainerBean should be created 2538 * @param containerpageRootPath the container page root path 2539 * 2540 * @return a container bean 2541 * 2542 * @throws CmsException in case generating the container data fails 2543 */ 2544 private CmsContainerBean getContainerBeanToSave(CmsContainer container, String containerpageRootPath) 2545 throws CmsException { 2546 2547 CmsObject cms = getCmsObject(); 2548 List<CmsContainerElementBean> elements = new ArrayList<CmsContainerElementBean>(); 2549 for (CmsContainerElement elementData : container.getElements()) { 2550 if (!elementData.isNew()) { 2551 CmsContainerElementBean newElementBean = getContainerElementBeanToSave( 2552 cms, 2553 containerpageRootPath, 2554 container, 2555 elementData); 2556 if (newElementBean != null) { 2557 elements.add(newElementBean); 2558 } 2559 } 2560 } 2561 CmsContainerBean result = CmsElementUtil.clientToServerContainer(container, elements); 2562 return result; 2563 } 2564 2565 /** 2566 * Converts container page element data to a bean which can be saved in a container page.<p> 2567 * 2568 * @param cms the current CMS context 2569 * @param containerpageRootPath the container page root path 2570 * @param container the container containing the element 2571 * @param elementData the data for the single element 2572 * 2573 * @return the container element bean 2574 * 2575 * @throws CmsException if something goes wrong 2576 */ 2577 private CmsContainerElementBean getContainerElementBeanToSave( 2578 CmsObject cms, 2579 String containerpageRootPath, 2580 CmsContainer container, 2581 CmsContainerElement elementData) 2582 throws CmsException { 2583 2584 String elementClientId = elementData.getClientId(); 2585 boolean hasUuidPrefix = (elementClientId != null) && elementClientId.matches(CmsUUID.UUID_REGEX + ".*$"); 2586 boolean isCreateNew = elementData.isCreateNew(); 2587 if (elementData.isNew() && !hasUuidPrefix) { 2588 2589 // Due to the changed save system without the save button, we need to make sure that new elements 2590 // are only created once. This must happen when the user first edits a new element. But we still 2591 // want to save changes to non-new elements on the page, so we skip new elements while saving. 2592 return null; 2593 } 2594 CmsContainerElementBean element = getCachedElement(elementData.getClientId(), containerpageRootPath); 2595 2596 CmsResource resource; 2597 if (element.getResource() == null) { 2598 element.initResource(cms); 2599 resource = element.getResource(); 2600 } else { 2601 // make sure resource is readable, this is necessary for new content elements 2602 if (element.getId().isNullUUID()) { 2603 // in memory only element, can not be read nor saved 2604 return null; 2605 } 2606 resource = cms.readResource(element.getId(), CmsResourceFilter.IGNORE_EXPIRATION); 2607 } 2608 2609 // check if there is a valid formatter 2610 int containerWidth = container.getWidth(); 2611 CmsADEConfigData config = getConfigData(containerpageRootPath); 2612 CmsFormatterConfiguration formatters = config.getFormatters(cms, resource); 2613 String containerType = null; 2614 containerType = container.getType(); 2615 I_CmsFormatterBean formatter = null; 2616 String formatterConfigId = null; 2617 if ((element.getIndividualSettings() != null) 2618 && (element.getIndividualSettings().get( 2619 CmsFormatterConfig.getSettingsKeyForContainer(container.getName())) != null)) { 2620 formatterConfigId = element.getIndividualSettings().get( 2621 CmsFormatterConfig.getSettingsKeyForContainer(container.getName())); 2622 I_CmsFormatterBean dynamicFmt = config.findFormatter(formatterConfigId); 2623 if (dynamicFmt != null) { 2624 formatter = dynamicFmt; 2625 } else if (formatterConfigId.startsWith(CmsFormatterConfig.SCHEMA_FORMATTER_ID) 2626 && CmsUUID.isValidUUID(formatterConfigId.substring(CmsFormatterConfig.SCHEMA_FORMATTER_ID.length()))) { 2627 formatter = formatters.getFormatterSelection(containerType, containerWidth).get(formatterConfigId); 2628 } 2629 } 2630 if (formatter == null) { 2631 formatter = CmsElementUtil.getFormatterForContainer(cms, element, container, config, getSessionCache()); 2632 if (formatter != null) { 2633 formatterConfigId = formatter.isFromFormatterConfigFile() 2634 ? formatter.getId() 2635 : CmsFormatterConfig.SCHEMA_FORMATTER_ID + formatter.getJspStructureId().toString(); 2636 } 2637 } 2638 CmsContainerElementBean newElementBean = null; 2639 if (formatter != null) { 2640 Map<String, String> settings = new HashMap<String, String>(element.getIndividualSettings()); 2641 String formatterKey = CmsFormatterConfig.getSettingsKeyForContainer(container.getName()); 2642 settings.put(formatterKey, formatterConfigId); 2643 // remove not used formatter settings 2644 Iterator<Entry<String, String>> entries = settings.entrySet().iterator(); 2645 while (entries.hasNext()) { 2646 Entry<String, String> entry = entries.next(); 2647 if (entry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY) 2648 && !entry.getKey().equals(formatterKey)) { 2649 entries.remove(); 2650 } 2651 } 2652 2653 newElementBean = new CmsContainerElementBean( 2654 element.getId(), 2655 formatter.getJspStructureId(), 2656 settings, 2657 isCreateNew); 2658 } 2659 return newElementBean; 2660 } 2661 2662 /** 2663 * Returns the requested container-page resource.<p> 2664 * 2665 * @param cms the current cms object 2666 * 2667 * @return the container-page resource 2668 * 2669 * @throws CmsException if the resource could not be read for any reason 2670 */ 2671 private CmsResource getContainerpage(CmsObject cms) throws CmsException { 2672 2673 String currentUri = cms.getRequestContext().getUri(); 2674 CmsResource containerPage = cms.readResource(currentUri, CmsResourceFilter.ignoreExpirationOffline(cms)); 2675 if (!CmsResourceTypeXmlContainerPage.isContainerPage(containerPage)) { 2676 // container page is used as template 2677 String cntPagePath = cms.readPropertyObject( 2678 containerPage, 2679 CmsPropertyDefinition.PROPERTY_TEMPLATE_ELEMENTS, 2680 true).getValue(""); 2681 try { 2682 containerPage = cms.readResource(cntPagePath, CmsResourceFilter.ignoreExpirationOffline(cms)); 2683 } catch (CmsException e) { 2684 if (!LOG.isDebugEnabled()) { 2685 LOG.warn(e.getLocalizedMessage()); 2686 } 2687 LOG.debug(e.getLocalizedMessage(), e); 2688 } 2689 } 2690 return containerPage; 2691 } 2692 2693 /** 2694 * Gets the (potentially empty) set of types for which the container page is registered as a detail page. 2695 * 2696 * @param cms the CMS context 2697 * @param containerPage a container page resource 2698 * 2699 * @return the set of names of types for which the container page is a detail page 2700 */ 2701 private Set<String> getDetailTypes(CmsObject cms, CmsResource containerPage) { 2702 2703 List<CmsDetailPageInfo> infos = OpenCms.getADEManager().getAllDetailPages(cms); 2704 Set<CmsUUID> ids = new HashSet<>(); 2705 ids.add(containerPage.getStructureId()); 2706 Set<String> result = new HashSet<>(); 2707 if (containerPage.isFile()) { 2708 try { 2709 CmsResource folder = cms.readParentFolder(containerPage.getStructureId()); 2710 if (folder != null) { 2711 ids.add(folder.getStructureId()); 2712 } 2713 } catch (CmsException e) { 2714 LOG.error(e.getLocalizedMessage(), e); 2715 } 2716 } 2717 for (CmsDetailPageInfo info : infos) { 2718 if (ids.contains(info.getId())) { 2719 result.add(info.getType()); 2720 } 2721 } 2722 2723 return result; 2724 2725 } 2726 2727 /** 2728 * Returns the data of the given elements.<p> 2729 * 2730 * @param config the sitemap configuration 2731 * @param page the current container page 2732 * @param clientIds the list of IDs of the elements to retrieve the data for 2733 * @param uriParam the current URI 2734 * @param detailContentId the detail content structure id 2735 * @param containers the containers for which the element data should be fetched 2736 * @param allwaysCopy <code>true</code> in case reading data for a clipboard element used as a copy group 2737 * @param dndOriginContainer the container from which an element was dragged (null if this method is not called for DND) 2738 * @param isDragMode if the page is in drag mode 2739 * @param locale the locale to use 2740 * 2741 * @return the elements data 2742 * 2743 * @throws CmsException if something really bad happens 2744 */ 2745 private Map<String, CmsContainerElementData> getElements( 2746 CmsADEConfigData config, 2747 CmsResource page, 2748 Collection<String> clientIds, 2749 String uriParam, 2750 CmsUUID detailContentId, 2751 Collection<CmsContainer> containers, 2752 boolean allwaysCopy, 2753 String dndOriginContainer, 2754 boolean isDragMode, 2755 Locale locale) 2756 throws CmsException { 2757 2758 CmsObject cms = getCmsObject(); 2759 CmsContainerPageBean pageBean = generateContainerPageForContainers( 2760 containers, 2761 cms.getRequestContext().addSiteRoot(uriParam)); 2762 Map<String, CmsContainerElementBean> idMapping = new HashMap<String, CmsContainerElementBean>(); 2763 for (String elemId : clientIds) { 2764 if ((elemId == null)) { 2765 continue; 2766 } 2767 CmsContainerElementBean element = getCachedElement(elemId, cms.getRequestContext().addSiteRoot(uriParam)); 2768 if (element.getInstanceId() == null) { 2769 element = element.clone(); 2770 getSessionCache().setCacheContainerElement(element.editorHash(), element); 2771 } 2772 element.initResource(cms); 2773 idMapping.put(elemId, element); 2774 } 2775 List<String> foundGroups = new ArrayList<String>(); 2776 if (CmsContainerElement.MENU_CONTAINER_ID.equals(dndOriginContainer)) { 2777 // this indicates the element is added to the page and not being repositioned, check for model group data 2778 CmsModelGroupHelper modelHelper = new CmsModelGroupHelper( 2779 cms, 2780 getConfigData(uriParam), 2781 getSessionCache(), 2782 isEditingModelGroups(cms, page)); 2783 String createElementContext = CmsResource.getParentFolder(page.getRootPath()); 2784 if (detailContentId != null) { 2785 try { 2786 CmsResource detailContent = cms.readResource(detailContentId, CmsResourceFilter.IGNORE_EXPIRATION); 2787 createElementContext = CmsResource.getParentFolder( 2788 CmsDetailOnlyContainerUtil.getDetailOnlyPageName( 2789 cms, 2790 page, 2791 detailContent.getRootPath(), 2792 "" + locale)); 2793 } catch (Exception e) { 2794 LOG.error(e.getLocalizedMessage(), e); 2795 } 2796 } 2797 pageBean = modelHelper.prepareforModelGroupContent( 2798 idMapping, 2799 foundGroups, 2800 pageBean, 2801 allwaysCopy, 2802 locale, 2803 createElementContext); 2804 } 2805 2806 CmsElementUtil elemUtil = new CmsElementUtil( 2807 cms, 2808 uriParam, 2809 pageBean, 2810 detailContentId, 2811 getRequest(), 2812 getResponse(), 2813 isDragMode, 2814 locale); 2815 Map<String, CmsContainerElementData> result = new HashMap<String, CmsContainerElementData>(); 2816 Set<String> ids = new HashSet<String>(); 2817 for (Entry<String, CmsContainerElementBean> entry : idMapping.entrySet()) { 2818 CmsContainerElementBean element = entry.getValue(); 2819 String dndId = null; 2820 if (ids.contains(element.editorHash())) { 2821 continue; 2822 } 2823 if ((dndOriginContainer != null) && !CmsContainerElement.MENU_CONTAINER_ID.equals(dndOriginContainer)) { 2824 CmsFormatterConfiguration formatterConfig = elemUtil.getFormatterConfiguration(element.getResource()); 2825 Map<String, String> dndSettings = getSettingsToChangeForDnd( 2826 config, 2827 element.getIndividualSettings(), 2828 formatterConfig, 2829 containers, 2830 dndOriginContainer); 2831 if (!dndSettings.isEmpty()) { 2832 CmsContainerElementBean dndElementBean = overrideSettings(element, dndSettings); 2833 getSessionCache().setCacheContainerElement(dndElementBean.editorHash(), dndElementBean); 2834 element = dndElementBean; 2835 dndId = dndElementBean.editorHash(); 2836 Map<String, CmsContainerElementData> dndResults = getElements( 2837 config, 2838 page, 2839 Arrays.asList(dndId), 2840 uriParam, 2841 detailContentId, 2842 containers, 2843 false, 2844 null, 2845 isDragMode, 2846 locale); 2847 result.putAll(dndResults); 2848 } 2849 } 2850 2851 CmsContainerElementData elementData = elemUtil.getElementData(page, element, containers); 2852 if (elementData == null) { 2853 continue; 2854 } 2855 getSessionCache().setCacheContainerElement(element.editorHash(), element); 2856 elementData.setDndId(dndId); 2857 result.put(entry.getKey(), elementData); 2858 if (elementData.isGroupContainer() || elementData.isInheritContainer()) { 2859 // this is a group-container 2860 CmsResource elementRes = cms.readResource(element.getId()); 2861 List<CmsContainerElementBean> subElements = elementData.isGroupContainer() 2862 ? getGroupContainerElements(elementRes) 2863 : getInheritedElements(elementRes, locale, uriParam); 2864 // adding all sub-items to the elements data 2865 for (CmsContainerElementBean subElement : subElements) { 2866 getSessionCache().setCacheContainerElement(subElement.editorHash(), subElement); 2867 if (!ids.contains(subElement.editorHash())) { 2868 CmsContainerElementData subItemData = elemUtil.getElementData(page, subElement, containers); 2869 ids.add(subElement.editorHash()); 2870 result.put(subElement.editorHash(), subItemData); 2871 } 2872 } 2873 } 2874 ids.add(element.editorHash()); 2875 } 2876 for (CmsContainerElementData elementData : result.values()) { 2877 elementData.setGroup(foundGroups.contains(elementData.getClientId())); 2878 } 2879 return result; 2880 } 2881 2882 /** 2883 * Helper method for converting a CmsGroupContainer to a CmsGroupContainerBean when saving a group container.<p> 2884 * 2885 * @param groupContainer the group-container data 2886 * @param containerPage the container page 2887 * @param locale the locale to use 2888 * 2889 * @return the group-container bean 2890 */ 2891 private CmsGroupContainerBean getGroupContainerBean( 2892 CmsGroupContainer groupContainer, 2893 CmsResource containerPage, 2894 String locale) { 2895 2896 CmsObject cms = getCmsObject(); 2897 List<CmsContainerElementBean> elements = new ArrayList<CmsContainerElementBean>(); 2898 for (CmsContainerElement elementData : groupContainer.getElements()) { 2899 try { 2900 if (elementData.isNew()) { 2901 elementData = createNewElement( 2902 containerPage.getStructureId(), 2903 null, 2904 elementData.getClientId(), 2905 elementData.getResourceType(), 2906 null, 2907 locale); 2908 } 2909 CmsContainerElementBean element = getCachedElement( 2910 elementData.getClientId(), 2911 containerPage.getRootPath()); 2912 2913 // make sure resource is readable, 2914 if (cms.existsResource(element.getId(), CmsResourceFilter.IGNORE_EXPIRATION)) { 2915 elements.add(element); 2916 } 2917 2918 } catch (Exception e) { 2919 log(e.getLocalizedMessage(), e); 2920 } 2921 } 2922 return new CmsGroupContainerBean( 2923 groupContainer.getTitle(), 2924 groupContainer.getDescription(), 2925 elements, 2926 groupContainer.getTypes()); 2927 } 2928 2929 /** 2930 * Returns the sub-elements of this group container resource.<p> 2931 * 2932 * @param resource the group container resource 2933 * 2934 * @return the sub-elements 2935 * 2936 * @throws CmsException if something goes wrong reading the resource 2937 */ 2938 private List<CmsContainerElementBean> getGroupContainerElements(CmsResource resource) throws CmsException { 2939 2940 CmsXmlGroupContainer xmlGroupContainer = CmsXmlGroupContainerFactory.unmarshal( 2941 getCmsObject(), 2942 resource, 2943 getRequest()); 2944 CmsGroupContainerBean groupContainer = xmlGroupContainer.getGroupContainer(getCmsObject()); 2945 return groupContainer.getElements(); 2946 } 2947 2948 /** 2949 * Gets the structure ids of group container elements from an unmarshalled group container for a single locale.<p> 2950 * 2951 * @param groupContainer the group container 2952 * @param locale the locale for which we want the element ids 2953 * 2954 * @return the group container's element ids for the given locale 2955 */ 2956 private Set<CmsUUID> getGroupElementIds(CmsXmlGroupContainer groupContainer, Locale locale) { 2957 2958 Set<CmsUUID> idSet = new HashSet<CmsUUID>(); 2959 CmsGroupContainerBean groupContainerBean = groupContainer.getGroupContainer(getCmsObject()); 2960 if (groupContainerBean != null) { 2961 for (CmsContainerElementBean element : groupContainerBean.getElements()) { 2962 idSet.add(element.getId()); 2963 } 2964 } 2965 return idSet; 2966 2967 } 2968 2969 /** 2970 * Returns the sub-elements of this inherit container resource.<p> 2971 * 2972 * @param resource the inherit container resource 2973 * @param locale the requested locale 2974 * @param uriParam the current URI 2975 * 2976 * @return the sub-elements 2977 * 2978 * @throws CmsException if something goes wrong reading the resource 2979 */ 2980 private List<CmsContainerElementBean> getInheritedElements(CmsResource resource, Locale locale, String uriParam) 2981 throws CmsException { 2982 2983 CmsObject cms = getCmsObject(); 2984 cms.getRequestContext().setLocale(locale); 2985 CmsInheritanceReferenceParser parser = new CmsInheritanceReferenceParser(cms); 2986 parser.parse(resource); 2987 CmsInheritanceReference ref = parser.getReference(locale); 2988 if (ref == null) { 2989 // new inheritance reference, return an empty list 2990 return Collections.emptyList(); 2991 } 2992 String name = ref.getName(); 2993 CmsADEManager adeManager = OpenCms.getADEManager(); 2994 CmsInheritedContainerState result = adeManager.getInheritedContainerState(cms, cms.addSiteRoot(uriParam), name); 2995 return result.getElements(true); 2996 } 2997 2998 /** 2999 * Returns the data of the given elements.<p> 3000 * 3001 * @param listElements the list of element beans to retrieve the data for 3002 * @param containerpageUri the current URI 3003 * @param detailContentId the detail content structure id 3004 * @param containers the containers which exist on the container page 3005 * @param locale the locale to use 3006 * 3007 * @return the elements data 3008 * 3009 * @throws CmsException if something really bad happens 3010 */ 3011 private List<CmsContainerElementData> getListElementsData( 3012 List<CmsContainerElementBean> listElements, 3013 String containerpageUri, 3014 CmsUUID detailContentId, 3015 Collection<CmsContainer> containers, 3016 Locale locale) 3017 throws CmsException { 3018 3019 CmsObject cms = getCmsObject(); 3020 CmsElementUtil elemUtil = new CmsElementUtil( 3021 cms, 3022 containerpageUri, 3023 generateContainerPageForContainers(containers, cms.getRequestContext().addSiteRoot(containerpageUri)), 3024 detailContentId, 3025 getRequest(), 3026 getResponse(), 3027 true, 3028 locale); 3029 CmsADESessionCache cache = getSessionCache(); 3030 List<CmsContainerElementData> result = new ArrayList<CmsContainerElementData>(); 3031 for (CmsContainerElementBean element : listElements) { 3032 // checking if resource exists 3033 if (cms.existsResource(element.getId(), CmsResourceFilter.ONLY_VISIBLE_NO_DELETED.addRequireFile())) { 3034 try { 3035 CmsContainerElementBean clone = element.clone(); 3036 // Because ensureNewInstanceId() just generates a new UUID, 3037 // the key for the element cache will not collide with anything else, so 3038 // we do not need to set the SYSTEM::pageId setting for disambiguation here. 3039 clone.ensureNewInstanceId(); 3040 cache.setCacheContainerElement(clone.editorHash(), clone); 3041 CmsContainerElementData elementData = elemUtil.getElementData( 3042 elemUtil.getPage(), 3043 clone, 3044 containers); 3045 result.add(elementData); 3046 } catch (CmsVfsResourceNotFoundException e) { 3047 // model group id not found, or other resources 3048 LOG.info(e.getLocalizedMessage(), e); 3049 } 3050 } 3051 } 3052 return result; 3053 } 3054 3055 /** 3056 * Returns the lock information to the given resource.<p> 3057 * 3058 * @param resource the resource 3059 * 3060 * @return lock information, if the page is locked by another user 3061 * 3062 * @throws CmsException if something goes wrong reading the lock owner user 3063 */ 3064 private String getLockInfo(CmsResource resource) throws CmsException { 3065 3066 CmsObject cms = getCmsObject(); 3067 CmsResourceUtil resourceUtil = new CmsResourceUtil(cms, resource); 3068 CmsLock lock = resourceUtil.getLock(); 3069 String lockInfo = null; 3070 if (!lock.isLockableBy(cms.getRequestContext().getCurrentUser())) { 3071 if (lock.getType() == CmsLockType.PUBLISH) { 3072 lockInfo = Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 3073 Messages.GUI_LOCKED_FOR_PUBLISH_0); 3074 } else { 3075 CmsUser lockOwner = cms.readUser(lock.getUserId()); 3076 lockInfo = Messages.get().getBundle(OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)).key( 3077 Messages.GUI_LOCKED_BY_1, 3078 lockOwner.getFullName()); 3079 } 3080 } 3081 return lockInfo; 3082 } 3083 3084 /** 3085 * Returns the element data for a new element not existing in the VFS yet.<p> 3086 * 3087 * @param resourceTypeName the resource type name 3088 * @param uriParam the request parameters 3089 * @param detailContentId the detail content structure id 3090 * @param containers the containers of the template 3091 * @param locale the current locale 3092 * 3093 * @return the element data 3094 * 3095 * @throws CmsException if something goes wrong 3096 */ 3097 private CmsContainerElementData getNewElement( 3098 String resourceTypeName, 3099 String uriParam, 3100 CmsUUID detailContentId, 3101 Collection<CmsContainer> containers, 3102 Locale locale) 3103 throws CmsException { 3104 3105 CmsObject cms = getCmsObject(); 3106 CmsElementUtil elemUtil = new CmsElementUtil( 3107 cms, 3108 uriParam, 3109 generateContainerPageForContainers(containers, cms.getRequestContext().addSiteRoot(uriParam)), 3110 detailContentId, 3111 getRequest(), 3112 getResponse(), 3113 true, 3114 locale); 3115 CmsADEConfigData configData = getConfigData(cms.getRequestContext().addSiteRoot(uriParam)); 3116 CmsResourceTypeConfig typeConfig = configData.getResourceType(resourceTypeName); 3117 CmsContainerElementBean elementBean = CmsContainerElementBean.createElementForResourceType( 3118 cms, 3119 OpenCms.getResourceManager().getResourceType(resourceTypeName), 3120 "/", 3121 Collections.<String, String> emptyMap(), 3122 typeConfig.isCopyInModels(), 3123 locale); 3124 CmsContainerElementData data = elemUtil.getElementData(elemUtil.getPage(), elementBean, containers); 3125 data.setClientId(elementBean.editorHash()); 3126 getSessionCache().setCacheContainerElement(resourceTypeName, elementBean); 3127 getSessionCache().setCacheContainerElement(elementBean.editorHash(), elementBean); 3128 return data; 3129 } 3130 3131 /** 3132 * Returns the no-edit reason for the given resource.<p> 3133 * 3134 * @param cms the current cms object 3135 * @param containerPage the resource 3136 * 3137 * @return the no-edit reason, empty if editing is allowed 3138 * 3139 * @throws CmsException is something goes wrong 3140 */ 3141 private String getNoEditReason(CmsObject cms, CmsResource containerPage) throws CmsException { 3142 3143 return new CmsResourceUtil(cms, containerPage).getNoEditReason( 3144 OpenCms.getWorkplaceManager().getWorkplaceLocale(cms), 3145 !cms.getRequestContext().getCurrentProject().isOnlineProject()); 3146 } 3147 3148 /** 3149 * Returns the session cache.<p> 3150 * 3151 * @return the session cache 3152 */ 3153 private CmsADESessionCache getSessionCache() { 3154 3155 if (m_sessionCache == null) { 3156 m_sessionCache = CmsADESessionCache.getCache(getRequest(), getCmsObject()); 3157 } 3158 return m_sessionCache; 3159 } 3160 3161 /** 3162 * Returns the workplace settings of the current user.<p> 3163 * 3164 * @return the workplace settings 3165 */ 3166 private CmsWorkplaceSettings getWorkplaceSettings() { 3167 3168 if (m_workplaceSettings == null) { 3169 m_workplaceSettings = CmsWorkplace.getWorkplaceSettings(getCmsObject(), getRequest()); 3170 } 3171 return m_workplaceSettings; 3172 } 3173 3174 /** 3175 * Checks if results for the stored gallery data can be restored for the new gallery data.<p> 3176 * 3177 * @param originalGalleryData the original gallery data 3178 * @param data the new gallery data 3179 * @param search the search bean 3180 * 3181 * @return true if the original and new gallery data are compatible, i.e. we can restore the search results 3182 */ 3183 private boolean hasCompatibleSearchData( 3184 CmsGalleryDataBean originalGalleryData, 3185 CmsGalleryDataBean data, 3186 CmsGallerySearchBean search) { 3187 3188 Set<String> originalUsableTypes = Sets.newHashSet(); 3189 Set<String> usableTypes = Sets.newHashSet(); 3190 for (CmsResourceTypeBean type : originalGalleryData.getTypes()) { 3191 if (!type.isDeactivated()) { 3192 originalUsableTypes.add(type.getType()); 3193 } 3194 } 3195 for (CmsResourceTypeBean type : data.getTypes()) { 3196 if (!type.isDeactivated()) { 3197 usableTypes.add(type.getType()); 3198 } 3199 } 3200 if (!usableTypes.containsAll(originalUsableTypes)) { 3201 return false; 3202 } 3203 return true; 3204 } 3205 3206 /** 3207 * Initializes request attributes using data from the RPC context.<p> 3208 * 3209 * @param context the RPC context 3210 */ 3211 private void initRequestFromRpcContext(CmsContainerPageRpcContext context) { 3212 3213 if (context.getTemplateContext() != null) { 3214 getRequest().setAttribute( 3215 CmsTemplateContextManager.ATTR_RPC_CONTEXT_OVERRIDE, 3216 context.getTemplateContext()); 3217 } 3218 } 3219 3220 /** 3221 * Internal method for saving a group container.<p> 3222 * 3223 * @param cms the cms context 3224 * @param pageStructureId the container page structure id 3225 * @param groupContainer the group container to save 3226 * 3227 * @return the container element representing the group container 3228 * 3229 * @throws CmsException if something goes wrong 3230 * @throws CmsXmlException if the XML processing goes wrong 3231 */ 3232 private CmsPair<CmsContainerElement, List<CmsRemovedElementStatus>> internalSaveGroupContainer( 3233 CmsObject cms, 3234 CmsUUID pageStructureId, 3235 CmsGroupContainer groupContainer) 3236 throws CmsException, CmsXmlException { 3237 3238 ensureSession(); 3239 CmsResource pageResource = getCmsObject().readResource(pageStructureId, CmsResourceFilter.IGNORE_EXPIRATION); 3240 CmsResource groupContainerResource = null; 3241 if (groupContainer.isNew()) { 3242 CmsADEConfigData config = getConfigData(pageResource.getRootPath()); 3243 CmsResourceTypeConfig typeConfig = config.getResourceType( 3244 CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME); 3245 groupContainerResource = typeConfig.createNewElement(getCmsObject(), pageResource.getRootPath()); 3246 String resourceName = cms.getSitePath(groupContainerResource); 3247 groupContainer.setSitePath(resourceName); 3248 groupContainer.setClientId(groupContainerResource.getStructureId().toString()); 3249 } 3250 if (groupContainerResource == null) { 3251 CmsUUID id = convertToServerId(groupContainer.getClientId()); 3252 groupContainerResource = cms.readResource(id, CmsResourceFilter.ONLY_VISIBLE_NO_DELETED); 3253 } 3254 CmsGroupContainerBean groupContainerBean = getGroupContainerBean( 3255 groupContainer, 3256 pageResource, 3257 Locale.ENGLISH.toString()); 3258 3259 cms.lockResourceTemporary(groupContainerResource); 3260 CmsFile groupContainerFile = cms.readFile(groupContainerResource); 3261 Locale locale = Locale.ENGLISH; 3262 CmsXmlGroupContainer xmlGroupContainer = CmsXmlGroupContainerFactory.unmarshal(cms, groupContainerFile); 3263 Set<CmsUUID> oldElementIds = getGroupElementIds(xmlGroupContainer, locale); 3264 xmlGroupContainer.clearLocales(); 3265 xmlGroupContainer.save(cms, groupContainerBean, locale); 3266 cms.unlockResource(groupContainerResource); 3267 Set<CmsUUID> newElementIds = getGroupElementIds(xmlGroupContainer, locale); 3268 Set<CmsUUID> removedElementIds = Sets.difference(oldElementIds, newElementIds); 3269 List<CmsRemovedElementStatus> deletionCandidateStatuses = new ArrayList<CmsRemovedElementStatus>(); 3270 for (CmsUUID removedId : removedElementIds) { 3271 CmsRemovedElementStatus status = internalGetRemovedElementStatus(removedId, null, null); 3272 if (status.isDeletionCandidate()) { 3273 deletionCandidateStatuses.add(status); 3274 } 3275 } 3276 CmsContainerElement element = new CmsContainerElement(); 3277 element.setClientId(groupContainerFile.getStructureId().toString()); 3278 element.setSitePath(cms.getSitePath(groupContainerFile)); 3279 element.setResourceType(CmsResourceTypeXmlContainerPage.GROUP_CONTAINER_TYPE_NAME); 3280 return CmsPair.create(element, deletionCandidateStatuses); 3281 } 3282 3283 /** 3284 * Checks if small elements in a container page should be initially editable.<p> 3285 * 3286 * @param request the current request 3287 * @param cms the current CMS context 3288 * @return true if small elements should be initially editable 3289 */ 3290 private boolean isEditSmallElements(HttpServletRequest request, CmsObject cms) { 3291 3292 CmsUser user = cms.getRequestContext().getCurrentUser(); 3293 String editSmallElementsStr = (String)(user.getAdditionalInfo().get(ADDINFO_EDIT_SMALL_ELEMENTS)); 3294 if (editSmallElementsStr == null) { 3295 return true; 3296 } else { 3297 return Boolean.valueOf(editSmallElementsStr).booleanValue(); 3298 } 3299 } 3300 3301 /** 3302 * Checks if a page is a model page.<p> 3303 * 3304 * @param cms the CMS context to use 3305 * @param containerPage the page to check 3306 * 3307 * @return true if the resource is a model page 3308 */ 3309 private boolean isModelPage(CmsObject cms, CmsResource containerPage) { 3310 3311 CmsADEConfigData config = getConfigData(containerPage.getRootPath()); 3312 for (CmsModelPageConfig modelConfig : config.getModelPages()) { 3313 if (modelConfig.getResource().getStructureId().equals(containerPage.getStructureId())) { 3314 return true; 3315 } 3316 } 3317 return false; 3318 } 3319 3320 /** 3321 * Saves the given containers to the container page resource.<p> 3322 * 3323 * @param cms the cms context 3324 * @param containerpage the container page resource 3325 * @param containerpageUri the container page site path 3326 * @param containers the container to save 3327 * 3328 * @throws CmsException if something goes wrong writing the file 3329 */ 3330 private void saveContainers( 3331 CmsObject cms, 3332 CmsResource containerpage, 3333 String containerpageUri, 3334 List<CmsContainer> containers) 3335 throws CmsException { 3336 3337 CmsContainerPageBean page = generateContainerPageForContainers(containers, containerpage.getRootPath()); 3338 3339 CmsModelGroupHelper modelHelper = new CmsModelGroupHelper( 3340 getCmsObject(), 3341 getConfigData(containerpage.getRootPath()), 3342 getSessionCache(), 3343 isEditingModelGroups(cms, containerpage)); 3344 if (isEditingModelGroups(cms, containerpage)) { 3345 page = modelHelper.saveModelGroups(page, containerpage); 3346 } else { 3347 page = modelHelper.removeModelGroupContainers(page); 3348 } 3349 CmsXmlContainerPage xmlCnt = CmsXmlContainerPageFactory.unmarshal( 3350 cms, 3351 cms.readFile(containerpageUri, CmsResourceFilter.ignoreExpirationOffline(cms))); 3352 xmlCnt.save(cms, page); 3353 } 3354 3355 /** 3356 * Saves the inheritance group.<p> 3357 * 3358 * @param resource the inheritance group resource 3359 * @param inheritanceContainer the inherited group container data 3360 * 3361 * @throws CmsException if something goes wrong 3362 */ 3363 private void saveInheritanceGroup(CmsResource resource, CmsInheritanceContainer inheritanceContainer) 3364 throws CmsException { 3365 3366 CmsObject cms = getCmsObject(); 3367 CmsFile file = cms.readFile(resource); 3368 CmsXmlContent document = CmsXmlContentFactory.unmarshal(cms, file); 3369 3370 for (Locale docLocale : document.getLocales()) { 3371 document.removeLocale(docLocale); 3372 } 3373 Locale locale = Locale.ENGLISH; 3374 document.addLocale(cms, locale); 3375 document.getValue("Title", locale).setStringValue(cms, inheritanceContainer.getTitle()); 3376 document.getValue("Description", locale).setStringValue(cms, inheritanceContainer.getDescription()); 3377 document.getValue("ConfigName", locale).setStringValue(cms, inheritanceContainer.getName()); 3378 byte[] content = document.marshal(); 3379 file.setContents(content); 3380 cms.writeFile(file); 3381 } 3382 3383 /** 3384 * Update favorite or recent list with the given element.<p> 3385 * 3386 * @param containerPage the edited container page 3387 * @param clientId the elements client id 3388 * @param list the list to update 3389 * 3390 * @return the updated list 3391 * 3392 * @throws CmsException in case reading the element resource fails 3393 */ 3394 private List<CmsContainerElementBean> updateFavoriteRecentList( 3395 CmsResource containerPage, 3396 String clientId, 3397 List<CmsContainerElementBean> list) 3398 throws CmsException { 3399 3400 try { 3401 CmsContainerElementBean element = getCachedElement(clientId, containerPage.getRootPath()); 3402 Map<String, String> settings = new HashMap<String, String>(element.getIndividualSettings()); 3403 String formatterID = null; 3404 Iterator<Entry<String, String>> entries = settings.entrySet().iterator(); 3405 while (entries.hasNext()) { 3406 Entry<String, String> entry = entries.next(); 3407 if (entry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY)) { 3408 formatterID = entry.getValue(); 3409 entries.remove(); 3410 } 3411 } 3412 settings.put(CmsFormatterConfig.FORMATTER_SETTINGS_KEY, formatterID); 3413 settings.put(SOURCE_CONTAINERPAGE_ID_SETTING, containerPage.getStructureId().toString()); 3414 settings.remove(CmsContainerElement.SETTING_PAGE_ID); 3415 element = CmsContainerElementBean.cloneWithSettings(element, settings); 3416 Iterator<CmsContainerElementBean> listIt = list.iterator(); 3417 while (listIt.hasNext()) { 3418 CmsContainerElementBean listElem = listIt.next(); 3419 if (element.getInstanceId().equals(listElem.getInstanceId())) { 3420 listIt.remove(); 3421 } 3422 } 3423 list.add(0, element); 3424 return list; 3425 } catch (CmsVfsResourceNotFoundException e) { 3426 LOG.warn(e.getLocalizedMessage(), e); 3427 return list; 3428 } 3429 } 3430 3431}