/**
* 学习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>