/**
* 学习jdom操作xml的习作:解析ant的build文件,目的是得到target的执行顺序
*
*/
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
public class AntFileParser {
private static Map<String, Element> targetMap;
/**
* @param args
*/
public static void main(String[] args) {
String xmlfile = "xmlfile/aaa.xml";
Document doc;
String finalTarget = "run";
try {
doc = build(xmlfile);
} catch (JDOMException e) {
throw new RuntimeException("parse error" + e, e);
} catch (IOException e) {
throw new RuntimeException("parse error" + e, e);
}
generateTargetNameMap(doc);
// 首先将最终任务入栈
Stack<String> stack = new Stack<String>();
stack.push(finalTarget);
// 计算其他任务的执行顺序
getExecuteOrder(findElementByAttributeName(finalTarget), stack);
System.out.print("执行顺序: ");
while (!stack.isEmpty()) {
System.out.print(stack.pop() + " ");
}
}
public static Document build(String file) throws JDOMException, IOException {
SAXBuilder b = new SAXBuilder();
Document doc = b.build(new File(file));
return doc;
}
/**
* 获取所有target元素
*
* @param doc
* @return
*/
public static List getTarget(Document doc) {
return doc.getRootElement().getChildren("target");
}
/**
* 获取指定元素的所有依赖
*
* @param element
* @return
*/
public static String[] getDepents(Element element) {
String depends = element.getAttribute("depends").getValue();
return depends.split(",");
}
/**
* 使用递归的方法查找执行顺序
*
* @param element
* @param stack
*/
public static void getExecuteOrder(Element element, Stack<String> stack) {
String cur;
if (element.getAttribute("depends") == null) {
// 已经找到了第一个任务,退出
return;
} else {
String[] depends = getDepents(element);
cur = depends[0];
if (depends.length != 1) {
// 存在多个依赖任务,可能有两种情况:
// (1)多个任务之间有依赖关系,则返回依赖最大的任务;
// (2)多个任务之间没有依赖关系,则返回全部依赖,用逗号分隔
cur = getmaxDependence(depends);
}
String[] curs = cur.split(",");
// 如果存在并行任务且并行任务之间没有互相依赖,则一并放入堆栈,无所谓顺序
for (String string : curs) {
element = findElementByAttributeName(string);
// 检查是否已经入栈
if (!stack.contains(element.getAttributeValue("name")))
stack.push(element.getAttributeValue("name"));
}
// 递归
getExecuteOrder(element, stack);
}
}
/**
* 从缓存的Map中,依据target元素的name属性查找target元素
*
* @param name
* @return
*/
public static Element findElementByAttributeName(String name) {
return targetMap.get(name);
}
/**
* 将target元素和其name属性缓存到map中
*
* @param doc
*/
public static void generateTargetNameMap(Document doc) {
List targetList = getTarget(doc);
targetMap = new HashMap<String, Element>();
for (Object object : targetList) {
Element ele = (Element) object;
String name = ele.getAttributeValue("name");
targetMap.put(name, ele);
}
}
public static String getmaxDependence(String[] depends) {
int size = depends.length;
String target = "";
// 保存每一个任务对其他任务的存在依赖关系的次数
int[] counts = new int[size];
//
for (int i = 0; i < size; i++) {
Element cur = findElementByAttributeName(depends[i]);
// 将数组转换成ArrayList
List list = arrayToList(getDepents(cur));
for (int j = i + 1; j < size; j++) {
// 检查当前任务对depends数组中的其他任务是否存在依赖
if (list.contains(depends[j])) {
counts[i]++;
}
}
}
// 获取最大依赖
int max = 0;
for (int a : counts) {
if (max < a)
max = a;
}
// 如果最大依赖为0,则说明depends中的任务之间没有互相依赖,为并行任务,转换逗号分隔返回
if (max == 0) {
for (int i = 0; i < size; i++) {
target = target + depends[i] + ",";
}
// 除去最后一个逗号
target = target.substring(0, target.length() - 1);
return target;
}
// 否则,任务之间存在依赖,取最大依赖
for (int i = 0; i < size; i++) {
if (counts[i] == max)
target = depends[i];
}
return target;
}
public static List<String> arrayToList(String[] array) {
ArrayList<String> list = new ArrayList<String>();
for (String string : array) {
list.add(string);
}
return list;
}
}
用到的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project name="srping_study" default="run">
<property name="src" value="src" />
<property name="bin" value="bin" />
<property name="test" value="test" />
<property name="run.classpath" value="bin" />
<property name="lib" value="lib" />
<property name="xmlfile" value="xmlfile" />
<path id="spring.lib">
<pathelement path="${lib}" />
<fileset dir="${lib}" includes="*.jar" />
</path>
<target name="clear">
<delete dir="${bin}" quiet="true" />
</target>
<target name="compile" depends="clear">
<mkdir dir="bin" />
<javac destdir="${run.classpath}" srcdir="${src}" classpathref="spring.lib">
</javac>
<copy todir="${run.classpath}">
<fileset dir="${xmlfile}">
<include name="*.xml" />
<include name="*.properties" />
</fileset>
</copy>
</target>
<target name="deploy" depends="compile">
<java classname="org.chen.spring_study.HibernateUtil" classpathref="spring.lib">
<classpath path="${run.classpath}" />
</java>
</target>
<target name="deploy1" depends="deploy">
<java classname="org.chen.spring_study.HibernateUtil" classpathref="spring.lib">
<classpath path="${run.classpath}" />
</java>
</target>
<target name="test" depends="compile">
<java classname="org.chen.spring_study.transaction.programmic.ProgramicCodingTrans" classpathref="spring.lib">
<classpath path="${run.classpath}" />
</java>
</target>
<target name="run" depends="test,deploy,deploy1">
<java classname="org.chen.spring_study.transaction.declaretrans.DeclareClient" classpathref="spring.lib">
<classpath path="${run.classpath}" />
</java>
</target>
</project>