|
1 | 1 | /** |
2 | | - * (C) Copyright IBM Corporation 2019, 2024. |
| 2 | + * (C) Copyright IBM Corporation 2019, 2025. |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
|
44 | 44 | import javax.xml.parsers.DocumentBuilder; |
45 | 45 | import javax.xml.parsers.DocumentBuilderFactory; |
46 | 46 | import javax.xml.parsers.ParserConfigurationException; |
| 47 | +import javax.xml.xpath.XPathExpressionException; |
47 | 48 |
|
48 | 49 | import org.apache.commons.io.FileUtils; |
49 | 50 | import org.apache.commons.io.comparator.NameFileComparator; |
@@ -218,7 +219,7 @@ public FeaturesPlatforms getServerFeatures(File serverDirectory, File serverXmlF |
218 | 219 | } else if (libertyDirectoryPropertyToFile == null) { |
219 | 220 | warn("The properties for directories are null and could lead to server include files not being processed for server features."); |
220 | 221 | } |
221 | | - Properties bootstrapProperties = getBootstrapProperties(new File(serverDirectory, "bootstrap.properties")); |
| 222 | + Properties bootstrapProperties = getPropertiesFromFile(new File(serverDirectory, "bootstrap.properties")); |
222 | 223 | FeaturesPlatforms result = getConfigDropinsFeatures(null, serverDirectory, bootstrapProperties, "defaults", dropinsFilesToIgnore); |
223 | 224 | if (serverXmlFile == null) { |
224 | 225 | serverXmlFile = new File(serverDirectory, "server.xml"); |
@@ -412,7 +413,7 @@ public void error(SAXParseException e) throws SAXException { |
412 | 413 | result.getFeatures().addAll(featuresToInstall); |
413 | 414 | result.getPlatforms().addAll(platformsToInstall); |
414 | 415 | } else if ("include".equals(child.getNodeName())){ |
415 | | - result = parseIncludeNode(result, serverDirectory, canonicalServerFile, bootstrapProperties, child, updatedParsedXmls); |
| 416 | + result = parseIncludeNode(result, serverDirectory, canonicalServerFile, bootstrapProperties, child, updatedParsedXmls, doc); |
416 | 417 | } |
417 | 418 | } |
418 | 419 | } |
@@ -491,29 +492,41 @@ private FeaturesPlatforms parseFeatureManagerNode(Element node) { |
491 | 492 |
|
492 | 493 | /** |
493 | 494 | * Parse features from an include node. |
494 | | - * |
495 | | - * @param result2 |
496 | | - * The features that have been parsed so far. |
497 | | - * @param serverDirectory |
498 | | - * The server directory containing the server.xml. |
499 | | - * @param serverFile |
500 | | - * The parent server XML file containing the include node. |
501 | | - * @param node |
502 | | - * The include node. |
503 | | - * @param updatedParsedXmls |
504 | | - * The list of XML files that have been parsed so far. |
| 495 | + * |
| 496 | + * @param origResult The features that have been parsed so far. |
| 497 | + * @param serverDirectory The server directory containing the server.xml. |
| 498 | + * @param serverFile The parent server XML file containing the include node. |
| 499 | + * @param node The include node. |
| 500 | + * @param updatedParsedXmls The list of XML files that have been parsed so far. |
| 501 | + * @param doc XML Documemy |
505 | 502 | * @return The set of features to install, or empty set if the cumulatively |
506 | | - * parsed xml files only have featureManager sections but no |
507 | | - * features to install, or null if there are no valid xml files or |
508 | | - * they have no featureManager section |
| 503 | + * parsed xml files only have featureManager sections but no |
| 504 | + * features to install, or null if there are no valid xml files or |
| 505 | + * they have no featureManager section |
509 | 506 | * @throws IOException |
510 | 507 | */ |
511 | 508 | private FeaturesPlatforms parseIncludeNode(FeaturesPlatforms origResult, File serverDirectory, File serverFile, Properties bootstrapProperties, Element node, |
512 | | - List<File> updatedParsedXmls) { |
| 509 | + List<File> updatedParsedXmls, Document doc) { |
513 | 510 | FeaturesPlatforms result = origResult; |
514 | 511 | // Need to handle more variable substitution for include location. |
| 512 | + // currently we are only checking for server.xml, bootstrap.properties and server.env |
515 | 513 | String nodeValue = node.getAttribute("location"); |
516 | | - String includeFileName = VariableUtility.resolveVariables(this, nodeValue, null, bootstrapProperties, new Properties(), getLibertyDirectoryPropertyFiles()); |
| 514 | + Properties props = new Properties(); |
| 515 | + Properties serverEnvProps = getPropertiesFromFile(new File(serverDirectory, "server.env")); |
| 516 | + props.putAll(serverEnvProps); |
| 517 | + props.putAll(bootstrapProperties); |
| 518 | + Properties defaultProps = new Properties(); |
| 519 | + |
| 520 | + try { |
| 521 | + List<Properties> resultMap = VariableUtility.parseVariables(doc, true, true, true); |
| 522 | + props.putAll(resultMap.get(0)); |
| 523 | + defaultProps.putAll(resultMap.get(1)); |
| 524 | + } catch (XPathExpressionException e) { |
| 525 | + warn("The server file " + serverFile + " cannot be parsed. Skipping the included features variable resolution for this file"); |
| 526 | + debug("Exception received: " + e.getMessage(), e); |
| 527 | + } |
| 528 | + |
| 529 | + String includeFileName = VariableUtility.resolveVariables(this, nodeValue, null, props, defaultProps, getLibertyDirectoryPropertyFiles()); |
517 | 530 |
|
518 | 531 | if (includeFileName == null || includeFileName.trim().isEmpty()) { |
519 | 532 | warn("Unable to parse include file "+nodeValue+". Skipping the included features."); |
@@ -623,23 +636,28 @@ private FeaturesPlatforms handleOnConflict(FeaturesPlatforms origResult, String |
623 | 636 | return result; |
624 | 637 | } |
625 | 638 |
|
626 | | - private Properties getBootstrapProperties(File bootstrapProperties) { |
| 639 | + /** |
| 640 | + * |
| 641 | + * @param propertiesFile properties file |
| 642 | + * @return |
| 643 | + */ |
| 644 | + private Properties getPropertiesFromFile(File propertiesFile) { |
627 | 645 | Properties prop = new Properties(); |
628 | | - if (bootstrapProperties != null && bootstrapProperties.exists()) { |
| 646 | + if (propertiesFile != null && propertiesFile.exists()) { |
629 | 647 | FileInputStream stream = null; |
630 | 648 | try { |
631 | | - stream = new FileInputStream(bootstrapProperties); |
| 649 | + stream = new FileInputStream(propertiesFile); |
632 | 650 | prop.load(stream); |
633 | 651 | } catch (IOException e) { |
634 | | - warn("The bootstrap.properties file " + bootstrapProperties.getAbsolutePath() |
635 | | - + " could not be loaded. Skipping the bootstrap.properties file."); |
| 652 | + warn("Properties from the file " + propertiesFile.getAbsolutePath() |
| 653 | + + " could not be loaded. Skipping the properties file."); |
636 | 654 | debug("Exception received: "+e.getMessage(), e); |
637 | 655 | } finally { |
638 | 656 | if (stream != null) { |
639 | 657 | try { |
640 | 658 | stream.close(); |
641 | 659 | } catch (IOException e) { |
642 | | - debug("Could not close input stream for file " + bootstrapProperties.getAbsolutePath(), e); |
| 660 | + debug("Could not close input stream for file " + propertiesFile.getAbsolutePath(), e); |
643 | 661 | } |
644 | 662 | } |
645 | 663 | } |
|
0 commit comments