项目需求:把指定的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