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