ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jesse Glick <jesse.gl...@sun.com>
Subject Re: Creating Filesets based on file contents
Date Mon, 15 Oct 2001 09:08:59 GMT
Magesh Umasankar wrote:
> I have hacked some code so that we would be able to
> create a patternset/fileset based on the contents of
> the file.  For example, we can do:
> [snip]

I did something similar recently (not based on contents but CVS status):

http://www.netbeans.org/source/browse/nbbuild/antsrc/org/netbeans/nbbuild/CvsFileSet.java?rev=1.1&content-type=text/x-cvsweb-markup

Writing the FileSet subclass was not so much of a problem, as how to use it.
As written in a bug I filed recently, <typedef> did not seem to get me
anywhere and I needed to modify tasks I wanted to use with it:

public void addCvsFileSet(CvsFileSet fs) {
    addFileSet(fs);
}

Clearly putting additional behavior like this into plain FileSet is out of the
question, some extensibility mechanism is needed. How do you extend such
things? I assumed there would be some kind of data type like <selector> that
you could use, along the lines of <mapper> which is not quite right for this
purpose:

<copy todir="...">
    <fileset dir="...">
        <include name="..."/>
        <selector type="org.netbeans.nbbuild.CvsFileSet"
                  criterion="text"/>
    </fileset>
</copy>

This would create a new CvsFileSet instance, cast to
org.apache.tools.ant.types.Selector or whatever, initialize it with a generic
argument setCriterion("text"), and use it to filter out non-text files.

Unfortunately there does not appear to be any such construction, as there is
for <mapper>s. Should there be?


One nasty problem I see with the pluggable mapper system is that there is no
way for a custom mapper class to be configured using richer data than a String
for 'from' and a String for 'to'. Specifically it cannot use additional
attributes, subelements, etc. This is a basic limitation of Ant's system of
introspection and XML configuration as far as I can tell. Maybe something like
<mapperdef/> would be a better solution: add to the "namespace" of mapper
elements, so instead of writing:

<copy ...>
    <mapper type="glob" from="*" to="*.orig"/>
</copy>

you would write:

<copy ...>
    <globmapper from="*" to="*.orig"/>
</copy>

and instead of:

<copy ...>
    <mapper classname="my.new.MapperType" classpath="..."
            to="{*.orig:*}{*.bak:*}{default:*}"/>
</copy>

you could do it right:

<mapperdef name="mymapper" classname="my.new.MapperType"
           classpath="..."/>
<copy ...>
    <mymapper>
        <case from="*.orig" to="*"/>
        <case from="*.bak" to="*"/>
        <default to="*"/>
    </mymapper>
</copy>

(Possibly plain <typedef/> could do instead of <mapperdef/>.) Somehow the Copy
task would need to indicate that it could accept any subelements with a
defined name whose class is assignable to FileNameMapper. The task could have:

public void addGeneric(FileNameMapper mapper);

where the keyword "generic" means to actually look in the name -> type mapping
for the actual sub element names. Only the add- and not create-variant of this
method could be supported of course. The same mechanism could be useful for
other purposes, esp. the EJB tasks I think.

Note you could not switch mapper type at runtime. I can't imagine why you
would actually want to anyway. But it means that this style would not be
proper for e.g. setting arguments to <javac> that might differ by compiler
implementation, as it makes perfect sense to switch Java compiler based on a
property, or generally situations where different implementations are
configured mostly uniformly.

-Jesse

-- 
Jesse Glick        <mailto:jesse.glick@sun.com>
NetBeans, Open APIs  <http://www.netbeans.org/>

Mime
View raw message