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.jsp; 029 030import org.opencms.ade.configuration.CmsADEConfigData; 031import org.opencms.ade.containerpage.CmsDetailOnlyContainerUtil; 032import org.opencms.file.CmsObject; 033import org.opencms.file.CmsResource; 034import org.opencms.file.CmsResourceFilter; 035import org.opencms.file.types.CmsResourceTypeXmlContent; 036import org.opencms.file.types.I_CmsResourceType; 037import org.opencms.flex.CmsFlexController; 038import org.opencms.jsp.util.CmsJspStandardContextBean; 039import org.opencms.loader.CmsLoaderException; 040import org.opencms.main.CmsException; 041import org.opencms.main.CmsLog; 042import org.opencms.main.OpenCms; 043import org.opencms.util.CmsStringUtil; 044import org.opencms.xml.CmsXmlContentDefinition; 045import org.opencms.xml.containerpage.CmsContainerBean; 046import org.opencms.xml.containerpage.CmsContainerElementBean; 047import org.opencms.xml.containerpage.CmsContainerPageBean; 048import org.opencms.xml.containerpage.CmsFormatterConfiguration; 049import org.opencms.xml.containerpage.I_CmsFormatterBean; 050 051import java.io.IOException; 052import java.io.UnsupportedEncodingException; 053import java.net.URLEncoder; 054import java.nio.charset.StandardCharsets; 055import java.util.ArrayList; 056import java.util.Collections; 057import java.util.HashMap; 058import java.util.LinkedHashMap; 059import java.util.LinkedHashSet; 060import java.util.List; 061import java.util.Map; 062import java.util.Map.Entry; 063import java.util.Set; 064 065import javax.servlet.ServletRequest; 066import javax.servlet.http.HttpServletRequest; 067import javax.servlet.jsp.JspException; 068import javax.servlet.jsp.tagext.BodyTagSupport; 069 070import org.apache.commons.logging.Log; 071 072import com.google.common.base.Joiner; 073import com.google.common.base.Splitter; 074import com.google.common.collect.Lists; 075 076/** 077 * This tag includes required CSS or JavaScript resources that are to be places in the HTML head.<p> 078 * 079 * Required resources can be configured in the resource type schema. 080 * Set attribute type to 'css' to include css resources or to 'javascript' to include JavaScript resources.<p> 081 * 082 * @since 8.0 083 */ 084public class CmsJspTagHeadIncludes extends BodyTagSupport implements I_CmsJspTagParamParent { 085 086 /** The include type CSS. */ 087 public static final String TYPE_CSS = "css"; 088 089 /** The include type java-script. */ 090 public static final String TYPE_JAVASCRIPT = "javascript"; 091 092 /** The log object for this class. */ 093 private static final Log LOG = CmsLog.getLog(CmsJspTagHeadIncludes.class); 094 095 /** Serial version UID required for safe serialisation. */ 096 private static final long serialVersionUID = 5496349529835666345L; 097 098 /** The value of the closetags attribute. */ 099 private String m_closeTags; 100 101 /** The default include resources separated by '|'. */ 102 private String m_defaults; 103 104 /** The detail container type. */ 105 private String m_detailType; 106 107 /** The detail container width. */ 108 private String m_detailWidth; 109 110 /** Map to save parameters to the include in. */ 111 private Map<String, String[]> m_parameterMap; 112 113 /** The include type. */ 114 private String m_type; 115 116 /** 117 * Adds parameters to a parameter Map that can be used for a http request.<p> 118 * 119 * @param parameters the Map to add the parameters to 120 * @param name the name to add 121 * @param value the value to add 122 * @param overwrite if <code>true</code>, a parameter in the map will be overwritten by 123 * a parameter with the same name, otherwise the request will have multiple parameters 124 * with the same name (which is possible in http requests) 125 */ 126 public static void addParameter(Map<String, String[]> parameters, String name, String value, boolean overwrite) { 127 128 // No null values allowed in parameters 129 if ((parameters == null) || (name == null) || (value == null)) { 130 return; 131 } 132 133 // Check if the parameter name (key) exists 134 if (parameters.containsKey(name) && (!overwrite)) { 135 // Yes: Check name values if value exists, if so do nothing, else add new value 136 String[] values = parameters.get(name); 137 String[] newValues = new String[values.length + 1]; 138 System.arraycopy(values, 0, newValues, 0, values.length); 139 newValues[values.length] = value; 140 parameters.put(name, newValues); 141 } else { 142 // No: Add new parameter name / value pair 143 String[] values = new String[] {value}; 144 parameters.put(name, values); 145 } 146 } 147 148 /** 149 * Gets the head includes for the given formatter bean.<p> 150 * 151 * @param formatter the formatter bean 152 * @param type the head include type 153 * 154 * @return the list of head includes 155 */ 156 protected static List<String> getHeadIncludes(I_CmsFormatterBean formatter, String type) { 157 158 if (TYPE_CSS.equals(type)) { 159 return Lists.newArrayList(formatter.getCssHeadIncludes()); 160 } else if (TYPE_JAVASCRIPT.equals(type)) { 161 return formatter.getJavascriptHeadIncludes(); 162 } 163 return null; 164 } 165 166 /** 167 * Gets the inline CSS/Javascrip for the given formatter bean.<p> 168 * 169 * @param formatter the formatter bean 170 * @param type the type (CSS or Javascript) 171 * 172 * @return the inline data for the given formatter bean 173 */ 174 protected static String getInlineData(I_CmsFormatterBean formatter, String type) { 175 176 if (TYPE_CSS.equals(type)) { 177 return formatter.getInlineCss(); 178 } else if (TYPE_JAVASCRIPT.equals(type)) { 179 return formatter.getInlineJavascript(); 180 } 181 return null; 182 } 183 184 /** 185 * @see org.opencms.jsp.I_CmsJspTagParamParent#addParameter(java.lang.String, java.lang.String) 186 */ 187 public void addParameter(String name, String value) { 188 189 // No null values allowed in parameters 190 if ((name == null) || (value == null)) { 191 return; 192 } 193 194 // Check if internal map exists, create new one if not 195 if (m_parameterMap == null) { 196 m_parameterMap = new HashMap<String, String[]>(); 197 } 198 199 addParameter(m_parameterMap, name, value, false); 200 201 } 202 203 /** 204 * @return <code>EVAL_PAGE</code> 205 * 206 * @see javax.servlet.jsp.tagext.Tag#doEndTag() 207 * 208 * @throws JspException by interface default 209 */ 210 @Override 211 public int doEndTag() throws JspException { 212 213 ServletRequest req = pageContext.getRequest(); 214 CmsFlexController controller = CmsFlexController.getController(req); 215 CmsObject cms = controller.getCmsObject(); 216 try { 217 if (TYPE_CSS.equals(m_type)) { 218 tagCssAction(cms, (HttpServletRequest)req); 219 } 220 if (TYPE_JAVASCRIPT.equals(m_type)) { 221 tagJSAction(cms, (HttpServletRequest)req); 222 } 223 } catch (Exception e) { 224 throw new JspException(e); 225 } finally { 226 m_parameterMap = null; 227 } 228 return EVAL_PAGE; 229 230 } 231 232 /** 233 * Returns <code>{@link #EVAL_BODY_BUFFERED}</code>.<p> 234 * 235 * @return <code>{@link #EVAL_BODY_BUFFERED}</code> 236 * 237 * @see javax.servlet.jsp.tagext.Tag#doStartTag() 238 */ 239 @Override 240 public int doStartTag() { 241 242 return EVAL_BODY_BUFFERED; 243 } 244 245 /** 246 * Returns the default include resources separated by '|'.<p> 247 * 248 * @return the default include resources 249 */ 250 public String getDefaults() { 251 252 return m_defaults; 253 } 254 255 /** 256 * Returns the detail container type.<p> 257 * 258 * @return the detail container type 259 */ 260 public String getDetailtype() { 261 262 return m_detailType; 263 } 264 265 /** 266 * Returns the detail container width.<p> 267 * 268 * @return the detail container width 269 */ 270 public String getDetailwidth() { 271 272 return m_detailWidth; 273 } 274 275 /** 276 * Returns the type.<p> 277 * 278 * @return the type 279 */ 280 public String getType() { 281 282 return m_type; 283 } 284 285 /** 286 * Sets the value of the closetags attribute.<p> 287 * 288 * @param closeTags the value of the closetags attribute 289 */ 290 public void setClosetags(String closeTags) { 291 292 m_closeTags = closeTags; 293 } 294 295 /** 296 * Sets the default include resources separated by '|'.<p> 297 * 298 * @param defaults the default include resources to set 299 */ 300 public void setDefaults(String defaults) { 301 302 m_defaults = defaults; 303 } 304 305 /** 306 * Sets the detail container type.<p> 307 * 308 * @param detailType the detail container type to set 309 */ 310 public void setDetailtype(String detailType) { 311 312 m_detailType = detailType; 313 } 314 315 /** 316 * Sets the detail container width.<p> 317 * 318 * @param detailWidth the detail container width to set 319 */ 320 public void setDetailwidth(String detailWidth) { 321 322 m_detailWidth = detailWidth; 323 } 324 325 /** 326 * Sets the type.<p> 327 * 328 * @param type the type to set 329 */ 330 public void setType(String type) { 331 332 m_type = type; 333 } 334 335 /** 336 * Returns true if the headincludes tag should be closed.<p> 337 * 338 * @return true if the headincludes tag should be closed 339 */ 340 public boolean shouldCloseTags() { 341 342 if (m_closeTags == null) { 343 return true; 344 } 345 return Boolean.parseBoolean(m_closeTags); 346 } 347 348 /** 349 * Action to include the CSS resources.<p> 350 * 351 * @param cms the current cms context 352 * @param req the current request 353 * 354 * @throws CmsException if something goes wrong reading the resources 355 * @throws IOException if something goes wrong writing to the response out 356 */ 357 public void tagCssAction(CmsObject cms, HttpServletRequest req) throws CmsException, IOException { 358 359 String includeType = TYPE_CSS; 360 361 CmsJspStandardContextBean standardContext = getStandardContext(cms, req); 362 CmsContainerPageBean containerPage = standardContext.getPage(); 363 364 Set<String> cssIncludes = new LinkedHashSet<String>(); 365 Map<String, String> inlineCss = new LinkedHashMap<String, String>(); 366 // add defaults 367 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_defaults)) { 368 String[] defaults = m_defaults.split("\\|"); 369 for (int i = 0; i < defaults.length; i++) { 370 cssIncludes.add(defaults[i].trim()); 371 } 372 } 373 374 collectHeadIncludesForContainerElement( 375 cms, 376 req, 377 standardContext, 378 containerPage, 379 includeType, 380 cssIncludes, 381 inlineCss); 382 if (standardContext.getDetailContentId() != null) { 383 try { 384 CmsResource detailContent = cms.readResource( 385 standardContext.getDetailContentId(), 386 CmsResourceFilter.ignoreExpirationOffline(cms)); 387 CmsFormatterConfiguration config = OpenCms.getADEManager().lookupConfiguration( 388 cms, 389 cms.getRequestContext().getRootUri()).getFormatters(cms, detailContent); 390 boolean requiresAllIncludes = true; 391 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(getDetailtype()) 392 && CmsStringUtil.isNotEmptyOrWhitespaceOnly(getDetailwidth())) { 393 try { 394 int width = Integer.parseInt(getDetailwidth()); 395 I_CmsFormatterBean formatter = config.getDetailFormatter(getDetailtype(), width); 396 cssIncludes.addAll(formatter.getCssHeadIncludes()); 397 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(formatter.getInlineCss())) { 398 inlineCss.put(formatter.getId(), formatter.getInlineCss()); 399 } 400 requiresAllIncludes = false; 401 } catch (NumberFormatException ne) { 402 // nothing to do, we will include CSS for all detail containers 403 } 404 } 405 if (requiresAllIncludes) { 406 for (I_CmsFormatterBean formatter : config.getDetailFormatters()) { 407 cssIncludes.addAll(getHeadIncludes(formatter, includeType)); 408 String inlineIncludeData = getInlineData(formatter, includeType); 409 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(inlineIncludeData)) { 410 inlineCss.put(formatter.getId(), inlineIncludeData); 411 } 412 } 413 } 414 } catch (CmsException e) { 415 LOG.error( 416 Messages.get().getBundle().key( 417 Messages.ERR_READING_REQUIRED_RESOURCE_1, 418 standardContext.getDetailContentId()), 419 e); 420 } 421 } 422 for (String cssUri : cssIncludes) { 423 pageContext.getOut().print( 424 "\n<link rel=\"stylesheet\" href=\"" 425 + CmsJspTagLink.linkTagAction(addParams(cssUri.trim()), req) 426 + "\" type=\"text/css\" "); 427 if (shouldCloseTags()) { 428 pageContext.getOut().print("/>"); 429 } else { 430 pageContext.getOut().print(">"); 431 } 432 } 433 if (cms.getRequestContext().getCurrentProject().isOnlineProject()) { 434 if (!inlineCss.isEmpty()) { 435 StringBuffer inline = new StringBuffer("\n<style type=\"text/css\">\n"); 436 for (Entry<String, String> cssEntry : inlineCss.entrySet()) { 437 inline.append(cssEntry.getValue()).append("\n\n"); 438 } 439 inline.append("\n</style>\n"); 440 pageContext.getOut().print(inline.toString()); 441 } 442 } else { 443 StringBuffer inline = new StringBuffer(); 444 for (Entry<String, String> cssEntry : inlineCss.entrySet()) { 445 inline.append("\n<style type=\"text/css\" rel=\"" + cssEntry.getKey() + "\">\n"); 446 inline.append(cssEntry.getValue()); 447 inline.append("\n</style>\n"); 448 } 449 pageContext.getOut().print(inline.toString()); 450 } 451 } 452 453 /** 454 * Action to include the java-script resources.<p> 455 * 456 * @param cms the current cms context 457 * @param req the current request 458 * 459 * @throws CmsException if something goes wrong reading the resources 460 * @throws IOException if something goes wrong writing to the response out 461 */ 462 public void tagJSAction(CmsObject cms, HttpServletRequest req) throws CmsException, IOException { 463 464 CmsJspStandardContextBean standardContext = getStandardContext(cms, req); 465 CmsContainerPageBean containerPage = standardContext.getPage(); 466 String includeType = TYPE_JAVASCRIPT; 467 Set<String> jsIncludes = new LinkedHashSet<String>(); 468 Map<String, String> inlineJS = new LinkedHashMap<String, String>(); 469 // add defaults 470 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_defaults)) { 471 String[] defaults = m_defaults.split("\\|"); 472 for (int i = 0; i < defaults.length; i++) { 473 jsIncludes.add(defaults[i].trim()); 474 } 475 } 476 collectHeadIncludesForContainerElement( 477 cms, 478 req, 479 standardContext, 480 containerPage, 481 includeType, 482 jsIncludes, 483 inlineJS); 484 if (standardContext.getDetailContentId() != null) { 485 try { 486 CmsResource detailContent = cms.readResource( 487 standardContext.getDetailContentId(), 488 CmsResourceFilter.ignoreExpirationOffline(cms)); 489 CmsFormatterConfiguration config = OpenCms.getADEManager().lookupConfiguration( 490 cms, 491 cms.getRequestContext().getRootUri()).getFormatters(cms, detailContent); 492 boolean requiresAllIncludes = true; 493 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(getDetailtype()) 494 && CmsStringUtil.isNotEmptyOrWhitespaceOnly(getDetailwidth())) { 495 try { 496 int width = Integer.parseInt(getDetailwidth()); 497 I_CmsFormatterBean formatter = config.getDetailFormatter(getDetailtype(), width); 498 jsIncludes.addAll(formatter.getJavascriptHeadIncludes()); 499 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(formatter.getInlineJavascript())) { 500 inlineJS.put(formatter.getId(), formatter.getInlineJavascript()); 501 } 502 requiresAllIncludes = false; 503 } catch (NumberFormatException ne) { 504 // nothing to do, we will include JavaScript for all detail containers 505 } 506 } 507 if (requiresAllIncludes) { 508 for (I_CmsFormatterBean formatter : config.getDetailFormatters()) { 509 jsIncludes.addAll(getHeadIncludes(formatter, includeType)); 510 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(formatter.getInlineJavascript())) { 511 inlineJS.put(formatter.getId(), formatter.getInlineJavascript()); 512 } 513 } 514 } 515 } catch (CmsException e) { 516 LOG.error( 517 Messages.get().getBundle().key( 518 Messages.ERR_READING_REQUIRED_RESOURCE_1, 519 standardContext.getDetailContentId()), 520 e); 521 } 522 } 523 for (String jsUri : jsIncludes) { 524 pageContext.getOut().print( 525 "\n<script src=\"" + CmsJspTagLink.linkTagAction(addParams(jsUri.trim()), req) + "\"></script>"); 526 } 527 if (!inlineJS.isEmpty()) { 528 StringBuffer inline = new StringBuffer(); 529 for (Entry<String, String> jsEntry : inlineJS.entrySet()) { 530 inline.append("\n<script>\n"); 531 inline.append(jsEntry.getValue()); 532 inline.append("\n</script>\n"); 533 } 534 pageContext.getOut().print(inline.toString()); 535 } 536 } 537 538 /** 539 * Collects the head includes for a given container element.<p> 540 * 541 * @param cms the current CMS context 542 * @param req the current request 543 * @param standardContext the current standard context 544 * @param containerPage the current container page 545 * @param includeType the type of head includes (CSS or Javascript) 546 * @param headincludes the set to which normal head includes should be added 547 * @param inline the map to which inline head includes should be added 548 */ 549 protected void collectHeadIncludesForContainerElement( 550 CmsObject cms, 551 ServletRequest req, 552 CmsJspStandardContextBean standardContext, 553 CmsContainerPageBean containerPage, 554 String includeType, 555 Set<String> headincludes, 556 Map<String, String> inline) { 557 558 CmsADEConfigData config = OpenCms.getADEManager().lookupConfigurationWithCache( 559 cms, 560 cms.getRequestContext().getRootUri()); 561 if ((containerPage != null) && (containerPage.getElements() != null)) { 562 List<CmsContainerBean> containers = new ArrayList<CmsContainerBean>(containerPage.getContainers().values()); 563 // add detail only containers if available 564 if (standardContext.isDetailRequest()) { 565 CmsContainerPageBean detailOnly = CmsDetailOnlyContainerUtil.getDetailOnlyPage( 566 cms, 567 req, 568 cms.getRequestContext().getRootUri()); 569 if (detailOnly != null) { 570 containers.addAll(detailOnly.getContainers().values()); 571 } 572 } 573 for (CmsContainerBean container : containers) { 574 for (CmsContainerElementBean element : container.getElements()) { 575 try { 576 element.initResource(cms); 577 if (!standardContext.getIsOnlineProject() 578 || element.getResource().isReleasedAndNotExpired( 579 cms.getRequestContext().getRequestTime())) { 580 if (element.isGroupContainer(cms) || element.isInheritedContainer(cms)) { 581 List<CmsContainerElementBean> subElements; 582 if (element.isGroupContainer(cms)) { 583 subElements = CmsJspTagContainer.getGroupContainerElements( 584 cms, 585 element, 586 req, 587 container.getType()); 588 } else { 589 subElements = CmsJspTagContainer.getInheritedContainerElements(cms, element); 590 } 591 for (CmsContainerElementBean subElement : subElements) { 592 subElement.initResource(cms); 593 if (!standardContext.getIsOnlineProject() 594 || subElement.getResource().isReleasedAndNotExpired( 595 cms.getRequestContext().getRequestTime())) { 596 I_CmsFormatterBean formatter = getFormatterBeanForElement( 597 cms, 598 config, 599 subElement, 600 container); 601 if (formatter != null) { 602 headincludes.addAll(getHeadIncludes(formatter, includeType)); 603 String inlineIncludeData = getInlineData(formatter, includeType); 604 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(inlineIncludeData)) { 605 inline.put(formatter.getId(), inlineIncludeData); 606 } 607 } else { 608 609 headincludes.addAll( 610 getSchemaHeadIncludes(cms, subElement.getResource(), includeType)); 611 } 612 } 613 } 614 } else { 615 I_CmsFormatterBean formatter = getFormatterBeanForElement( 616 cms, 617 config, 618 element, 619 container); 620 if (formatter != null) { 621 headincludes.addAll(getHeadIncludes(formatter, includeType)); 622 String inlineIncludeData = getInlineData(formatter, includeType); 623 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(inlineIncludeData)) { 624 inline.put(formatter.getId(), inlineIncludeData); 625 } 626 } else { 627 628 headincludes.addAll(getSchemaHeadIncludes(cms, element.getResource(), includeType)); 629 } 630 } 631 } 632 } catch (CmsException e) { 633 LOG.error( 634 Messages.get().getBundle().key( 635 Messages.ERR_READING_REQUIRED_RESOURCE_1, 636 element.getSitePath()), 637 e); 638 } 639 } 640 } 641 } 642 } 643 644 /** 645 * Merges the parameter map with the potentially existing parameters in a link. 646 * 647 * @param link the link to add the parameters to 648 * @return the link with the added parameters 649 * @throws UnsupportedEncodingException if something goes wrong encoding the request parameters 650 */ 651 private String addParams(String link) throws UnsupportedEncodingException { 652 653 int pos = link.indexOf("?"); 654 List<String> queryParts = new ArrayList<>(); 655 String target = link; 656 if (pos != -1) { 657 target = link.substring(0, pos); 658 for (String queryPart : Splitter.on("&").split(link.substring(pos + 1))) { 659 queryParts.add(queryPart); 660 } 661 } 662 663 if (m_parameterMap != null) { 664 for (Entry<String, String[]> paramEntry : m_parameterMap.entrySet()) { 665 if (paramEntry.getValue() != null) { 666 for (int i = 0; i < paramEntry.getValue().length; i++) { 667 queryParts.add( 668 paramEntry.getKey() 669 + "=" 670 + URLEncoder.encode(paramEntry.getValue()[i], StandardCharsets.UTF_8.toString())); 671 } 672 } 673 } 674 } 675 String result = target + (queryParts.isEmpty() ? "" : "?" + Joiner.on("&").join(queryParts)); 676 return result; 677 } 678 679 /** 680 * Generates the request parameter string.<p> 681 * 682 * @return the request parameter string 683 * 684 * @throws UnsupportedEncodingException if something goes wrong encoding the request parameters 685 */ 686 private String generateReqParams() throws UnsupportedEncodingException { 687 688 String params = ""; 689 if ((m_parameterMap != null) && !m_parameterMap.isEmpty()) { 690 for (Entry<String, String[]> paramEntry : m_parameterMap.entrySet()) { 691 if (paramEntry.getValue() != null) { 692 for (int i = 0; i < paramEntry.getValue().length; i++) { 693 params += "&" 694 + paramEntry.getKey() 695 + "=" 696 + URLEncoder.encode(paramEntry.getValue()[i], "UTF-8"); 697 } 698 } 699 } 700 params = "?" + params.substring(1); 701 } 702 return params; 703 } 704 705 /** 706 * Returns the schema configured CSS head include resources.<p> 707 * 708 * @param cms the current cms context 709 * @param resource the resource 710 * 711 * @return the configured CSS head include resources 712 */ 713 private Set<String> getCSSHeadIncludes(CmsObject cms, CmsResource resource) { 714 715 if (CmsResourceTypeXmlContent.isXmlContent(resource)) { 716 try { 717 CmsXmlContentDefinition contentDefinition = CmsXmlContentDefinition.getContentDefinitionForResource( 718 cms, 719 resource); 720 return contentDefinition.getContentHandler().getCSSHeadIncludes(cms, resource); 721 } catch (CmsException e) { 722 LOG.warn(e.getLocalizedMessage(), e); 723 // NOOP, use the empty set 724 } 725 } 726 return Collections.emptySet(); 727 } 728 729 /** 730 * Returns the formatter configuration for the given element, will return <code>null</code> for schema formatters.<p> 731 * 732 * @param cms the current CMS context 733 * @param config the current sitemap configuration 734 * @param element the element bean 735 * @param container the container bean 736 * @param formatters the formatter map 737 * 738 * @return the formatter configuration bean 739 */ 740 private I_CmsFormatterBean getFormatterBeanForElement( 741 CmsObject cms, 742 CmsADEConfigData config, 743 CmsContainerElementBean element, 744 CmsContainerBean container) { 745 746 int containerWidth = -1; 747 if (container.getWidth() == null) { 748 // the container width has not been set yet 749 containerWidth = CmsFormatterConfiguration.MATCH_ALL_CONTAINER_WIDTH; 750 } else { 751 try { 752 753 containerWidth = Integer.parseInt(container.getWidth()); 754 } catch (NumberFormatException e) { 755 // do nothing, set width to -1 756 } 757 } 758 I_CmsFormatterBean result = CmsJspTagContainer.getFormatterConfigurationForElement( 759 cms, 760 element, 761 config, 762 container.getName(), 763 container.getType(), 764 containerWidth); 765 return result; 766 } 767 768 /** 769 * Returns the schema configured JavaScript head include resources.<p> 770 * 771 * @param cms the current cms context 772 * @param resource the resource 773 * 774 * @return the configured JavaScript head include resources 775 * 776 * @throws CmsLoaderException if something goes wrong reading the resource type 777 */ 778 private Set<String> getJSHeadIncludes(CmsObject cms, CmsResource resource) throws CmsLoaderException { 779 780 I_CmsResourceType resType = OpenCms.getResourceManager().getResourceType(resource.getTypeId()); 781 if (resType instanceof CmsResourceTypeXmlContent) { 782 try { 783 CmsXmlContentDefinition contentDefinition = CmsXmlContentDefinition.getContentDefinitionForResource( 784 cms, 785 resource); 786 return contentDefinition.getContentHandler().getJSHeadIncludes(cms, resource); 787 } catch (CmsException e) { 788 LOG.warn(e.getLocalizedMessage(), e); 789 // NOOP, use the empty set 790 } 791 } 792 return Collections.emptySet(); 793 } 794 795 /** 796 * Gets the head includes of a resource from the content definition.<p> 797 * 798 * @param cms the current CMS context 799 * @param res the resource for which the head includes should be fetched 800 * @param type the head include type (CSS or Javascript) 801 * 802 * @return the set of schema head includes 803 * 804 * @throws CmsLoaderException if something goes wrong 805 */ 806 private Set<String> getSchemaHeadIncludes(CmsObject cms, CmsResource res, String type) throws CmsLoaderException { 807 808 if (type.equals(TYPE_CSS)) { 809 return getCSSHeadIncludes(cms, res); 810 } else if (type.equals(TYPE_JAVASCRIPT)) { 811 return getJSHeadIncludes(cms, res); 812 } 813 return null; 814 } 815 816 /** 817 * Returns the standard context bean.<p> 818 * 819 * @param cms the current cms context 820 * @param req the current request 821 * 822 * @return the standard context bean 823 * 824 * @throws CmsException if something goes wrong 825 */ 826 private CmsJspStandardContextBean getStandardContext(CmsObject cms, HttpServletRequest req) throws CmsException { 827 828 CmsJspStandardContextBean standardContext = CmsJspStandardContextBean.getInstance(req); 829 standardContext.initPage(); 830 return standardContext; 831 } 832 833}