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.CmsElementView; 032import org.opencms.ade.configuration.CmsResourceTypeConfig; 033import org.opencms.ade.containerpage.inherited.CmsContainerConfigurationCache; 034import org.opencms.ade.containerpage.inherited.CmsInheritanceReference; 035import org.opencms.ade.containerpage.inherited.CmsInheritanceReferenceParser; 036import org.opencms.ade.containerpage.inherited.CmsInheritedContainerState; 037import org.opencms.ade.containerpage.shared.CmsContainer; 038import org.opencms.ade.containerpage.shared.CmsContainerElement; 039import org.opencms.ade.containerpage.shared.CmsContainerElement.ModelGroupState; 040import org.opencms.ade.containerpage.shared.CmsContainerElementData; 041import org.opencms.ade.containerpage.shared.CmsElementLockInfo; 042import org.opencms.ade.containerpage.shared.CmsElementSettingsConfig; 043import org.opencms.ade.containerpage.shared.CmsFormatterConfig; 044import org.opencms.ade.containerpage.shared.CmsFormatterConfigCollection; 045import org.opencms.ade.containerpage.shared.CmsInheritanceInfo; 046import org.opencms.ade.detailpage.CmsDetailPageResourceHandler; 047import org.opencms.configuration.CmsConfigurationException; 048import org.opencms.db.CmsResourceState; 049import org.opencms.file.CmsFile; 050import org.opencms.file.CmsObject; 051import org.opencms.file.CmsRequestContext; 052import org.opencms.file.CmsResource; 053import org.opencms.file.CmsResourceFilter; 054import org.opencms.file.CmsUser; 055import org.opencms.file.types.CmsResourceTypeXmlContainerPage; 056import org.opencms.file.types.CmsResourceTypeXmlContent; 057import org.opencms.file.types.I_CmsResourceType; 058import org.opencms.gwt.CmsDefaultResourceStatusProvider; 059import org.opencms.gwt.CmsIconUtil; 060import org.opencms.gwt.shared.CmsAdditionalInfoBean; 061import org.opencms.gwt.shared.CmsPermissionInfo; 062import org.opencms.i18n.CmsMessageContainer; 063import org.opencms.i18n.CmsMessages; 064import org.opencms.jsp.util.CmsJspStandardContextBean; 065import org.opencms.jsp.util.CmsJspStandardContextBean.TemplateBean; 066import org.opencms.loader.CmsTemplateContextManager; 067import org.opencms.lock.CmsLock; 068import org.opencms.main.CmsException; 069import org.opencms.main.CmsLog; 070import org.opencms.main.OpenCms; 071import org.opencms.relations.CmsRelation; 072import org.opencms.relations.CmsRelationFilter; 073import org.opencms.relations.CmsRelationType; 074import org.opencms.search.galleries.CmsGallerySearch; 075import org.opencms.search.galleries.CmsGallerySearchResult; 076import org.opencms.util.CmsDateUtil; 077import org.opencms.util.CmsStringUtil; 078import org.opencms.util.CmsUUID; 079import org.opencms.workplace.CmsWorkplaceMessages; 080import org.opencms.workplace.editors.CmsWorkplaceEditorManager; 081import org.opencms.workplace.editors.directedit.CmsAdvancedDirectEditProvider; 082import org.opencms.workplace.editors.directedit.CmsDirectEditMode; 083import org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider; 084import org.opencms.workplace.explorer.CmsExplorerTypeSettings; 085import org.opencms.workplace.explorer.CmsResourceUtil; 086import org.opencms.xml.containerpage.CmsADESessionCache; 087import org.opencms.xml.containerpage.CmsContainerBean; 088import org.opencms.xml.containerpage.CmsContainerElementBean; 089import org.opencms.xml.containerpage.CmsContainerPageBean; 090import org.opencms.xml.containerpage.CmsFormatterConfiguration; 091import org.opencms.xml.containerpage.CmsGroupContainerBean; 092import org.opencms.xml.containerpage.CmsXmlContainerPage; 093import org.opencms.xml.containerpage.CmsXmlContainerPageFactory; 094import org.opencms.xml.containerpage.CmsXmlGroupContainer; 095import org.opencms.xml.containerpage.CmsXmlGroupContainerFactory; 096import org.opencms.xml.containerpage.I_CmsFormatterBean; 097import org.opencms.xml.content.CmsXmlContent; 098import org.opencms.xml.content.CmsXmlContentFactory; 099import org.opencms.xml.content.CmsXmlContentProperty; 100import org.opencms.xml.content.CmsXmlContentPropertyHelper; 101 102import java.io.IOException; 103import java.text.DateFormat; 104import java.util.ArrayList; 105import java.util.Collection; 106import java.util.Collections; 107import java.util.Date; 108import java.util.HashMap; 109import java.util.LinkedHashMap; 110import java.util.LinkedHashSet; 111import java.util.List; 112import java.util.Locale; 113import java.util.Map; 114import java.util.Map.Entry; 115import java.util.Set; 116import java.util.function.Function; 117import java.util.regex.Matcher; 118import java.util.regex.Pattern; 119 120import javax.servlet.ServletException; 121import javax.servlet.http.HttpServletRequest; 122import javax.servlet.http.HttpServletResponse; 123 124import org.apache.commons.logging.Log; 125 126import com.google.common.base.Supplier; 127import com.google.common.base.Suppliers; 128import com.google.common.collect.Sets; 129 130/** 131 * Utility class to generate the element data objects used within the container-page editor.<p> 132 * 133 * @since 8.0.0 134 */ 135public class CmsElementUtil { 136 137 /** The maximum number of nested container levels. */ 138 public static final int MAX_NESTING_LEVEL = 7; 139 140 /** Static reference to the log. */ 141 private static final Log LOG = CmsLog.getLog(org.opencms.ade.containerpage.CmsElementUtil.class); 142 143 /** The ADE configuration data for the current page URI. */ 144 private CmsADEConfigData m_adeConfig; 145 146 /** The cms context. */ 147 private CmsObject m_cms; 148 149 /** The current page uri. */ 150 private String m_currentPageUri; 151 152 /** The content locale. */ 153 private Locale m_locale; 154 155 /** The current container page. */ 156 private CmsResource m_page; 157 158 /** The request parameters to use while rendering the elements. */ 159 @SuppressWarnings("unused") 160 private Map<String, Object> m_parameterMap; 161 162 /** The http request. */ 163 private HttpServletRequest m_req; 164 165 /** The http response. */ 166 private HttpServletResponse m_res; 167 168 /** The standard context bean. */ 169 private CmsJspStandardContextBean m_standardContext; 170 171 /** 172 * Creates a new instance.<p> 173 * Use this constructor to set the current container page state.<p> 174 * 175 * @param cms the cms context 176 * @param currentPageUri the current page uri 177 * @param containerPage the container page bean with the current container state 178 * @param detailContentId the detail content structure id 179 * @param req the http request 180 * @param res the http response 181 * @param isDragMode if the page is in drag mode 182 * @param locale the content locale 183 * 184 * @throws CmsException if something goes wrong 185 */ 186 public CmsElementUtil( 187 CmsObject cms, 188 String currentPageUri, 189 CmsContainerPageBean containerPage, 190 CmsUUID detailContentId, 191 HttpServletRequest req, 192 HttpServletResponse res, 193 boolean isDragMode, 194 Locale locale) 195 throws CmsException { 196 197 m_cms = OpenCms.initCmsObject(cms); 198 String contextPath = (String)cms.getRequestContext().getAttribute(CmsRequestContext.ATTRIBUTE_ADE_CONTEXT_PATH); 199 if (contextPath != null) { 200 m_cms.getRequestContext().setAttribute(CmsRequestContext.ATTRIBUTE_ADE_CONTEXT_PATH, contextPath); 201 } 202 m_req = req; 203 m_res = res; 204 m_currentPageUri = currentPageUri; 205 m_locale = locale; 206 // initializing request for standard context bean 207 req.setAttribute(CmsJspStandardContextBean.ATTRIBUTE_CMS_OBJECT, m_cms); 208 if (detailContentId != null) { 209 CmsResource detailRes = m_cms.readResource( 210 detailContentId, 211 CmsResourceFilter.ignoreExpirationOffline(m_cms)); 212 req.setAttribute(CmsDetailPageResourceHandler.ATTR_DETAIL_CONTENT_RESOURCE, detailRes); 213 } 214 m_standardContext = CmsJspStandardContextBean.getInstance(req); 215 m_page = m_cms.readResource(currentPageUri, CmsResourceFilter.ignoreExpirationOffline(cms)); 216 m_standardContext.setPage(containerPage); 217 m_standardContext.setDragMode(isDragMode); 218 } 219 220 /** 221 * Creates a new instance.<p> 222 * 223 * @param cms the cms context 224 * @param currentPageUri the current page uri 225 * @param detailContentId the detail content structure id 226 * @param req the http request 227 * @param res the http response 228 * @param locale the content locale 229 * 230 * @throws CmsException if something goes wrong 231 */ 232 public CmsElementUtil( 233 CmsObject cms, 234 String currentPageUri, 235 CmsUUID detailContentId, 236 HttpServletRequest req, 237 HttpServletResponse res, 238 Locale locale) 239 throws CmsException { 240 241 m_cms = OpenCms.initCmsObject(cms); 242 m_req = req; 243 m_res = res; 244 m_currentPageUri = currentPageUri; 245 m_locale = locale; 246 // initializing request for standard context bean 247 req.setAttribute(CmsJspStandardContextBean.ATTRIBUTE_CMS_OBJECT, m_cms); 248 if (detailContentId != null) { 249 CmsResource detailRes = m_cms.readResource(detailContentId, CmsResourceFilter.ignoreExpirationOffline(cms)); 250 req.setAttribute(CmsDetailPageResourceHandler.ATTR_DETAIL_CONTENT_RESOURCE, detailRes); 251 } 252 m_standardContext = CmsJspStandardContextBean.getInstance(req); 253 m_page = m_cms.readResource(currentPageUri); 254 CmsXmlContainerPage xmlContainerPage = CmsXmlContainerPageFactory.unmarshal(cms, m_page, req); 255 CmsContainerPageBean containerPage = xmlContainerPage.getContainerPage(cms); 256 m_standardContext.setPage(containerPage); 257 } 258 259 /** 260 * Creates a new instance.<p> 261 * 262 * @param cms the cms context 263 * @param currentPageUri the current page uri 264 * @param detailContentId the detail content structure id 265 * @param requestParameters the request parameters to use while rendering the elements 266 * @param req the http request 267 * @param res the http response 268 * @param locale the content locale 269 * 270 * @throws CmsException if something goes wrong 271 */ 272 public CmsElementUtil( 273 CmsObject cms, 274 String currentPageUri, 275 CmsUUID detailContentId, 276 String requestParameters, 277 HttpServletRequest req, 278 HttpServletResponse res, 279 Locale locale) 280 throws CmsException { 281 282 this(cms, currentPageUri, detailContentId, req, res, locale); 283 m_parameterMap = parseRequestParameters(requestParameters); 284 } 285 286 /** 287 * Checks if a group element is allowed in a container with a given type.<p> 288 * 289 * @param containerType the container type spec (comma separated) 290 * @param groupContainer the group 291 * 292 * @return true if the group is allowed in the container 293 */ 294 public static boolean checkGroupAllowed(String containerType, CmsGroupContainerBean groupContainer) { 295 296 return !Sets.intersection(CmsContainer.splitType(containerType), groupContainer.getTypes()).isEmpty(); 297 } 298 299 public static CmsContainerBean clientToServerContainer( 300 CmsContainer container, 301 List<CmsContainerElementBean> elements) { 302 303 return new CmsContainerBean( 304 container.getName(), 305 container.getType(), 306 container.getParentInstanceId(), 307 container.isRootContainer(), 308 container.getMaxElements(), 309 elements); 310 311 } 312 313 /** 314 * Helper method to create a string template source for a given formatter and content. 315 * 316 * @param formatter the formatter 317 * @param contentSupplier the content supplier 318 * 319 * @return the string template provider 320 */ 321 public static Function<String, String> createStringTemplateSource( 322 I_CmsFormatterBean formatter, 323 Supplier<CmsXmlContent> contentSupplier) { 324 325 return key -> { 326 String result = null; 327 if (formatter != null) { 328 result = formatter.getAttributes().get(key); 329 } 330 if (result == null) { 331 CmsXmlContent content = contentSupplier.get(); 332 if (content != null) { 333 result = content.getHandler().getParameter(key); 334 } 335 } 336 return result; 337 }; 338 } 339 340 /** 341 * Returns the formatter bean for the given element and container.<p> 342 * 343 * @param cms the cms context 344 * @param element the element to render 345 * @param container the container 346 * @param config the configuration data 347 * @param cache the session cache 348 * 349 * @return the formatter bean 350 */ 351 public static I_CmsFormatterBean getFormatterForContainer( 352 CmsObject cms, 353 CmsContainerElementBean element, 354 CmsContainer container, 355 CmsADEConfigData config, 356 CmsADESessionCache cache) { 357 358 I_CmsFormatterBean formatter = null; 359 CmsFormatterConfiguration formatterSet = config.getFormatters(cms, element.getResource()); 360 Map<String, I_CmsFormatterBean> formatters = formatterSet.getFormatterSelectionByKeyOrId( 361 container.getType(), 362 container.getWidth()); 363 String formatterId = element.getIndividualSettings().get( 364 CmsFormatterConfig.getSettingsKeyForContainer(container.getName())); 365 if (formatterId != null) { 366 I_CmsFormatterBean dynamicFmt = config.findFormatter(formatterId); 367 if (dynamicFmt != null) { 368 formatter = dynamicFmt; 369 } else { 370 formatter = formatters.get(formatterId); 371 } 372 } 373 if (formatter == null) { 374 formatterId = element.getIndividualSettings().get(CmsFormatterConfig.FORMATTER_SETTINGS_KEY); 375 if (formatterId != null) { 376 formatter = lookupFormatter(config, formatterId, formatters); 377 } 378 } 379 if (formatter == null) { 380 // check for formatter config id stored for other containers matching the current container 381 for (Entry<String, String> settingsEntry : element.getIndividualSettings().entrySet()) { 382 if (settingsEntry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY)) { 383 formatter = lookupFormatter(config, settingsEntry.getValue(), formatters); 384 if (formatter != null) { 385 break; 386 } 387 } 388 } 389 } 390 if ((formatter == null) && (element.getFormatterId() != null)) { 391 for (I_CmsFormatterBean currentFormatter : formatters.values()) { 392 if ((currentFormatter.getJspStructureId() != null) 393 && currentFormatter.getJspStructureId().equals(element.getFormatterId())) { 394 formatter = currentFormatter; 395 break; 396 } 397 } 398 } 399 if (formatter == null) { 400 formatter = getStartFormatter(cms, container, config, element, cache); 401 } 402 return formatter; 403 } 404 405 /** 406 * Checks if the given setting name is a system setting. 407 * 408 * @param name the setting name 409 * @return true if the name corresponds to a system setting 410 */ 411 public static final boolean isSystemSetting(String name) { 412 413 if (CmsXmlContainerPage.LEGACY_SYSTEM_SETTING_NAMES.contains(name) 414 || CmsContainerElement.ELEMENT_INSTANCE_ID.equals(name) 415 || name.startsWith(CmsXmlContainerPage.SYSTEM_SETTING_PREFIX) 416 || name.startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY)) { 417 return true; 418 } 419 return false; 420 } 421 422 /** 423 * Returns the start formatter for a newly dropped element.<p> 424 * This will be either the least recently used matching formatter or the default formatter.<p> 425 * 426 * @param cms the cms context 427 * @param cnt the container 428 * @param configData the configuration data 429 * @param element the container element 430 * @param cache the session cache 431 * 432 * @return the formatter bean 433 */ 434 private static I_CmsFormatterBean getStartFormatter( 435 CmsObject cms, 436 CmsContainer cnt, 437 CmsADEConfigData configData, 438 CmsContainerElementBean element, 439 CmsADESessionCache cache) { 440 441 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 442 I_CmsFormatterBean formatter = cache.getRecentFormatter(type.getTypeName(), cnt, configData); 443 if (formatter == null) { 444 formatter = configData.getFormatters(cms, element.getResource()).getDefaultFormatter( 445 cnt.getType(), 446 cnt.getWidth()); 447 } 448 return formatter; 449 } 450 451 /** 452 * Helper method for looking up the correct formatter for an element. 453 * 454 * @param config the sitemap config 455 * @param keyOrId the key or id of the formatter stored with the container element 456 * @param active map of active formatters by key or id 457 * 458 * @return the formatter with the given key or id 459 */ 460 private static I_CmsFormatterBean lookupFormatter( 461 CmsADEConfigData config, 462 String keyOrId, 463 Map<String, I_CmsFormatterBean> active) { 464 465 I_CmsFormatterBean dynamicFmt = config.findFormatter(keyOrId); 466 if (dynamicFmt != null) { 467 for (String key : new String[] {dynamicFmt.getKey(), dynamicFmt.getId(), keyOrId}) { 468 if ((key != null) && (active.get(key) != null)) { 469 return active.get(key); 470 } 471 } 472 return null; 473 } else { 474 // schema formatters 475 return active.get(keyOrId); 476 } 477 } 478 479 /** 480 * Returns the HTML content for the given resource and container.<p> 481 * 482 * @param elementFile the element resource file 483 * @param elementId the element id 484 * @param container the container 485 * 486 * @return the HTML content 487 */ 488 public String getContentByContainer(CmsFile elementFile, String elementId, CmsContainer container) { 489 490 CmsContainerElementBean element = CmsADESessionCache.getCache(m_req, m_cms).getCacheContainerElement(elementId); 491 element = element.clone(); 492 element.setTemporaryFile(elementFile); 493 CmsFormatterConfiguration configs = getFormatterConfiguration(element.getResource()); 494 return getContentByContainer(element, container, configs); 495 } 496 497 /** 498 * Returns the data for an element.<p> 499 * 500 * @param page the current container page 501 * @param element the resource 502 * @param containers the containers on the current container page 503 * 504 * @return the data for an element 505 * 506 * @throws CmsException if something goes wrong 507 */ 508 public CmsContainerElementData getElementData( 509 CmsResource page, 510 CmsContainerElementBean element, 511 Collection<CmsContainer> containers) 512 throws CmsException { 513 514 Locale requestLocale = m_cms.getRequestContext().getLocale(); 515 m_cms.getRequestContext().setLocale(m_locale); 516 element.initResource(m_cms); 517 if (element.getResource().isFolder()) { 518 return null; 519 } 520 boolean typeDisabled = false; 521 boolean createDisabled = false; 522 if (page != null) { 523 524 CmsADEConfigData config = OpenCms.getADEManager().lookupConfigurationWithCache(m_cms, page.getRootPath()); 525 String typeName = OpenCms.getResourceManager().getResourceType(element.getResource()).getTypeName(); 526 if (!config.getAddableTypeNames().contains(typeName)) { 527 typeDisabled = true; 528 } 529 CmsResourceTypeConfig typeConfig = config.getTypesByName().get(typeName); 530 if ((typeConfig == null) || typeConfig.isCreateDisabled()) { 531 createDisabled = true; 532 } 533 } 534 535 CmsContainerElementData elementData = getBaseElementData(page, element); 536 elementData.setAddDisabled(typeDisabled); 537 elementData.setCopyDisabled(createDisabled); 538 CmsFormatterConfiguration formatterConfiguraton = getFormatterConfiguration(element.getResource()); 539 Map<String, String> contents = new HashMap<String, String>(); 540 if (element.isGroupContainer(m_cms)) { 541 Map<String, CmsContainer> containersByName = new HashMap<String, CmsContainer>(); 542 for (CmsContainer container : containers) { 543 containersByName.put(container.getName(), container); 544 } 545 CmsXmlGroupContainer xmlGroupContainer = CmsXmlGroupContainerFactory.unmarshal( 546 m_cms, 547 element.getResource(), 548 m_req); 549 CmsGroupContainerBean groupContainer = xmlGroupContainer.getGroupContainer(m_cms); 550 // make sure to use the content title and not the property title 551 elementData.setTitle(groupContainer.getTitle()); 552 elementData.setTypes(groupContainer.getTypes()); 553 elementData.setDescription(groupContainer.getDescription()); 554 if (groupContainer.getTypes().isEmpty()) { 555 if (groupContainer.getElements().isEmpty()) { 556 String emptySub = "<div>NEW AND EMPTY</div>"; 557 for (CmsContainer cont : containersByName.values()) { 558 if (formatterConfiguraton.hasFormatter(cont.getType(), cont.getWidth())) { 559 contents.put(cont.getName(), emptySub); 560 } 561 } 562 } else { 563 // TODO: throw appropriate exception 564 return null; 565 } 566 } else { 567 568 // add formatter and content entries for the supported types 569 for (CmsContainer cnt : containersByName.values()) { 570 571 String type = cnt.getType(); 572 if (checkGroupAllowed(type, groupContainer)) { 573 contents.put(cnt.getName(), "<div>should not be used</div>"); 574 } 575 } 576 } 577 // add subitems 578 List<String> subItems = new ArrayList<String>(); 579 580 for (CmsContainerElementBean subElement : groupContainer.getElements()) { 581 // collect ids 582 subItems.add(subElement.editorHash()); 583 } 584 elementData.setSubItems(subItems); 585 } else if (element.isInheritedContainer(m_cms)) { 586 CmsInheritanceReferenceParser parser = new CmsInheritanceReferenceParser(m_cms); 587 parser.parse(element.getResource()); 588 CmsInheritanceReference ref = parser.getReference(m_locale); 589 String name = null; 590 // check for new inheritance reference 591 if (ref != null) { 592 name = ref.getName(); 593 elementData.setDescription(ref.getDescription()); 594 elementData.setTitle(ref.getTitle()); 595 } 596 for (CmsContainer container : containers) { 597 if (formatterConfiguraton.hasFormatter(container.getType(), container.getWidth())) { 598 contents.put(container.getName(), "<div>should not be used</div>"); 599 } 600 } 601 602 List<CmsInheritanceInfo> inheritanceInfos = new ArrayList<CmsInheritanceInfo>(); 603 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(name)) { 604 CmsInheritedContainerState result = OpenCms.getADEManager().getInheritedContainerState( 605 m_cms, 606 m_cms.addSiteRoot(m_currentPageUri), 607 name); 608 for (CmsContainerElementBean subElement : result.getElements(true)) { 609 CmsInheritanceInfo inheritanceInfo = subElement.getInheritanceInfo(); 610 inheritanceInfo.setClientId(subElement.editorHash()); 611 inheritanceInfos.add(inheritanceInfo); 612 } 613 } else { 614 // setting a new id for name, will be persisted once the inheritance reference is edited and saved. 615 // use the structure id so it will always be the same for the resource 616 name = element.getResource().getStructureId().toString(); 617 } 618 elementData.setInheritanceInfos(inheritanceInfos); 619 elementData.setInheritanceName(name); 620 } else { 621 622 for (CmsContainer cnt : containers) { 623 boolean missesFormatterSetting = !elementData.getSettings().containsKey( 624 CmsFormatterConfig.getSettingsKeyForContainer(cnt.getName())); 625 if (missesFormatterSetting) { 626 if (element.getFormatterId() == null) { 627 I_CmsFormatterBean formatter = getStartFormatter( 628 m_cms, 629 cnt, 630 m_adeConfig, 631 element, 632 CmsADESessionCache.getCache(m_req, m_cms)); 633 if (formatter != null) { 634 elementData.getSettings().put( 635 CmsFormatterConfig.getSettingsKeyForContainer(cnt.getName()), 636 formatter.getId()); 637 element.addFormatterSetting(cnt.getName(), formatter.getKeyOrId()); 638 } 639 } else { 640 Map<String, I_CmsFormatterBean> formatterSelection = formatterConfiguraton.getFormatterSelection( 641 cnt.getType(), 642 cnt.getWidth()); 643 for (Entry<String, I_CmsFormatterBean> formatterEntry : formatterSelection.entrySet()) { 644 I_CmsFormatterBean formatter = formatterEntry.getValue(); 645 String id = formatterEntry.getKey(); 646 if (element.getFormatterId().equals(formatter.getJspStructureId())) { 647 elementData.getSettings().put( 648 CmsFormatterConfig.getSettingsKeyForContainer(cnt.getName()), 649 formatter.getKeyOrId()); 650 break; 651 } 652 } 653 } 654 } 655 } 656 // get the formatter configuration 657 Map<String, String> contentsByName = getContentsByContainerName(element, containers); 658 contents = contentsByName; 659 } 660 elementData.setContents(contents); 661 m_cms.getRequestContext().setLocale(requestLocale); 662 return elementData; 663 } 664 665 /** 666 * Returns the formatter and settings config data for an element.<p> 667 * 668 * @param page the current container page 669 * @param element the resource 670 * @param containerId the parent container id 671 * @param containers the containers on the current container page 672 * 673 * @return the data for an element 674 * 675 * @throws CmsException if something goes wrong 676 */ 677 public CmsElementSettingsConfig getElementSettingsConfig( 678 CmsResource page, 679 CmsContainerElementBean element, 680 String containerId, 681 Collection<CmsContainer> containers) 682 throws CmsException { 683 684 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms); 685 CmsADEConfigData adeConfig = OpenCms.getADEManager().lookupConfigurationWithCache(m_cms, page.getRootPath()); 686 Locale requestLocale = m_cms.getRequestContext().getLocale(); 687 m_cms.getRequestContext().setLocale(m_locale); 688 element.initResource(m_cms); 689 if (element.getResource().isFolder()) { 690 return null; 691 } 692 String schema = null; 693 try { 694 I_CmsResourceType type = OpenCms.getResourceManager().getResourceType(element.getResource()); 695 schema = type.getConfiguration().getString("schema", null); 696 } catch (Exception e) { 697 LOG.error(e.getLocalizedMessage(), e); 698 } 699 CmsContainerElementData elementData = getBaseElementData(page, element); 700 701 Map<String, String> settingUpdates = new HashMap<>(); 702 for (Map.Entry<String, String> entry : elementData.getSettings().entrySet()) { 703 int underscorePos = entry.getKey().indexOf("_"); 704 if ((underscorePos >= 0) && !isSystemSetting(entry.getKey())) { 705 String prefix = entry.getKey().substring(0, underscorePos); 706 I_CmsFormatterBean dynamicFmt = adeConfig.findFormatter(prefix, true); 707 708 if (CmsUUID.isValidUUID(prefix)) { 709 // If we already have a formatter referenced by name, we don't need to do anything 710 if ((dynamicFmt != null) && (dynamicFmt.getKey() != null)) { 711 // Replace setting prefix with formatter key 712 String newSettingName = dynamicFmt.getKey() + entry.getKey().substring(underscorePos); 713 settingUpdates.put(newSettingName, entry.getValue()); 714 settingUpdates.put(entry.getKey(), null); 715 } 716 } 717 } 718 719 if (entry.getKey().startsWith(CmsFormatterConfig.FORMATTER_SETTINGS_KEY)) { 720 String value = entry.getValue(); 721 if (CmsUUID.isValidUUID(value)) { 722 I_CmsFormatterBean dynamicFmt = adeConfig.findFormatter(value); 723 if ((dynamicFmt != null) && (dynamicFmt.getKey() != null)) { 724 settingUpdates.put(entry.getKey(), dynamicFmt.getKey()); 725 } 726 } 727 } 728 } 729 for (String key : settingUpdates.keySet()) { 730 String value = settingUpdates.get(key); 731 if (value == null) { 732 elementData.getSettings().remove(key); 733 } else { 734 elementData.getSettings().put(key, value); 735 } 736 } 737 Supplier<CmsXmlContent> contentSupplier = Suppliers.memoize(() -> { 738 try { 739 return CmsXmlContentFactory.unmarshal(m_cms, m_cms.readFile(element.getResource())); 740 } catch (CmsException e) { 741 LOG.error(e.getLocalizedMessage(), e); 742 return null; 743 } 744 }); 745 I_CmsFormatterBean foundFormatter = null; 746 747 if (!element.isGroupContainer(m_cms) && !element.isInheritedContainer(m_cms)) { 748 CmsFormatterConfiguration formatterConfiguraton = getFormatterConfiguration(element.getResource()); 749 Map<String, CmsFormatterConfigCollection> formatters = new HashMap<String, CmsFormatterConfigCollection>(); 750 for (CmsContainer cnt : containers) { 751 if (cnt.getName().equals(containerId)) { 752 CmsFormatterConfigCollection containerFormatters = new CmsFormatterConfigCollection(); 753 String foundFormatterKey = null; 754 for (String containerName : new String[] {cnt.getName(), ""}) { 755 foundFormatterKey = elementData.getSettings().get( 756 CmsFormatterConfig.getSettingsKeyForContainer(containerName)); 757 if (foundFormatterKey != null) { 758 break; 759 } 760 } 761 boolean missesFormatterSetting = (foundFormatterKey == null); 762 if (!missesFormatterSetting) { 763 foundFormatter = adeConfig.findFormatter(foundFormatterKey); 764 } 765 Map<String, I_CmsFormatterBean> formatterSelection = formatterConfiguraton.getFormatterSelection( 766 cnt.getType(), 767 cnt.getWidth()); 768 for (Entry<String, I_CmsFormatterBean> formatterEntry : formatterSelection.entrySet()) { 769 I_CmsFormatterBean formatter = formatterEntry.getValue(); 770 String id = formatterEntry.getValue().getId(); 771 if (missesFormatterSetting 772 && ((element.getFormatterId() == null) 773 || element.getFormatterId().equals(formatter.getJspStructureId()))) { 774 elementData.getSettings().put( 775 CmsFormatterConfig.getSettingsKeyForContainer(cnt.getName()), 776 id); 777 missesFormatterSetting = false; 778 } 779 String label = formatter.getNiceName(OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms)); 780 if (formatterEntry.getKey().startsWith(CmsFormatterConfig.SCHEMA_FORMATTER_ID)) { 781 label = Messages.get().getBundle().key(Messages.GUI_SCHEMA_FORMATTER_LABEL_0) 782 + " [" 783 + CmsResource.getName(formatter.getJspRootPath()) 784 + "]"; 785 } 786 if (CmsStringUtil.isEmptyOrWhitespaceOnly(label)) { 787 label = id; 788 } 789 CmsFormatterConfig config = new CmsFormatterConfig(id); 790 Set<String> cssResources = new LinkedHashSet<String>(); 791 for (String cssSitePath : formatter.getCssHeadIncludes()) { 792 cssResources.add(OpenCms.getLinkManager().getOnlineLink(m_cms, cssSitePath)); 793 } 794 config.setCssResources(cssResources); 795 config.setInlineCss(formatter.getInlineCss()); 796 config.setKey(formatter.getKey()); 797 config.setLabel(label); 798 config.setDescription( 799 formatter.getDescription(OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms))); 800 Map<String, CmsXmlContentProperty> settingsConfig = OpenCms.getADEManager().getFormatterSettings( 801 m_cms, 802 adeConfig, 803 formatter, 804 element.getResource(), 805 m_locale, 806 m_req); 807 Function<String, String> templateSource = createStringTemplateSource( 808 formatter, 809 contentSupplier); 810 settingsConfig = CmsXmlContentPropertyHelper.resolveMacrosForPropertyInfo( 811 m_cms, 812 page, 813 element.getResource(), 814 contentSupplier, 815 templateSource, 816 settingsConfig); 817 config.setSettingConfig(settingsConfig); 818 List<I_CmsFormatterBean> nestedFormatters = OpenCms.getADEManager().getNestedFormatters( 819 m_cms, 820 adeConfig, 821 element.getResource(), 822 m_locale, 823 m_req); 824 if ((nestedFormatters != null) && !nestedFormatters.isEmpty()) { 825 Map<String, String> settingPrefixes = new LinkedHashMap<String, String>(); 826 for (I_CmsFormatterBean nested : nestedFormatters) { 827 String sectionLabel = nested.getNiceName( 828 OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms)); 829 settingPrefixes.put(nested.getId(), sectionLabel); 830 if (nested.getKey() != null) { 831 settingPrefixes.put(nested.getKey() + "_", sectionLabel); 832 } 833 } 834 config.setNestedFormatterPrefixes(settingPrefixes); 835 } 836 837 config.setJspRootPath(formatter.getJspRootPath()); 838 containerFormatters.add(config); 839 } 840 formatters.put(cnt.getName(), containerFormatters); 841 } 842 } 843 elementData.setFormatters(formatters); 844 } 845 846 m_cms.getRequestContext().setLocale(requestLocale); 847 ArrayList<CmsAdditionalInfoBean> infos = new ArrayList<>(); 848 849 CmsResource resource = element.getResource(); 850 String resTypeName = OpenCms.getResourceManager().getResourceType(resource).getTypeName(); 851 CmsExplorerTypeSettings cmsExplorerTypeSettings = OpenCms.getWorkplaceManager().getExplorerTypeSetting( 852 resTypeName); 853 if (null == cmsExplorerTypeSettings) { 854 CmsMessageContainer errMsg = org.opencms.gwt.Messages.get().container( 855 org.opencms.gwt.Messages.ERR_EXPLORER_TYPE_SETTINGS_FOR_RESOURCE_TYPE_NOT_FOUND_3, 856 resource.getRootPath(), 857 resTypeName, 858 Integer.valueOf(resource.getTypeId())); 859 throw new CmsConfigurationException(errMsg); 860 } 861 String key = cmsExplorerTypeSettings.getKey(); 862 Locale currentLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms); 863 CmsMessages messages = OpenCms.getWorkplaceManager().getMessages(currentLocale); 864 String resTypeNiceName = messages.key(key); 865 infos.add( 866 new CmsAdditionalInfoBean( 867 messages.key(org.opencms.workplace.commons.Messages.GUI_LABEL_TYPE_0), 868 resTypeNiceName, 869 null)); 870 871 try { 872 CmsRelationFilter filter = CmsRelationFilter.relationsFromStructureId( 873 element.getResource().getStructureId()).filterType(CmsRelationType.XSD); 874 for (CmsRelation relation : m_cms.readRelations(filter)) { 875 CmsResource target = relation.getTarget(m_cms, CmsResourceFilter.IGNORE_EXPIRATION); 876 String label = Messages.get().getBundle(wpLocale).key(Messages.GUI_ADDINFO_SCHEMA_0); 877 infos.add(new CmsAdditionalInfoBean(label, target.getRootPath(), null)); 878 break; 879 } 880 } catch (CmsException e) { 881 LOG.error(e.getLocalizedMessage(), e); 882 } 883 if (foundFormatter != null) { 884 Map<String, String> formatterInfo = CmsDefaultResourceStatusProvider.getFormatterInfo( 885 m_cms, 886 foundFormatter); 887 for (Map.Entry<String, String> entry : formatterInfo.entrySet()) { 888 infos.add(new CmsAdditionalInfoBean(entry.getKey(), entry.getValue(), null)); 889 } 890 } 891 892 CmsResourceState state = element.getResource().getState(); 893 return new CmsElementSettingsConfig(elementData, state, infos, schema); 894 } 895 896 /** 897 * Gets the container page.<p> 898 * 899 * @return the container page resource 900 */ 901 public CmsResource getPage() { 902 903 return m_page; 904 } 905 906 /** 907 * Sets the data to the given container element.<p> 908 * 909 * @param elementBean the element bean 910 * @param result the container element to set the data to 911 * 912 * @return the container element 913 * 914 * @throws CmsException if something goes wrong 915 */ 916 public CmsContainerElement setElementInfo(CmsContainerElementBean elementBean, CmsContainerElement result) 917 throws CmsException { 918 919 Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms); 920 // reinitializing resource to avoid caching issues 921 elementBean.initResource(m_cms); 922 CmsResource resource = elementBean.getResource(); 923 boolean isModelGroup = elementBean.getIndividualSettings().containsKey(CmsContainerElement.MODEL_GROUP_ID); 924 if (isModelGroup) { 925 CmsUUID groupId = new CmsUUID(elementBean.getIndividualSettings().get(CmsContainerElement.MODEL_GROUP_ID)); 926 resource = m_cms.readResource(groupId, CmsResourceFilter.IGNORE_EXPIRATION); 927 } 928 929 boolean newEditorDisabled = !CmsWorkplaceEditorManager.checkAcaciaEditorAvailable( 930 m_cms, 931 elementBean.getResource()); 932 result.setNewEditorDisabled(newEditorDisabled); 933 I_CmsResourceType resourceType = OpenCms.getResourceManager().getResourceType(resource); 934 String typeName = resourceType.getTypeName(); 935 result.setHasEditHandler( 936 (resourceType instanceof CmsResourceTypeXmlContent) 937 && (((CmsResourceTypeXmlContent)resourceType).getEditHandler(m_cms) != null)); 938 result.setResourceType(typeName); 939 result.setIconClasses( 940 CmsIconUtil.getIconClasses( 941 CmsIconUtil.getDisplayType(m_cms, resource), 942 elementBean.getResource().getName(), 943 false)); 944 CmsPermissionInfo permissionInfo; 945 String title; 946 String subTitle; 947 if (!elementBean.isInMemoryOnly()) { 948 CmsElementLockInfo lockInfo = getLockInfo(m_cms, resource); 949 result.setLockInfo(lockInfo); 950 permissionInfo = OpenCms.getADEManager().getPermissionInfo(m_cms, resource, m_page.getRootPath()); 951 if (CmsResourceTypeXmlContent.isXmlContent(resource)) { 952 if (CmsStringUtil.isEmptyOrWhitespaceOnly(permissionInfo.getNoEditReason()) 953 && elementBean.isInheritedContainer(m_cms)) { 954 String requestUri = m_cms.getRequestContext().getUri(); 955 String folderPath = CmsResource.getFolderPath(requestUri); 956 String configPath = CmsStringUtil.joinPaths( 957 folderPath, 958 CmsContainerConfigurationCache.INHERITANCE_CONFIG_FILE_NAME); 959 if (m_cms.existsResource(configPath)) { 960 permissionInfo.setNoEditReason( 961 new CmsResourceUtil(m_cms, m_cms.readResource(configPath)).getNoEditReason(wpLocale, true)); 962 } else { 963 if (!m_cms.getLock(folderPath).isLockableBy(m_cms.getRequestContext().getCurrentUser())) { 964 permissionInfo.setNoEditReason( 965 org.opencms.workplace.explorer.Messages.get().getBundle(wpLocale).key( 966 org.opencms.workplace.explorer.Messages.GUI_NO_EDIT_REASON_LOCK_1, 967 new CmsResourceUtil(m_cms, m_cms.readResource(folderPath)).getLockedByName())); 968 } 969 } 970 } 971 } else { 972 permissionInfo.setNoEditReason( 973 Messages.get().getBundle(wpLocale).key(Messages.GUI_ELEMENT_RESOURCE_CAN_NOT_BE_EDITED_0)); 974 } 975 CmsGallerySearchResult searchResult = CmsGallerySearch.searchById( 976 m_cms, 977 resource.getStructureId(), 978 m_locale); 979 title = searchResult.getTitle(); 980 if (CmsStringUtil.isEmptyOrWhitespaceOnly(title)) { 981 resource.getName(); 982 } 983 subTitle = searchResult.getUserLastModified(); 984 Date lastModDate = searchResult.getDateLastModified(); 985 if (lastModDate != null) { 986 subTitle += " / " + CmsDateUtil.getDateTime(lastModDate, DateFormat.MEDIUM, wpLocale); 987 } 988 } else { 989 permissionInfo = new CmsPermissionInfo(true, true, ""); 990 title = CmsWorkplaceMessages.getResourceTypeName(wpLocale, typeName); 991 subTitle = CmsWorkplaceMessages.getResourceTypeDescription(wpLocale, typeName); 992 } 993 result.setTitle(title); 994 result.setSubTitle(subTitle); 995 result.setClientId(elementBean.editorHash()); 996 result.setSitePath(m_cms.getSitePath(resource)); 997 998 result.setCreateNew(elementBean.isCreateNew()); 999 CmsResourceTypeConfig typeConfig = getConfigData().getResourceType(typeName); 1000 if (typeConfig != null) { 1001 result.setCopyInModels(typeConfig.isCopyInModels()); 1002 } 1003 Map<CmsUUID, CmsElementView> viewMap = OpenCms.getADEManager().getElementViews(m_cms); 1004 1005 boolean isModelGroupEditing = CmsModelGroupHelper.isModelGroupResource(m_page); 1006 if (!isModelGroup 1007 && isModelGroupEditing 1008 && elementBean.getIndividualSettings().containsKey(CmsContainerElement.MODEL_GROUP_STATE) 1009 && (ModelGroupState.isModelGroup == ModelGroupState.evaluate( 1010 elementBean.getIndividualSettings().get(CmsContainerElement.MODEL_GROUP_STATE)))) { 1011 isModelGroup = true; 1012 } 1013 if (!isModelGroupEditing && isModelGroup) { 1014 CmsResourceTypeConfig modelGroupConfig = getConfigData().getResourceType( 1015 CmsResourceTypeXmlContainerPage.MODEL_GROUP_TYPE_NAME); 1016 if (modelGroupConfig != null) { 1017 CmsUUID elementView = modelGroupConfig.getElementView(); 1018 CmsElementView viewObject = viewMap.get(elementView); 1019 if ((viewObject != null) && (viewObject.getParentViewId() != null)) { 1020 elementView = viewObject.getParentViewId(); 1021 } 1022 result.setElementView(elementView); 1023 } 1024 } else if (typeConfig != null) { 1025 CmsUUID elementView = typeConfig.getElementView(); 1026 CmsElementView viewObject = viewMap.get(elementView); 1027 if ((viewObject != null) && (viewObject.getParentViewId() != null)) { 1028 elementView = viewObject.getParentViewId(); 1029 } 1030 result.setElementView(elementView); 1031 } 1032 if (CmsStringUtil.isEmptyOrWhitespaceOnly(permissionInfo.getNoEditReason()) 1033 && ((typeConfig == null) || typeConfig.isEditDisabled())) { 1034 String message = Messages.get().getBundle(wpLocale).key( 1035 Messages.GUI_CONTAINERPAGE_EDIT_DISABLED_BY_SITEMAP_CONFIG_0); 1036 permissionInfo.setNoEditReason(message); 1037 } 1038 result.setHasSettings(hasSettings(m_cms, elementBean.getResource())); 1039 result.setPermissionInfo(permissionInfo); 1040 result.setReleasedAndNotExpired(elementBean.isReleasedAndNotExpired()); 1041 if (elementBean.isModelGroup()) { 1042 String modelId = elementBean.getIndividualSettings().get(CmsContainerElement.MODEL_GROUP_ID); 1043 result.setModelGroupId(modelId != null ? new CmsUUID(modelId) : CmsUUID.getNullUUID()); 1044 } 1045 result.setWasModelGroup( 1046 elementBean.getIndividualSettings().containsKey(CmsContainerElement.MODEL_GROUP_STATE) 1047 && (ModelGroupState.evaluate( 1048 elementBean.getIndividualSettings().get( 1049 CmsContainerElement.MODEL_GROUP_STATE)) == ModelGroupState.wasModelGroup)); 1050 return result; 1051 } 1052 1053 /** 1054 * Returns the formatter configuration for the given element resource.<p> 1055 * 1056 * @param resource the element resource 1057 * 1058 * @return the formatter configuration 1059 */ 1060 CmsFormatterConfiguration getFormatterConfiguration(CmsResource resource) { 1061 1062 return getConfigData().getFormatters(m_cms, resource); 1063 } 1064 1065 /** 1066 * Returns the base element data for the given element bean, without content or formatter info.<p> 1067 * 1068 * @param page the current container page 1069 * @param element the resource 1070 * 1071 * @return base element data 1072 * 1073 * @throws CmsException in case reading the data fails 1074 */ 1075 private CmsContainerElementData getBaseElementData(CmsResource page, CmsContainerElementBean element) 1076 throws CmsException { 1077 1078 CmsResourceUtil resUtil = new CmsResourceUtil(m_cms, element.getResource()); 1079 CmsContainerElementData elementData = new CmsContainerElementData(); 1080 setElementInfo(element, elementData); 1081 elementData.setLoadTime(System.currentTimeMillis()); 1082 elementData.setLastModifiedDate(element.getResource().getDateLastModified()); 1083 String userName = null; 1084 try { 1085 CmsUser user = m_cms.readUser(element.getResource().getUserLastModified()); 1086 userName = user.getName(); 1087 } catch (CmsException e) { 1088 userName = "" + element.getResource().getUserLastModified(); 1089 LOG.debug(e.getLocalizedMessage(), e); 1090 } 1091 elementData.setLastModifiedByUser(userName); 1092 elementData.setNavText(resUtil.getNavText()); 1093 Map<String, CmsXmlContentProperty> settingConfig = CmsXmlContentPropertyHelper.getPropertyInfo( 1094 m_cms, 1095 page, 1096 element.getResource()); 1097 elementData.setSettings( 1098 CmsXmlContentPropertyHelper.convertPropertiesToClientFormat( 1099 m_cms, 1100 element.getIndividualSettings(), 1101 settingConfig)); 1102 return elementData; 1103 } 1104 1105 /** 1106 * Returns the ADE configuration data for the current URI.<p> 1107 * 1108 * @return the ADE configuration data 1109 */ 1110 private CmsADEConfigData getConfigData() { 1111 1112 if (m_adeConfig == null) { 1113 m_adeConfig = OpenCms.getADEManager().lookupConfigurationWithCache( 1114 m_cms, 1115 m_cms.addSiteRoot(m_currentPageUri)); 1116 } 1117 return m_adeConfig; 1118 } 1119 1120 /** 1121 * Returns the HTML content of the given element and container.<p> 1122 * 1123 * @param element the element 1124 * @param container the container 1125 * @param configs the formatter configurations 1126 * 1127 * @return the HTML content 1128 */ 1129 private String getContentByContainer( 1130 CmsContainerElementBean element, 1131 CmsContainer container, 1132 CmsFormatterConfiguration configs) { 1133 1134 String content = null; 1135 1136 I_CmsFormatterBean formatter = getFormatterForContainer( 1137 m_cms, 1138 element, 1139 container, 1140 m_adeConfig, 1141 CmsADESessionCache.getCache(m_req, m_cms)); 1142 if (formatter != null) { 1143 element = element.clone(); // clone element because presets for different containers may be different 1144 element.initSettings(m_cms, m_adeConfig, formatter, m_locale, m_req, container.getSettingPresets()); 1145 try { 1146 content = getElementContent(element, m_cms.readResource(formatter.getJspStructureId()), container); 1147 // } 1148 } catch (Exception e) { 1149 LOG.error(e.getLocalizedMessage(), e); 1150 } 1151 if (content != null) { 1152 content = removeScriptTags(content); 1153 } 1154 } 1155 return content; 1156 } 1157 1158 /** 1159 * Returns the rendered element content for all the given containers. 1160 * 1161 * @param element the element to render 1162 * @param containers the containers the element appears in 1163 * 1164 * @return a map from container names to rendered page contents 1165 */ 1166 private Map<String, String> getContentsByContainerName( 1167 CmsContainerElementBean element, 1168 Collection<CmsContainer> containers) { 1169 1170 CmsFormatterConfiguration configs = getFormatterConfiguration(element.getResource()); 1171 Map<String, String> result = new HashMap<String, String>(); 1172 for (CmsContainer container : containers) { 1173 String content = getContentByContainer(element, container, configs); 1174 if (content != null) { 1175 content = removeScriptTags(content); 1176 } 1177 result.put(container.getName(), content); 1178 } 1179 return result; 1180 } 1181 1182 /** 1183 * Returns the content of an element when rendered with the given formatter.<p> 1184 * 1185 * @param element the element bean 1186 * @param formatter the formatter uri 1187 * @param container the container for which the element content should be retrieved 1188 * 1189 * @return generated html code 1190 * 1191 * @throws CmsException if an cms related error occurs 1192 * @throws ServletException if a jsp related error occurs 1193 * 1194 * @throws IOException if a jsp related error occurs 1195 */ 1196 private String getElementContent(CmsContainerElementBean element, CmsResource formatter, CmsContainer container) 1197 throws CmsException, ServletException, IOException { 1198 1199 element.initResource(m_cms); 1200 TemplateBean templateBean = CmsADESessionCache.getCache(m_req, m_cms).getTemplateBean( 1201 m_cms.addSiteRoot(m_currentPageUri), 1202 true); 1203 String oldUri = m_cms.getRequestContext().getUri(); 1204 try { 1205 m_cms.getRequestContext().setUri(m_currentPageUri); 1206 CmsContainerBean containerBean = null; 1207 if ((m_standardContext.getPage() != null) 1208 && m_standardContext.getPage().getContainers().containsKey(container.getName())) { 1209 containerBean = m_standardContext.getPage().getContainers().get(container.getName()); 1210 } else { 1211 containerBean = CmsElementUtil.clientToServerContainer( 1212 container, 1213 Collections.<CmsContainerElementBean> emptyList()); 1214 } 1215 if (containerBean.getWidth() == null) { 1216 containerBean.setWidth(String.valueOf(container.getWidth())); 1217 } 1218 containerBean.setDetailOnly(container.isDetailOnly()); 1219 m_standardContext.setContainer(containerBean); 1220 m_standardContext.setElement(element); 1221 m_standardContext.setEdited(true); 1222 // to enable 'old' direct edit features for content-collector-elements, 1223 // set the direct-edit-provider-attribute in the request 1224 I_CmsDirectEditProvider eb = new CmsAdvancedDirectEditProvider(); 1225 eb.init(m_cms, CmsDirectEditMode.TRUE, element.getSitePath()); 1226 m_req.setAttribute(I_CmsDirectEditProvider.ATTRIBUTE_DIRECT_EDIT_PROVIDER, eb); 1227 m_req.setAttribute(CmsTemplateContextManager.ATTR_TEMPLATE_BEAN, templateBean); 1228 String encoding = m_res.getCharacterEncoding(); 1229 return (new String( 1230 OpenCms.getResourceManager().getLoader(formatter).dump(m_cms, formatter, null, m_locale, m_req, m_res), 1231 encoding)).trim(); 1232 } finally { 1233 m_cms.getRequestContext().setUri(oldUri); 1234 } 1235 } 1236 1237 /** 1238 * Gets the lock information. 1239 * 1240 * @param cms the current CMS context 1241 * @param resource the resource for which to get lock information 1242 * @return the lock information 1243 */ 1244 private CmsElementLockInfo getLockInfo(CmsObject cms, CmsResource resource) { 1245 1246 try { 1247 CmsLock lock = cms.getLock(resource); 1248 CmsUUID owner = lock.getUserId(); 1249 boolean isPublish = lock.isPublish(); 1250 return new CmsElementLockInfo(owner, isPublish); 1251 } catch (Exception e) { 1252 LOG.error(e.getLocalizedMessage(), e); 1253 return new CmsElementLockInfo(null, false); 1254 } 1255 } 1256 1257 /** 1258 * Helper method for checking whether there are properties defined for a given content element.<p> 1259 * 1260 * @param cms the CmsObject to use for VFS operations 1261 * @param resource the resource for which it should be checked whether it has properties 1262 * 1263 * @return true if the resource has properties defined 1264 * 1265 * @throws CmsException if something goes wrong 1266 */ 1267 private boolean hasSettings(CmsObject cms, CmsResource resource) throws CmsException { 1268 1269 if (!CmsResourceTypeXmlContent.isXmlContent(resource)) { 1270 return false; 1271 } 1272 1273 CmsADEConfigData config = getConfigData(); 1274 CmsFormatterConfiguration formatters = config.getFormatters(m_cms, resource); 1275 boolean result = (formatters.getAllFormatters().size() > 1) 1276 || !CmsXmlContentPropertyHelper.getPropertyInfo(m_cms, null, resource).isEmpty(); 1277 if (!result && (formatters.getAllFormatters().size() == 1)) { 1278 result = (formatters.getAllFormatters().get(0).getSettings(config).size() > 0); 1279 } 1280 return result; 1281 } 1282 1283 /** 1284 * Parses the given request parameters string into a parameter map.<p> 1285 * 1286 * @param requestParameters the request parameters to parse 1287 * 1288 * @return the parameter map 1289 */ 1290 private Map<String, Object> parseRequestParameters(String requestParameters) { 1291 1292 Map<String, Object> parameterMap; 1293 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(requestParameters)) { 1294 parameterMap = new HashMap<String, Object>(); 1295 String[] params = requestParameters.split("&"); 1296 for (int i = 0; i < params.length; i++) { 1297 int position = params[i].indexOf("="); 1298 if (position >= 0) { 1299 String key = params[i].substring(0, position); 1300 String value = params[i].substring(position + 1); 1301 if (value.contains(",")) { 1302 parameterMap.put(key, value.split(",")); 1303 } else { 1304 parameterMap.put(key, value); 1305 } 1306 } 1307 } 1308 } else { 1309 parameterMap = Collections.<String, Object> emptyMap(); 1310 } 1311 return parameterMap; 1312 } 1313 1314 /** 1315 * Removes all script tags from given input.<p> 1316 * 1317 * @param input the input to remove script tags from 1318 * 1319 * @return the cleaned input 1320 */ 1321 private String removeScriptTags(String input) { 1322 1323 Pattern removePattern = Pattern.compile("<script[^>]*?>[\\s\\S]*?<\\/script>"); 1324 Matcher match = removePattern.matcher(input); 1325 return match.replaceAll(""); 1326 } 1327}