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