This is an automated email from the ASF dual-hosted git repository.

pradeep pushed a commit to branch RANGER-5027_master
in repository https://gitbox.apache.org/repos/asf/ranger.git

commit d1d30f19a01dcd171ed43c8196ac88fcbcfba85c
Author: Pradeep AgrawaL <[email protected]>
AuthorDate: Mon Dec 16 16:38:56 2024 +0530

    RANGER-5027: agents-installer module: update for code readability 
improvement
---
 agents-installer/pom.xml                           |   5 +
 .../ranger/utils/install/XmlConfigChanger.java     | 895 ++++++++++-----------
 2 files changed, 432 insertions(+), 468 deletions(-)

diff --git a/agents-installer/pom.xml b/agents-installer/pom.xml
index 6d80eff3f..89ac6e260 100644
--- a/agents-installer/pom.xml
+++ b/agents-installer/pom.xml
@@ -27,6 +27,11 @@
     <packaging>jar</packaging>
     <name>Installer Support Component</name>
     <description>Security Plugins Installer</description>
+    <properties>
+        <checkstyle.failOnViolation>true</checkstyle.failOnViolation>
+        <checkstyle.skip>false</checkstyle.skip>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
     <dependencies>
         <dependency>
             <groupId>commons-cli</groupId>
diff --git 
a/agents-installer/src/main/java/org/apache/ranger/utils/install/XmlConfigChanger.java
 
b/agents-installer/src/main/java/org/apache/ranger/utils/install/XmlConfigChanger.java
index 270e52181..28113cd77 100644
--- 
a/agents-installer/src/main/java/org/apache/ranger/utils/install/XmlConfigChanger.java
+++ 
b/agents-installer/src/main/java/org/apache/ranger/utils/install/XmlConfigChanger.java
@@ -17,26 +17,7 @@
  * under the License.
  */
 
- package org.apache.ranger.utils.install;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Properties;
-
-import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
+package org.apache.ranger.utils.install;
 
 import org.apache.commons.cli.BasicParser;
 import org.apache.commons.cli.CommandLine;
@@ -52,454 +33,432 @@ import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.SAXException;
 
-public class XmlConfigChanger {
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
 
-       private static final String EMPTY_TOKEN = "%EMPTY%";
-       private static final String EMPTY_TOKEN_VALUE = "";
-
-       public static final String ROOT_NODE_NAME = "configuration";
-       public static final String NAME_NODE_NAME = "name";
-       public static final String PROPERTY_NODE_NAME = "property";
-       public static final String VALUE_NODE_NAME = "value";
-
-       private File inpFile;
-       private File outFile;
-       private File confFile;
-       private File propFile;
-       
-       private Document doc;
-       Properties installProperties = new Properties();
-
-       public static void main(String[] args) {
-               XmlConfigChanger xmlConfigChanger = new XmlConfigChanger();
-               xmlConfigChanger.parseConfig(args);
-               try {
-                       xmlConfigChanger.run();
-               }
-               catch(Throwable t) {
-                       
System.err.println("*************************************************************************");
-                       System.err.println("******* ERROR: unable to process 
xml configuration changes due to error:" + t.getMessage());
-                       t.printStackTrace();
-                       
System.err.println("*************************************************************************");
-                       System.exit(1);
-               }
-       }
-
-       @SuppressWarnings("static-access")
-       public void parseConfig(String[] args) {
-               
-               
-               Options options = new Options();
-
-               Option inputOption = 
OptionBuilder.hasArgs(1).isRequired().withLongOpt("input").withDescription("Input
 xml file name").create('i');
-               options.addOption(inputOption);
-
-               Option outputOption = 
OptionBuilder.hasArgs(1).isRequired().withLongOpt("output").withDescription("Output
 xml file name").create('o');
-               options.addOption(outputOption);
-
-               Option configOption = 
OptionBuilder.hasArgs(1).isRequired().withLongOpt("config").withDescription("Config
 file name").create('c');
-               options.addOption(configOption);
-
-               Option installPropOption = 
OptionBuilder.hasArgs(1).isRequired(false).withLongOpt("installprop").withDescription("install.properties").create('p');
-               options.addOption(installPropOption);
-
-               CommandLineParser parser = new BasicParser();
-               CommandLine cmd = null;
-               try {
-                       cmd = parser.parse(options, args);
-               } catch (ParseException e) {
-                       String header = "ERROR: " + e;
-                       HelpFormatter helpFormatter = new HelpFormatter();
-                       helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
-                       throw new RuntimeException(e);
-               }
-
-               String inputFileName = cmd.getOptionValue('i');
-               this.inpFile = new File(inputFileName);
-               if (! this.inpFile.canRead()) {
-                       String header = "ERROR: Input file [" + 
this.inpFile.getAbsolutePath() + "] can not be read.";
-                       HelpFormatter helpFormatter = new HelpFormatter();
-                       helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
-                       throw new RuntimeException(header);
-               }
-               
-               String outputFileName = cmd.getOptionValue('o');
-               this.outFile = new File(outputFileName);
-               if (this.outFile.exists()) {
-                       String header = "ERROR: Output file [" + 
this.outFile.getAbsolutePath() + "] already exists. Specify a filepath for 
creating new output file for the input [" + this.inpFile.getAbsolutePath() + 
"]";
-                       HelpFormatter helpFormatter = new HelpFormatter();
-                       helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
-                       throw new RuntimeException(header);
-               }
-               
-               String configFileName = cmd.getOptionValue('c');
-               this.confFile  = new File(configFileName);
-               if (! this.confFile.canRead()) {
-                       String header = "ERROR: Config file [" + 
this.confFile.getAbsolutePath() + "] can not be read.";
-                       HelpFormatter helpFormatter = new HelpFormatter();
-                       helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
-                       throw new RuntimeException(header);
-               }
-
-               String installPropFileName = (cmd.hasOption('p') ? 
cmd.getOptionValue('p') : null );
-               if (installPropFileName != null) {
-                       this.propFile = new File(installPropFileName);
-                       if (! this.propFile.canRead()) {
-                               String header = "ERROR: Install Property file 
[" + this.propFile.getAbsolutePath() + "] can not be read.";
-                               HelpFormatter helpFormatter = new 
HelpFormatter();
-                               helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
-                               throw new RuntimeException(header);
-                       }
-               }
-               
-       }
-
-       public void run() throws ParserConfigurationException, SAXException, 
IOException, TransformerException {
-               loadInstallProperties();
-               
-               DocumentBuilderFactory factory = 
DocumentBuilderFactory.newInstance();
-               factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, 
true);
-               
factory.setFeature("http://xml.org/sax/features/external-general-entities";, 
false);
-               
factory.setFeature("http://xml.org/sax/features/external-parameter-entities";, 
false);
-               DocumentBuilder builder = factory.newDocumentBuilder();
-               doc = builder.parse(inpFile);
-
-               BufferedReader reader = null;
-               try {
-                       reader = new BufferedReader(new FileReader(confFile));
-
-                       String line = null;
-
-                       @SuppressWarnings("unused")
-                       int lineNo = 0;
-                       Properties variables = new Properties();
-                       while ((line = reader.readLine()) != null) {
-                               lineNo++;
-                               line = line.trim();
-                               if (line.isEmpty() )
-                                       continue;
-                               if (line.startsWith("#")) {
-                                       continue;
-                               }
-                               if (line.contains("#")) {
-                                       int len = line.indexOf("#");
-                                       line = line.substring(0,len);
-                               }
-                               String[] tokens = line.split("\\s+");
-                               String propName = tokens[0];
-                               String propValue = null;
-                               try {
-                                       if 
(propnameContainsVariables(propName)) {
-                                               propName = 
replaceProp(propName, variables);
-                                       }
-                                       propValue = 
replaceProp(tokens[1],installProperties);
-                               } catch (ValidationException e) {
-                                       // throw new RuntimeException("Unable 
to replace tokens in the line: \n[" + line + "]\n in file [" + 
confFile.getAbsolutePath() + "] line number:["  + lineNo + "]" );
-                                       throw new RuntimeException(e);
-                               }
-
-                               String actionType = tokens[2];
-                               String options = (tokens.length > 3 ? tokens[3] 
: null);
-                               boolean createIfNotExists = (options != null && 
options.contains("create-if-not-exists"));
-                               
-                               
-                               if ("add".equals(actionType)) {
-                                       addProperty(propName, propValue);
-                               }
-                               else if ("mod".equals(actionType)) {
-                                       modProperty(propName, 
propValue,createIfNotExists);
-                               }
-                               else if ("del".equals(actionType)) {
-                                       delProperty(propName);
-                               }
-                               else if ("append".equals(actionType)) {
-                                       String curVal =  getProperty(propName);
-                                       if (curVal == null) {
-                                               if (createIfNotExists) {
-                                                       addProperty(propName, 
propValue);
-                                               }
-                                       }
-                                       else {
-                                               String appendDelimitor = 
(tokens.length > 4 ? tokens[4] : " ");
-                                               if (! 
curVal.contains(propValue)) {
-                                                       String newVal = null;
-                                                       if (curVal.length() == 
0) {
-                                                               newVal = 
propValue;
-                                                       }
-                                                       else {
-                                                               newVal = curVal 
+ appendDelimitor + propValue;
-                                                       }
-                                                       modProperty(propName, 
newVal,createIfNotExists);
-                                               }
-                                       }
-                               }
-                               else if ("delval".equals(actionType)) {
-                                       String curVal =  getProperty(propName);
-                                       if (curVal != null) {
-                                               String appendDelimitor = 
(tokens.length > 4 ? tokens[4] : " ");
-                                               if (curVal.contains(propValue)) 
{
-                                                       String[] valTokens = 
curVal.split(appendDelimitor);
-                                                       StringBuilder sb = new 
StringBuilder();
-                                                       for(String v : 
valTokens) {
-                                                               if (! 
v.equals(propValue)) {
-                                                                       if 
(sb.length() > 0) {
-                                                                               
sb.append(appendDelimitor);
-                                                                       }
-                                                                       
sb.append(v);
-                                                               }
-                                                       }
-                                                       String newVal = 
sb.toString();
-                                                       modProperty(propName, 
newVal,createIfNotExists);
-                                               }
-                                       }
-                               }
-                               else if ("var".equals(actionType)) {
-                                       variables.put(propName, propValue);
-                               }
-                               else {
-                                       throw new RuntimeException("Unknown 
Command Found: [" + actionType + "], Supported Types:  add modify del append");
-                               }
-                               
-                       }
-                       
-                       TransformerFactory tfactory = 
TransformerFactory.newInstance();
-                       
tfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE);
-                       Transformer transformer = tfactory.newTransformer();
-                       transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-                       
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount";, "4");
-                       
-                       DOMSource source = new DOMSource(doc);
-                       FileOutputStream out = new FileOutputStream(outFile);
-                       StreamResult result = new StreamResult(out);
-                       transformer.transform(source, result);
-                       out.close();
-
-               }
-               finally {
-                       if (reader != null) {
-                               reader.close();
-                       }
-               }
-
-       }
-
-       /**
-        * Check if prop name contains a substitution variable embedded in it, 
e.g. %VAR_NAME%.
-        * @param propName
-        * @return true if propname contains at least 2 '%' characters in it, 
else false
-        */
-       private boolean propnameContainsVariables(String propName) {
-
-               if (propName != null) {
-                       int first = propName.indexOf('%');
-                       if (first != -1) {
-                               // indexof is safe even if 2nd argument is 
beyond size of string, i.e. if 1st percent was the last character of the string.
-                               int second = propName.indexOf('%', first + 1);
-                               if (second != -1) {
-                                       return true;
-                               }
-                       }
-               }
-               return false;
-       }
-
-
-       private void addProperty(String propName, String val) {
-               NodeList nl = doc.getElementsByTagName(ROOT_NODE_NAME);
-               Node rootConfig = nl.item(0);
-               rootConfig.appendChild(createNewElement(propName,val));
-       }
-
-       private void modProperty(String propName, String val, boolean 
createIfNotExists) {
-               Node node = findProperty(propName);
-               if (node != null) {
-                       NodeList cnl = node.getChildNodes();
-                       for (int j = 0; j < cnl.getLength() ; j++) {
-                               String nodeName = cnl.item(j).getNodeName();
-                               if (nodeName.equals(VALUE_NODE_NAME)) {
-                                       if (cnl.item(j).hasChildNodes()) {
-                                               
cnl.item(j).getChildNodes().item(0).setNodeValue(val);
-                                       }
-                                       else {
-                                               Node propValueNode = 
cnl.item(j);
-                                               Node txtNode = 
doc.createTextNode(val);
-                                               
propValueNode.appendChild(txtNode);
-                                               txtNode.setNodeValue(val);
-                                       }
-                                       return;
-                               }
-                       }
-               }
-               if (createIfNotExists) {
-                       addProperty(propName, val);
-               }
-       }
-
-       private String getProperty(String propName) {
-               String ret = null;
-               try {
-                       Node node = findProperty(propName);
-                       if (node != null) {
-                               NodeList cnl = node.getChildNodes();
-                               for (int j = 0; j < cnl.getLength() ; j++) {
-                                       String nodeName = 
cnl.item(j).getNodeName();
-                                       if (nodeName.equals(VALUE_NODE_NAME)) {
-                                               Node valueNode = null;
-                                               if 
(cnl.item(j).hasChildNodes()) {
-                                                       valueNode = 
cnl.item(j).getChildNodes().item(0);
-                                               }
-                                               if (valueNode == null) {        
// Value Node is defined with
-                                                       ret = "";
-                                               }
-                                               else {
-                                                       ret = 
valueNode.getNodeValue();
-                                               }
-                                               break;
-                                       }
-                               }
-                       }
-               }
-               catch(Throwable t) {
-                       throw new RuntimeException("getProperty(" + propName + 
") failed.", t);
-               }
-               return ret;
-       }
-
-       
-       private void delProperty(String propName) {
-               Node node = findProperty(propName);
-               if (node != null) {
-                       node.getParentNode().removeChild(node);
-               }
-       }
-       
-       
-       private Node findProperty(String propName) {
-               Node ret = null;
-               try {
-                       NodeList nl = 
doc.getElementsByTagName(PROPERTY_NODE_NAME);
-                       
-                       for(int i = 0; i < nl.getLength() ; i++) {
-                               NodeList cnl = nl.item(i).getChildNodes();
-                               boolean found = false;
-                               for (int j = 0; j < cnl.getLength() ; j++) {
-                                       String nodeName = 
cnl.item(j).getNodeName();
-                                       if (nodeName.equals(NAME_NODE_NAME)) {
-                                               String pName = 
cnl.item(j).getChildNodes().item(0).getNodeValue();
-                                               found = pName.equals(propName);
-                                               if (found)
-                                                       break;
-                                       }
-                               }
-                               if (found) {
-                                       ret = nl.item(i);
-                                       break;
-                               }
-                       }
-               }
-               catch(Throwable t) {
-                       throw new RuntimeException("findProperty(" + propName + 
") failed.", t);
-               }
-               return ret;
-       }
-       
-       
-       private Element createNewElement(String propName, String val) {
-               Element ret = null;
-               
-               try {
-                       if (doc != null) {
-                               ret = doc.createElement(PROPERTY_NODE_NAME);
-                               Node propNameNode  = 
doc.createElement(NAME_NODE_NAME);
-                               Node txtNode = doc.createTextNode(propName);
-                               propNameNode.appendChild(txtNode);
-                               propNameNode.setNodeValue(propName);
-                               ret.appendChild(propNameNode);
-
-                               Node propValueNode = 
doc.createElement(VALUE_NODE_NAME);
-                               txtNode = doc.createTextNode(val);
-                               propValueNode.appendChild(txtNode);
-                               propValueNode.setNodeValue(propName);
-                               ret.appendChild(propValueNode);
-                       }
-               }
-               catch(Throwable t) {
-                       throw new RuntimeException("createNewElement(" + 
propName + ") with value [" + val + "] failed.", t);
-               }
-
-               return ret;
-       }
-
-       private void loadInstallProperties() {
-               if (propFile != null) {
-                       try (FileInputStream in = new 
FileInputStream(propFile)) {
-                               installProperties.load(in);
-                       } catch (IOException ioe) {
-                               System.err.println("******* ERROR: load file 
failure. The reason: " + ioe.getMessage());
-                               ioe.printStackTrace();
-                       }
-               }
-               // To support environment variable, we will add all environment 
variables to the Properties
-               installProperties.putAll(System.getenv());
-       }
-
-       private String replaceProp(String propValue, Properties prop) throws 
ValidationException  {
-                       
-               StringBuilder tokensb = new StringBuilder();
-               StringBuilder retsb = new StringBuilder();
-               boolean isToken = false;
-
-               for(char c : propValue.toCharArray()) {
-                       if (c == '%') {
-                               if (isToken) {
-                                       String token = tokensb.toString();
-                                       String tokenValue = (token.length() == 
0 ? "%" : prop.getProperty(token) );
-                                       if (tokenValue == null  || 
tokenValue.trim().isEmpty()) {
-                                               throw new 
ValidationException("ERROR: configuration token [" + token + "] is not defined 
in the file: [" + (propFile != null ? propFile.getAbsolutePath() : "{no 
install.properties file specified using -p option}") + "]");
-                                       }
-                                       else {
-                                               if 
(EMPTY_TOKEN.equals(tokenValue)) {
-                                                       
retsb.append(EMPTY_TOKEN_VALUE);
-                                               }
-                                               else {
-                                                       
retsb.append(tokenValue);
-                                               }
-                                       }
-                                       isToken = false;
-                               }
-                               else {
-                                       isToken = true;
-                                       tokensb.setLength(0);
-                               }
-                       }
-                       else if (isToken) {
-                               tokensb.append(String.valueOf(c));
-                       }
-                       else {
-                               retsb.append(String.valueOf(c));
-                       }
-               }
-               
-               if (isToken) {
-                       throw new ValidationException("ERROR: configuration has 
a token defined without end-token [" + propValue + "] in the file: [" + 
(propFile != null ? propFile.getAbsolutePath() : "{no install.properties file 
specified using -p option}") + "]");
-               }
-               
-               return retsb.toString();
-       }
-       
-       
-       @SuppressWarnings("serial")
-       class ValidationException extends Exception {
-
-               public ValidationException(String msg) {
-                       super(msg);
-               }
-
-               public ValidationException(Throwable cause) {
-                       super(cause);
-               }
-               
-       }
-       
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Properties;
 
+public class XmlConfigChanger {
+    public static final String ROOT_NODE_NAME     = "configuration";
+    public static final String NAME_NODE_NAME     = "name";
+    public static final String PROPERTY_NODE_NAME = "property";
+    public static final String VALUE_NODE_NAME    = "value";
+    private static final String EMPTY_TOKEN       = "%EMPTY%";
+    private static final String EMPTY_TOKEN_VALUE = "";
+    Properties installProperties = new Properties();
+    private File inpFile;
+    private File outFile;
+    private File confFile;
+    private File propFile;
+    private Document doc;
+
+    public static void main(String[] args) {
+        XmlConfigChanger xmlConfigChanger = new XmlConfigChanger();
+        xmlConfigChanger.parseConfig(args);
+        try {
+            xmlConfigChanger.run();
+        } catch (Throwable t) {
+            
System.err.println("*************************************************************************");
+            System.err.println("******* ERROR: unable to process xml 
configuration changes due to error:" + t.getMessage());
+            t.printStackTrace();
+            
System.err.println("*************************************************************************");
+            System.exit(1);
+        }
+    }
+
+    @SuppressWarnings("static-access")
+    public void parseConfig(String[] args) {
+        Options options = new Options();
+
+        Option inputOption = 
OptionBuilder.hasArgs(1).isRequired().withLongOpt("input").withDescription("Input
 xml file name").create('i');
+        options.addOption(inputOption);
+
+        Option outputOption = 
OptionBuilder.hasArgs(1).isRequired().withLongOpt("output").withDescription("Output
 xml file name").create('o');
+        options.addOption(outputOption);
+
+        Option configOption = 
OptionBuilder.hasArgs(1).isRequired().withLongOpt("config").withDescription("Config
 file name").create('c');
+        options.addOption(configOption);
+
+        Option installPropOption = 
OptionBuilder.hasArgs(1).isRequired(false).withLongOpt("installprop").withDescription("install.properties").create('p');
+        options.addOption(installPropOption);
+
+        CommandLineParser parser = new BasicParser();
+        CommandLine       cmd    = null;
+        try {
+            cmd = parser.parse(options, args);
+        } catch (ParseException e) {
+            String        header        = "ERROR: " + e;
+            HelpFormatter helpFormatter = new HelpFormatter();
+            helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
+            throw new RuntimeException(e);
+        }
+
+        String inputFileName = cmd.getOptionValue('i');
+        this.inpFile = new File(inputFileName);
+        if (!this.inpFile.canRead()) {
+            String        header        = "ERROR: Input file [" + 
this.inpFile.getAbsolutePath() + "] can not be read.";
+            HelpFormatter helpFormatter = new HelpFormatter();
+            helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
+            throw new RuntimeException(header);
+        }
+
+        String outputFileName = cmd.getOptionValue('o');
+        this.outFile = new File(outputFileName);
+        if (this.outFile.exists()) {
+            String        header        = "ERROR: Output file [" + 
this.outFile.getAbsolutePath() + "] already exists. Specify a filepath for 
creating new output file for the input [" + this.inpFile.getAbsolutePath() + 
"]";
+            HelpFormatter helpFormatter = new HelpFormatter();
+            helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
+            throw new RuntimeException(header);
+        }
+
+        String configFileName = cmd.getOptionValue('c');
+        this.confFile = new File(configFileName);
+        if (!this.confFile.canRead()) {
+            String        header        = "ERROR: Config file [" + 
this.confFile.getAbsolutePath() + "] can not be read.";
+            HelpFormatter helpFormatter = new HelpFormatter();
+            helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
+            throw new RuntimeException(header);
+        }
+
+        String installPropFileName = (cmd.hasOption('p') ? 
cmd.getOptionValue('p') : null);
+        if (installPropFileName != null) {
+            this.propFile = new File(installPropFileName);
+            if (!this.propFile.canRead()) {
+                String        header        = "ERROR: Install Property file [" 
+ this.propFile.getAbsolutePath() + "] can not be read.";
+                HelpFormatter helpFormatter = new HelpFormatter();
+                helpFormatter.printHelp("java " + 
XmlConfigChanger.class.getName(), header, options, null, true);
+                throw new RuntimeException(header);
+            }
+        }
+    }
+
+    public void run() throws ParserConfigurationException, SAXException, 
IOException, TransformerException {
+        loadInstallProperties();
+
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+        
factory.setFeature("http://xml.org/sax/features/external-general-entities";, 
false);
+        
factory.setFeature("http://xml.org/sax/features/external-parameter-entities";, 
false);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.parse(inpFile);
+
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new FileReader(confFile));
+
+            String line = null;
+
+            @SuppressWarnings("unused")
+            int lineNo = 0;
+            Properties variables = new Properties();
+            while ((line = reader.readLine()) != null) {
+                lineNo++;
+                line = line.trim();
+                if (line.isEmpty()) {
+                    continue;
+                }
+                if (line.startsWith("#")) {
+                    continue;
+                }
+                if (line.contains("#")) {
+                    int len = line.indexOf("#");
+                    line = line.substring(0, len);
+                }
+                String[] tokens    = line.split("\\s+");
+                String   propName  = tokens[0];
+                String   propValue = null;
+                try {
+                    if (propnameContainsVariables(propName)) {
+                        propName = replaceProp(propName, variables);
+                    }
+                    propValue = replaceProp(tokens[1], installProperties);
+                } catch (ValidationException e) {
+                    throw new RuntimeException(e);
+                }
+
+                String  actionType        = tokens[2];
+                String  options           = (tokens.length > 3 ? tokens[3] : 
null);
+                boolean createIfNotExists = (options != null && 
options.contains("create-if-not-exists"));
+
+                if ("add".equals(actionType)) {
+                    addProperty(propName, propValue);
+                } else if ("mod".equals(actionType)) {
+                    modProperty(propName, propValue, createIfNotExists);
+                } else if ("del".equals(actionType)) {
+                    delProperty(propName);
+                } else if ("append".equals(actionType)) {
+                    String curVal = getProperty(propName);
+                    if (curVal == null) {
+                        if (createIfNotExists) {
+                            addProperty(propName, propValue);
+                        }
+                    } else {
+                        String appendDelimitor = (tokens.length > 4 ? 
tokens[4] : " ");
+                        if (!curVal.contains(propValue)) {
+                            String newVal = null;
+                            if (curVal.length() == 0) {
+                                newVal = propValue;
+                            } else {
+                                newVal = curVal + appendDelimitor + propValue;
+                            }
+                            modProperty(propName, newVal, createIfNotExists);
+                        }
+                    }
+                } else if ("delval".equals(actionType)) {
+                    String curVal = getProperty(propName);
+                    if (curVal != null) {
+                        String appendDelimitor = (tokens.length > 4 ? 
tokens[4] : " ");
+                        if (curVal.contains(propValue)) {
+                            String[]      valTokens = 
curVal.split(appendDelimitor);
+                            StringBuilder sb        = new StringBuilder();
+                            for (String v : valTokens) {
+                                if (!v.equals(propValue)) {
+                                    if (sb.length() > 0) {
+                                        sb.append(appendDelimitor);
+                                    }
+                                    sb.append(v);
+                                }
+                            }
+                            String newVal = sb.toString();
+                            modProperty(propName, newVal, createIfNotExists);
+                        }
+                    }
+                } else if ("var".equals(actionType)) {
+                    variables.put(propName, propValue);
+                } else {
+                    throw new RuntimeException("Unknown Command Found: [" + 
actionType + "], Supported Types:  add modify del append");
+                }
+            }
+
+            TransformerFactory tfactory = TransformerFactory.newInstance();
+            tfactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, 
Boolean.TRUE);
+            Transformer transformer = tfactory.newTransformer();
+            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+            
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount";, "4");
+
+            DOMSource        source = new DOMSource(doc);
+            FileOutputStream out    = new FileOutputStream(outFile);
+            StreamResult     result = new StreamResult(out);
+            transformer.transform(source, result);
+            out.close();
+        } finally {
+            if (reader != null) {
+                reader.close();
+            }
+        }
+    }
+
+    /**
+     * Check if prop name contains a substitution variable embedded in it, 
e.g. %VAR_NAME%.
+     *
+     * @param propName
+     * @return true if propname contains at least 2 '%' characters in it, else 
false
+     */
+    private boolean propnameContainsVariables(String propName) {
+        if (propName != null) {
+            int first = propName.indexOf('%');
+            if (first != -1) {
+                // indexof is safe even if 2nd argument is beyond size of 
string, i.e. if 1st percent was the last character of the string.
+                int second = propName.indexOf('%', first + 1);
+                if (second != -1) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private void addProperty(String propName, String val) {
+        NodeList nl         = doc.getElementsByTagName(ROOT_NODE_NAME);
+        Node     rootConfig = nl.item(0);
+        rootConfig.appendChild(createNewElement(propName, val));
+    }
+
+    private void modProperty(String propName, String val, boolean 
createIfNotExists) {
+        Node node = findProperty(propName);
+        if (node != null) {
+            NodeList cnl = node.getChildNodes();
+            for (int j = 0; j < cnl.getLength(); j++) {
+                String nodeName = cnl.item(j).getNodeName();
+                if (nodeName.equals(VALUE_NODE_NAME)) {
+                    if (cnl.item(j).hasChildNodes()) {
+                        cnl.item(j).getChildNodes().item(0).setNodeValue(val);
+                    } else {
+                        Node propValueNode = cnl.item(j);
+                        Node txtNode       = doc.createTextNode(val);
+                        propValueNode.appendChild(txtNode);
+                        txtNode.setNodeValue(val);
+                    }
+                    return;
+                }
+            }
+        }
+        if (createIfNotExists) {
+            addProperty(propName, val);
+        }
+    }
+
+    private String getProperty(String propName) {
+        String ret = null;
+        try {
+            Node node = findProperty(propName);
+            if (node != null) {
+                NodeList cnl = node.getChildNodes();
+                for (int j = 0; j < cnl.getLength(); j++) {
+                    String nodeName = cnl.item(j).getNodeName();
+                    if (nodeName.equals(VALUE_NODE_NAME)) {
+                        Node valueNode = null;
+                        if (cnl.item(j).hasChildNodes()) {
+                            valueNode = cnl.item(j).getChildNodes().item(0);
+                        }
+                        if (valueNode == null) {    // Value Node is defined 
with
+                            ret = "";
+                        } else {
+                            ret = valueNode.getNodeValue();
+                        }
+                        break;
+                    }
+                }
+            }
+        } catch (Throwable t) {
+            throw new RuntimeException("getProperty(" + propName + ") 
failed.", t);
+        }
+        return ret;
+    }
+
+    private void delProperty(String propName) {
+        Node node = findProperty(propName);
+        if (node != null) {
+            node.getParentNode().removeChild(node);
+        }
+    }
+
+    private Node findProperty(String propName) {
+        Node ret = null;
+        try {
+            NodeList nl = doc.getElementsByTagName(PROPERTY_NODE_NAME);
+
+            for (int i = 0; i < nl.getLength(); i++) {
+                NodeList cnl   = nl.item(i).getChildNodes();
+                boolean  found = false;
+                for (int j = 0; j < cnl.getLength(); j++) {
+                    String nodeName = cnl.item(j).getNodeName();
+                    if (nodeName.equals(NAME_NODE_NAME)) {
+                        String pName = 
cnl.item(j).getChildNodes().item(0).getNodeValue();
+                        found = pName.equals(propName);
+                        if (found) {
+                            break;
+                        }
+                    }
+                }
+                if (found) {
+                    ret = nl.item(i);
+                    break;
+                }
+            }
+        } catch (Throwable t) {
+            throw new RuntimeException("findProperty(" + propName + ") 
failed.", t);
+        }
+        return ret;
+    }
+
+    private Element createNewElement(String propName, String val) {
+        Element ret = null;
+
+        try {
+            if (doc != null) {
+                ret = doc.createElement(PROPERTY_NODE_NAME);
+                Node propNameNode = doc.createElement(NAME_NODE_NAME);
+                Node txtNode      = doc.createTextNode(propName);
+                propNameNode.appendChild(txtNode);
+                propNameNode.setNodeValue(propName);
+                ret.appendChild(propNameNode);
+
+                Node propValueNode = doc.createElement(VALUE_NODE_NAME);
+                txtNode = doc.createTextNode(val);
+                propValueNode.appendChild(txtNode);
+                propValueNode.setNodeValue(propName);
+                ret.appendChild(propValueNode);
+            }
+        } catch (Throwable t) {
+            throw new RuntimeException("createNewElement(" + propName + ") 
with value [" + val + "] failed.", t);
+        }
+
+        return ret;
+    }
+
+    private void loadInstallProperties() {
+        if (propFile != null) {
+            try (FileInputStream in = new FileInputStream(propFile)) {
+                installProperties.load(in);
+            } catch (IOException ioe) {
+                System.err.println("******* ERROR: load file failure. The 
reason: " + ioe.getMessage());
+                ioe.printStackTrace();
+            }
+        }
+        // To support environment variable, we will add all environment 
variables to the Properties
+        installProperties.putAll(System.getenv());
+    }
+
+    private String replaceProp(String propValue, Properties prop) throws 
ValidationException {
+        StringBuilder tokensb = new StringBuilder();
+        StringBuilder retsb   = new StringBuilder();
+        boolean       isToken = false;
+
+        for (char c : propValue.toCharArray()) {
+            if (c == '%') {
+                if (isToken) {
+                    String token      = tokensb.toString();
+                    String tokenValue = (token.length() == 0 ? "%" : 
prop.getProperty(token));
+                    if (tokenValue == null || tokenValue.trim().isEmpty()) {
+                        throw new ValidationException("ERROR: configuration 
token [" + token + "] is not defined in the file: [" + (propFile != null ? 
propFile.getAbsolutePath() : "{no install.properties file specified using -p 
option}") + "]");
+                    } else {
+                        if (EMPTY_TOKEN.equals(tokenValue)) {
+                            retsb.append(EMPTY_TOKEN_VALUE);
+                        } else {
+                            retsb.append(tokenValue);
+                        }
+                    }
+                    isToken = false;
+                } else {
+                    isToken = true;
+                    tokensb.setLength(0);
+                }
+            } else if (isToken) {
+                tokensb.append(String.valueOf(c));
+            } else {
+                retsb.append(String.valueOf(c));
+            }
+        }
+
+        if (isToken) {
+            throw new ValidationException("ERROR: configuration has a token 
defined without end-token [" + propValue + "] in the file: [" + (propFile != 
null ? propFile.getAbsolutePath() : "{no install.properties file specified 
using -p option}") + "]");
+        }
+
+        return retsb.toString();
+    }
+
+    class ValidationException extends Exception {
+        public ValidationException(String msg) {
+            super(msg);
+        }
+
+        public ValidationException(Throwable cause) {
+            super(cause);
+        }
+    }
 }


Reply via email to