项目需求:把指定的Spring配置文件的指定密码提取出来,用Spring风格的占位符取代。
并把取出的密码集中保存到唯一的properties格式的文件中。
完整的项目代码和资源请查看附件。
build.gradle
apply plugin: 'groovy' repositories { mavenLocal() mavenCentral() } dependencies { compile 'org.codehaus.groovy:groovy-all:2.3.7' compile 'org.apache.ant:ant:1.9.4' testCompile 'junit:junit:4.11' testCompile 'commons-io:commons-io:2.2' } sourceSets { main { groovy { srcDirs = ['./src/main/groovy'] include 'Main.groovy' } } test { groovy { srcDirs = ['./src/test/groovy'] } } } task runScript(type: JavaExec) { description 'Run Groovy script' // Set main property to name of Groovy script class. main = 'Main' // Set classpath for running the Groovy script. classpath = sourceSets.main.runtimeClasspath } defaultTasks 'runScript'
Main.groovy
import groovy.util.Node import groovy.xml.XmlUtil public class Main{ public static final String LINE_SEPARATOR = System.getProperty("line.separator") boolean extractPassword(Node root, def map){ boolean update = false String beanId String propertyName for(def entry: map.entrySet()){ beanId = entry.key.split('_')[0] propertyName = entry.key.split('_')[-1] def node = root.find{ it."@id" == beanId }.find{ it."@name" == propertyName } String password = node.attribute("value") if( password ==~ /\$\{.*?\}/ ){ println "It's already a place-holder of Spring style. Skip." continue } node."@value" = '${' + entry.key + '}' entry.value = password update = true //println XmlUtil.serialize(node) } return update } void saveXml(String fileName, Node xml){ def writer = new FileWriter(fileName) def printer = new XmlNodePrinter(new PrintWriter(writer)) printer.preserveWhitespace = true printer.print(xml) } void saveSstsConfiguration(String fileName, def map){ File file = new File(fileName) Properties props = new Properties() file.withInputStream{ stream -> props.load(stream) } boolean update = false map.entrySet().each{ entry-> if(props[entry.key] == null){ if( !(entry.value ==~ /\$\{.*?\}/) ){ file.append(LINE_SEPARATOR + "${entry.key}=${entry.value}") update = true } } } if(update){ file.append(LINE_SEPARATOR) } } static main(args){ Main obj = new Main() String fileName = "./src/main/resources/Spring-Config.xml" def map = ["database_password":"", "sybase_password":""] File file = new File(fileName) Node root = new XmlParser().parseText(file.getText()) boolean update = obj.extractPassword(root, map) if(update){ new AntBuilder().copy( file:fileName, tofile:fileName + "_Bak") obj.saveXml(fileName, root) String sstsConfiguration = "./src/main/resources/ssts.configuration" new AntBuilder().copy( file:sstsConfiguration, tofile:sstsConfiguration + "_Bak") obj.saveSstsConfiguration(sstsConfiguration, map) }else{ println "No update and no replication." } println map } }
MainTest.groovy
import org.junit.* import static org.junit.Assert.* import org.apache.commons.io.FileUtils import groovy.util.AntBuilder import groovy.xml.XmlUtil import groovy.util.Node import org.apache.commons.io.FileUtils class MainTest { private obj = null static final String input = '''<beans xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <bean id="database" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=gbk"/> <property name="username" value="root"/> <property name="password" value="sa"/> </bean> <bean id="sybase" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=gbk"/> <property name="username" value="root"/> <property name="password" value="ind_suezssts"/> </bean> </beans> ''' static final String target = '''<beans xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <bean id="database" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=gbk"/> <property name="username" value="root"/> <property name="password" value="${database_password}"/> </bean> <bean id="sybase" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=gbk"/> <property name="username" value="root"/> <property name="password" value="${sybase_password}"/> </bean> </beans> ''' static def map = null static Node root static Node xml @BeforeClass public static void enter(){ } @Before public void setUp(){ root = new XmlParser().parseText(input) xml = new XmlParser().parseText(target) obj = new Main() map = ["database_password":"", "sybase_password":""] } @Test public void extractPasswordReturnTrue(){ boolean result = obj.extractPassword(root, map) def mymap = ["database_password":"sa", "sybase_password":"ind_suezssts"] assertTrue result assertEquals mymap,map assertEquals XmlUtil.serialize(xml), XmlUtil.serialize(root) } @Test public void extractPasswordReturnFalse(){ Node myxml = new XmlParser().parseText(target) boolean result = obj.extractPassword(xml, map) def mymap = ["database_password":"", "sybase_password":""] assertFalse result assertEquals mymap,map assertEquals XmlUtil.serialize(myxml), XmlUtil.serialize(xml) } @Test public void saveXml(){ //String fileName, Node xml String fileName = "./src/test/resources/test-A.xml" new File(fileName).delete() obj.saveXml(fileName, xml) assertTrue new File(fileName).exists() Node myxml = new XmlParser().parseText(new File(fileName).getText()) assertEquals XmlUtil.serialize(myxml), XmlUtil.serialize(xml) } // void saveSstsConfiguration(String fileName, def map){ @Test public void saveSstsConfiguration(){ String fileName = "./src/test/resources/ssts.configuration.test" String fileTarget = "./src/test/resources/ssts.configuration.target" new File(fileName).write("") boolean result = obj.extractPassword(root, map) obj.saveSstsConfiguration(fileName, map) assertEquals(FileUtils.readLines(new File(fileName)), FileUtils.readLines(new File(fileTarget))); } }
项目结构:
G:\share\groovy\centralize-password>tree 卷 DOC 的文件夹 PATH 列表 卷序列号为 9AC5-4EB7 G:. ├─src │ ├─main │ │ ├─groovy │ │ └─resources │ └─test │ ├─groovy │ └─resources