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