Date: 2004-02-28T18:14:14 Editor: 218.214.49.176 <> Wiki: Ant Wiki Page: AntOddities URL: http://wiki.apache.org/ant/AntOddities
no comment Change Log: ------------------------------------------------------------------------------ @@ -1,44 +1,44 @@ -== <fileset>s strange behaviour == +== <fileset>'s strange behaviour == -Here is an oddity whose solution was discovered by Jan Matèrne. In Ant, what is the simplest way to get a <fileset> that contains only files that do '''not''' have an extension in a directory tree. +Here is an oddity whose solution was discovered by Jan Matèrne. In Ant, what is the simplest way to get a <fileset> that contains only files that do '''not''' have an extension in a directory tree. You might think you could just specify that the included files end in a period, like so: -{{{ <fileset includes="**/*." /> }}} +{{{ <fileset includes="**/*." /> }}} but that will only select files which literally end in a period. The actual answer is a bit counterintuitive. You select all files (implicit) and then exclude those that have an extension: -{{{ <fileset excludes="*.*" /> }}} +{{{ <fileset excludes="*.*" /> }}} == Changing default Locale == When I worked with CheckStyle I realized that there are localized message. So far so fine. But now I want to generate an international (English) site on my (German) machine. But how to realize that? -CheckStyle - like many other programs - uses the java.util.ResourceBundle.getBundle() method which returns the appropriate bundle for the '''default''' Locale. So I will set the default Locale to the US value. Before that I store the actual one (or the 'key') as property and restore that after invoking CheckStyle. Because I need (simple) access to the Java API, I write that inside <script> tasks: +CheckStyle - like many other programs - uses the java.util.ResourceBundle.getBundle() method which returns the appropriate bundle for the '''default''' Locale. So I will set the default Locale to the US value. Before that I store the actual one (or the 'key') as property and restore that after invoking CheckStyle. Because I need (simple) access to the Java API, I write that inside <script> tasks: -{{{ <script language="javascript"> <![CDATA[ }}} -{{{ importClass(java.util.Locale); }}} -{{{ actualDefault = Locale.getDefault(); }}} -{{{ project.setProperty("---actual-default-locale---", actualDefault); }}} -{{{ Locale.setDefault(Locale.US); }}} -{{{ ]]></script> }}} - -{{{ <ant .../> }}} - -{{{ <script language="javascript"> <![CDATA[ }}} -{{{ importClass(java.util.Locale); }}} -{{{ actualDefault = project.getProperty("---actual-default-locale---"); }}} -{{{ Locale.setDefault(new Locale(actualDefault)); }}} -{{{ ]]></script> }}} +{{{ <script language="javascript"> <![CDATA[ + importClass(java.util.Locale); + actualDefault = Locale.getDefault(); + project.setProperty("---actual-default-locale---", actualDefault); + Locale.setDefault(Locale.US); + ]]></script> + + <ant .../> + + <script language="javascript"> <![CDATA[ + importClass(java.util.Locale); + actualDefault = project.getProperty("---actual-default-locale---"); + Locale.setDefault(new Locale(actualDefault)); + ]]></script> }}} ''Jan Matèrne'' -== Using your own classes inside <script> == +== Using your own classes inside <script> == -When you use <script language="javascript"> you are using the Java API. Ok so far. It´s simple to use java.io.File for getting information about a particular file or creating complex strings with java.util.StringBuffer. But there are two problems: +When you use <script language="javascript"> you are using the Java API. Ok so far. It´s simple to use java.io.File for getting information about a particular file or creating complex strings with java.util.StringBuffer. But there are two problems: * How to import other (non java.*) classes, e.g. Ant´s own classes? * How to import classes which are '''not''' on Ant´s classpath? @@ -54,22 +54,22 @@ And now the trick: Ant´s Project class provides methods for getting classloader. And there is one which includes specified paths. So we * get the ''ext'' directory - * create a <path> object + * create a <path> object * get the classloader * load the class * instantiate that -{{{ <script language="javascript"> <![CDATA[ }}} -{{{ importClass(java.util.TreeSet); }}} -{{{ importClass(Packages.org.apache.tools.ant.types.Path); }}} - -{{{ loaderpath = new Path(project, project.getProperty("ext.dir")); }}} -{{{ classloader = project.createClassLoader(loaderpath); }}} -{{{ comparatorClass = classloader.loadClass("ReportDateComparator"); }}} -{{{ comparator = comparatorClass.newInstance(); }}} +{{{ <script language="javascript"> <![CDATA[ + importClass(java.util.TreeSet); + importClass(Packages.org.apache.tools.ant.types.Path); + + loaderpath = new Path(project, project.getProperty("ext.dir")); + classloader = project.createClassLoader(loaderpath); + comparatorClass = classloader.loadClass("ReportDateComparator"); + comparator = comparatorClass.newInstance(); -{{{ list = new TreeSet(comparator); }}} -{{{ ]]></script> }}} + list = new TreeSet(comparator); + ]]></script> }}} ''Jan Matèrne'' @@ -77,49 +77,49 @@ == Writing a "Task" for getting the dependency list for a target == That was the question I was asked recently on [http://jguru.com/forums/view.jsp?EID=1122213 jGuru]. That was a nice question :-) The final result is -{{{ <macrodef name="dep"> }}} -{{{ <attribute name="root"/> }}} -{{{ <attribute name="file" default="${root}.dep"/> }}} -{{{ <sequential> }}} -{{{ <script language="javascript"> <![CDATA[ }}} -{{{ // attribute expansion from macrodef (script can´t reach the values) }}} -{{{ root = "${root}"; }}} -{{{ filename = "${file}"; }}} - -{{{ // for collecting the informations }}} -{{{ lineSep = project.getProperty("line.separator"); }}} -{{{ list = new java.lang.StringBuffer(); }}} -{{{ file = new java.io.File(filename); }}} - -{{{ // get all targets of the current project }}} -{{{ targets = project.getTargets(); }}} - -{{{ // get the dependencies - including not executing targets }}} -{{{ sorted = project.topoSort(root, targets); }}} - -{{{ // create the list and break if we have "executed" our root target }}} -{{{ // this code is adapted from Project.executeTarget(String) }}} -{{{ for(it=sorted.iterator(); it.hasNext();) { }}} -{{{ curTarget = it.next(); }}} -{{{ list.append(curTarget).append(lineSep); }}} -{{{ if (curTarget.getName().equals(root)) { }}} -{{{ break; }}} -{{{ } }}} -{{{ } }}} - -{{{ // create the file }}} -{{{ echo = project.createTask("echo"); }}} -{{{ echo.setMessage(list.toString()); }}} -{{{ echo.setFile(file); }}} -{{{ echo.perform(); }}} -{{{ ]]></script> }}} -{{{ </sequential> }}} -{{{ </macrodef> }}} - -{{{ <target name="dep"> }}} -{{{ <dep root="build"/> }}} -{{{ <dep root="dist-lite" file="dist_lite.txt"/> }}} -{{{ </target> }}} +{{{ <macrodef name="dep"> + <attribute name="root"/> + <attribute name="file" default="${root}.dep"/> + <sequential> + <script language="javascript"> <![CDATA[ + // attribute expansion from macrodef (script can´t reach the values) + root = "${root}"; + filename = "${file}"; + + // for collecting the informations + lineSep = project.getProperty("line.separator"); + list = new java.lang.StringBuffer(); + file = new java.io.File(filename); + + // get all targets of the current project + targets = project.getTargets(); + + // get the dependencies - including not executing targets + sorted = project.topoSort(root, targets); + + // create the list and break if we have "executed" our root target + // this code is adapted from Project.executeTarget(String) + for(it=sorted.iterator(); it.hasNext();) { + curTarget = it.next(); + list.append(curTarget).append(lineSep); + if (curTarget.getName().equals(root)) { + break; + } + } + + // create the file + echo = project.createTask("echo"); + echo.setMessage(list.toString()); + echo.setFile(file); + echo.perform(); + ]]></script> + </sequential> + </macrodef> + + <target name="dep"> + <dep root="build"/> + <dep root="dist-lite" file="dist_lite.txt"/> + </target> }}} ''Jan Matèrne'' @@ -143,85 +143,85 @@ * ''proxy.port'': proxy settings And the final buildfile is: -{{{ <project default="main"> }}} +{{{ <project default="main"> -{{{ <taskdef resource="net/sf/antcontrib/antcontrib.properties"/> }}} + <taskdef resource="net/sf/antcontrib/antcontrib.properties"/> -{{{ <property name="result.file" value="check-downloads-results.properties"/> }}} -{{{ <property file="check-downloads.properties"/> }}} -{{{ <property file="${result.file}"/> }}} - -{{{ <target name="main"> }}} -{{{ <setproxy proxyHost="${proxy.host}" proxyPort="${proxy.port}"/> }}} -{{{ <foreach list="${file.list}" param="file" target="checkFile"/> }}} -{{{ </target> }}} - -{{{ <target name="checkFile" depends="check.download,check.md5-1,check.md5-2" if="file"/> }}} - -{{{ <target name="check.init"> }}} -{{{ <property name="zip.file" value="${file}"/> }}} -{{{ <property name="md5.file" value="${file}.md5"/> }}} -{{{ <condition property="md5-ok"><isset property="${zip.file}.isValid"/></condition> }}} -{{{ <condition property="download-ok"> }}} -{{{ <and> }}} -{{{ <available file="${dest.dir}/${zip.file}"/> }}} -{{{ <available file="${dest.dir}/${md5.file}"/> }}} -{{{ </and> }}} -{{{ </condition> }}} -{{{ </target> }}} - -{{{ <target name="check.download" unless="download-ok" depends="check.init"> }}} -{{{ <echo>Download ${md5.file}</echo> }}} -{{{ <get src="${download.md5.dir}/${md5.file}" dest="${dest.dir}/${md5.file}"/> }}} -{{{ <echo>Download ${zip.file}</echo> }}} -{{{ <get src="${download.zip.dir}/${zip.file}" dest="${dest.dir}/${zip.file}"/> }}} -{{{ </target> }}} - -{{{ <target name="check.md5-1" if="md5-ok" depends="check.init"> }}} -{{{ <echo>${zip.file}: just processed</echo> }}} -{{{ </target> }}} - -{{{ <target name="check.md5-2" unless="md5-ok" depends="check.init"> }}} -{{{ <trycatch><try> }}} -{{{ <!-- what is the valid md5 value specified in the md5 file --> }}} -{{{ <loadfile srcFile="${md5.file}" property="md5.valid"> }}} -{{{ <filterchain> }}} -{{{ <striplinebreaks/> }}} -{{{ <tokenfilter> }}} -{{{ <stringtokenizer/> }}} -{{{ <replaceregex pattern="${zip.file}" replace=''''''/> }}} -{{{ </tokenfilter> }}} -{{{ <tokenfilter> }}} -{{{ <trim/> }}} -{{{ </tokenfilter> }}} -{{{ </filterchain> }}} -{{{ </loadfile> }}} -{{{ <!-- what is the actual md5 value --> }}} -{{{ <checksum file="${zip.file}" property="md5.actual"/> }}} -{{{ <!-- compare them --> }}} -{{{ <condition property="md5.isValid"> }}} -{{{ <equals arg1="${md5.valid}" arg2="${md5.actual}"/> }}} -{{{ </condition> }}} -{{{ <property name="md5.isValid" value="false"/> }}} -{{{ <!-- print the result --> }}} -{{{ <if> }}} -{{{ <istrue value="${md5.isValid}"/> }}} -{{{ <then> }}} -{{{ <echo>${zip.file}: ok</echo> }}} -{{{ <echo file="${result.file}" }}} -{{{ append="true" }}} -{{{ message="${zip.file}.isValid=true${line.separator}"/> }}} -{{{ </then> }}} -{{{ <else> }}} -{{{ <echo>${zip.file}: Wrong MD5 checksum !!!</echo> }}} -{{{ <echo>- expected: ${md5.valid}</echo> }}} -{{{ <echo>- actual : ${md5.actual}</echo> }}} -{{{ <move file="${zip.file}" tofile="${zip.file}.wrong-checksum"/> }}} -{{{ </else> }}} -{{{ </if> }}} -{{{ </try><catch/></trycatch> }}} -{{{ </target> }}} -{{{ </project> }}} + <property name="result.file" value="check-downloads-results.properties"/> + <property file="check-downloads.properties"/> + <property file="${result.file}"/> + + <target name="main"> + <setproxy proxyHost="${proxy.host}" proxyPort="${proxy.port}"/> + <foreach list="${file.list}" param="file" target="checkFile"/> + </target> + + <target name="checkFile" depends="check.download,check.md5-1,check.md5-2" if="file"/> + + <target name="check.init"> + <property name="zip.file" value="${file}"/> + <property name="md5.file" value="${file}.md5"/> + <condition property="md5-ok"><isset property="${zip.file}.isValid"/></condition> + <condition property="download-ok"> + <and> + <available file="${dest.dir}/${zip.file}"/> + <available file="${dest.dir}/${md5.file}"/> + </and> + </condition> + </target> + + <target name="check.download" unless="download-ok" depends="check.init"> + <echo>Download ${md5.file}</echo> + <get src="${download.md5.dir}/${md5.file}" dest="${dest.dir}/${md5.file}"/> + <echo>Download ${zip.file}</echo> + <get src="${download.zip.dir}/${zip.file}" dest="${dest.dir}/${zip.file}"/> + </target> + + <target name="check.md5-1" if="md5-ok" depends="check.init"> + <echo>${zip.file}: just processed</echo> + </target> + + <target name="check.md5-2" unless="md5-ok" depends="check.init"> + <trycatch><try> + <!-- what is the valid md5 value specified in the md5 file --> + <loadfile srcFile="${md5.file}" property="md5.valid"> + <filterchain> + <striplinebreaks/> + <tokenfilter> + <stringtokenizer/> + <replaceregex pattern="${zip.file}" replace=''''''/> + </tokenfilter> + <tokenfilter> + <trim/> + </tokenfilter> + </filterchain> + </loadfile> + <!-- what is the actual md5 value --> + <checksum file="${zip.file}" property="md5.actual"/> + <!-- compare them --> + <condition property="md5.isValid"> + <equals arg1="${md5.valid}" arg2="${md5.actual}"/> + </condition> + <property name="md5.isValid" value="false"/> + <!-- print the result --> + <if> + <istrue value="${md5.isValid}"/> + <then> + <echo>${zip.file}: ok</echo> + <echo file="${result.file}" + append="true" + message="${zip.file}.isValid=true${line.separator}"/> + </then> + <else> + <echo>${zip.file}: Wrong MD5 checksum !!!</echo> + <echo>- expected: ${md5.valid}</echo> + <echo>- actual : ${md5.actual}</echo> + <move file="${zip.file}" tofile="${zip.file}.wrong-checksum"/> + </else> + </if> + </try><catch/></trycatch> + </target> + </project> }}} I got very nice results when starting with -quiet mode. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]