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