You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by William Uther <wi...@cs.cmu.edu> on 2000/02/19 00:14:26 UTC

Copying meta-info on a mac (and small bug fix)

Hi all,
  As I'm sure most of you know, Macs carry meta-info around with their
files.  Currently ANT's copyFile methods don't copy that.  I've modified
the Project.copyFile() method to copy that data.  My modifications use this
open source java library: <http://www.amug.org/~glguerin/sw/#macbinary>.

  At the same time I noticed that the copyFile method will leave the file
open if an IOException is thrown.  I've added try/finally blocks to close
the files.

  Both modifications should have no effect on Non-Mac platforms.  You'll
need to download the library though.

later,

\x/ill         :-}

Here is the replacement copyFile method.  Sorry, I don't have a 'diff'
utility on my Mac, so this is the entire method:

    public void copyFile(File sourceFile, File destFile, boolean filtering)
        throws IOException
    {

        if (destFile.lastModified() < sourceFile.lastModified()) {
            log("Copy: " + sourceFile.getAbsolutePath() + " > "
                    + destFile.getAbsolutePath(), MSG_VERBOSE);

            // ensure that parent dir of dest file exists!
            // not using getParentFile method to stay 1.1 compat
            File parent = new File(destFile.getParent());
            if (!parent.exists()) {
                parent.mkdirs();
            }

            if (filtering) {
                BufferedReader in = null;
                BufferedWriter out = null;

		try {
	                int length;
			String line;
	                String newline = null;

			in = new BufferedReader(new FileReader(sourceFile));
			out = new BufferedWriter(new FileWriter(destFile));
	                line = in.readLine();
	                while (line != null) {
	                    if (line.length() == 0) {
	                        out.newLine();
	                    } else {
	                        newline = replace(line, filters);
	                        out.write(newline);
	                        out.newLine();
	                    }
	                    line = in.readLine();
	                }
		} finally {
			if (out != null)
                		out.close();
                	if (in != null)
                		in.close();
                }
            } else {
                FileInputStream in = null;
                FileOutputStream out = null;

		try {
			in = new FileInputStream(sourceFile);
			out = new FileOutputStream(destFile);
					
	                byte[] buffer = new byte[8 * 1024];
	                int count = 0;
	                do {
	                    out.write(buffer, 0, count);
	                    count = in.read(buffer, 0, buffer.length);
	                } while (count != -1);
				} finally {
                	if (in != null)
                		in.close();
					if (out != null)
                		out.close();
                }
            }
            
            // now copy the mac resource fork and other Meta-Info.
            // Should never filter the Meta-Info!
            if (glguerin.util.MacPlatform.getJDirectVersion() == 2) {

	glguerin.mac.io.MacFileForker.SetFactoryName("glguerin.mac.io.imp.macos.JD
2.JD2Forker");
            	glguerin.mac.io.MacFileForker sourceFF =
            		glguerin.mac.io.MacFileForker.MakeOne(
            			new glguerin.mac.io.MacFilePathname(sourceFile));
            	glguerin.mac.io.MacFileForker destFF =
            		glguerin.mac.io.MacFileForker.MakeOne(
            			new glguerin.mac.io.MacFilePathname(destFile));
            	
            	if (!sourceFile.isDirectory()) {
            		InputStream in = null;
            		OutputStream out = null;
            		
            		try {
            			in = sourceFF.makeForkInputStream(true);
            			out = destFF.makeForkOutputStream(true);
            			
		                byte[] buffer = new byte[8 * 1024];
		                int count = 0;
		                do {
		                    out.write(buffer, 0, count);
		                    count = in.read(buffer, 0, buffer.length);
		                } while (count != -1);
			} finally {
				if (in != null)
		                	in.close();
		                if (out != null)
		                	out.close();
	                }
            	}
            	
            	destFF.setCatalogInfo(sourceFF.getCatalogInfo(true));
            }
        }
    }



Re: Copying meta-info on a mac (and small bug fix)

Posted by James Duncan Davidson <ja...@eng.sun.com>.
> I guess you could say it is a bug in Java (and UNIX)'s impoverished
concept
> of a file.  Almost every OS I know of has meta-info with files (Apple II
> DOS 3.3, Apple II ProDOS, Apple IIGS GSOS, AmigaDOS, Microsoft Windows NT
> (some versions), BeOS).  Java provides no standard way to access it.

Even though NTFS has support for meta-info, it isn't typically used like it
is for MacOS. Too much need to support FAT based systems so everything is
done with extension mappings.

.duncan


RE: Platform specific code (was: Meta-info on Mac)

Posted by Conor MacNeill <co...@ebinteractive.com.au>.

> -----Original Message-----
> From: Stefano Mazzocchi [mailto:stefano@apache.org]
> Sent: Wednesday, 23 February 2000 5:09
> To: ant-dev@jakarta.apache.org
> Subject: Re: Platform specific code (was: Meta-info on Mac)
>
>
> William Uther wrote:
> >
> >
> > No, I hadn't.  I just went searching for it and found:
> >
> > <http://ptolemy.eecs.berkeley.edu/~cxh/java/javadepend/>
> >
> > and
> >
> > <http://www.cs.McGill.CA/~stever/software/JavaDeps/>
> >
> > It looks like both of these process the source to get the dependancies.
> > Arnout Kuiper's method of looking in the .class files looks cool too.
>
> to be honest, I didn't quite get Arnout's idea... :/
>

When a Java class references another class (a dependency), the class file's
constant pool will have a constant pool entry for the referred class. It is
possible to read the constant pool entries and thereby determine the
dependencies. I would guess that parsing the source is generally harder :-)

Conor


Re: Platform specific code (was: Meta-info on Mac)

Posted by Stefano Mazzocchi <st...@apache.org>.
William Uther wrote:
> 
> --On Tue, Feb 22, 2000 1:02 PM +0100 Stefano Mazzocchi <st...@apache.org>
> wrote:
> 
> > sometimes devs don't have all the free time they'd like to :(
> 
> I understand.  Believe me, I understand. :)
> 
> >> > I don't want to have dependencies on stuff like that.
> >> >
> >> > Can't you use reflection to instance the classes?
> >>
> >> Ok.  I'll rewrite it with reflection and repost it.  Given that the other
> >> would compile and run fine on all platforms I didn't bother before.
> >
> > As a standard design pattern and development guideline, ant should not
> > depend on packages for compilation that are platform dependent. Say I
> > want to have a task that sets the windows registry, I use reflection.
> > Say I want a task for compilation dependencies that uses another
> > packages and that is redistributable, then yes, it's fine for me...
> > we'll make the build.xml file work around its absence, if required.
> 
> What do you mean by 'platform dependant'?  Do you mean 'This only works on
> one platform', or 'This is only needed on one plaform'?  In this case it
> seems you mean the second definition - I originally assumed the first.
> 
> It is a little annoying to use reflection for the whole thing.  How does
> this setup look:
> 
> Add a package: org.apache.tools.ant.platform
> with a sub-package: org.apache.tools.ant.platform.mac
> 
> add an interface
> 
> interface org.apache.tools.ant.argRunnable {
>         Object run(Object[] args);
> }
> 
> modify build.xml to exclude the platform package.  Add extra rules to
> comile the individual platforms:
> 
>   <target name="compile" depends="prepare">
>     <mkdir dir="${build.classes}"/>
>     <javac srcdir="${src.dir}"
>            destdir="${build.classes}"
>            excludes="**/platform/**"
>            classpath="${classpath}"
>            debug="on"
>            deprecation="on"
>     />
>   </target>
> 
>   <target name="mac" depends="compile">
>     <javac srcdir="${src.dir}"
>            destdir="${build.classes}"
>            includes="**/platform/mac/**"
>            classpath="${classpath}"
>            debug="on"
>            deprecation="on"
>     />
>   </target>
> 
> Then in the main code you can try to load the appropriate
> platform-dependant class, make a new argRunnable instance and call it.
> Most of the plaform dependant code goes into the argRunnable instance and
> doesn't have to use reflection.  This gives you compile-time type checking,
> etc.

+1
 
> > (BTW, have you guys looked at javadep?)
> 
> No, I hadn't.  I just went searching for it and found:
> 
> <http://ptolemy.eecs.berkeley.edu/~cxh/java/javadepend/>
> 
> and
> 
> <http://www.cs.McGill.CA/~stever/software/JavaDeps/>
> 
> It looks like both of these process the source to get the dependancies.
> Arnout Kuiper's method of looking in the .class files looks cool too.

to be honest, I didn't quite get Arnout's idea... :/ 

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------
 Come to the first official Apache Software Foundation Conference!  
------------------------- http://ApacheCon.Com ---------------------



Re: Platform specific code (was: Meta-info on Mac)

Posted by William Uther <wi...@cs.cmu.edu>.
--On Tue, Feb 22, 2000 1:02 PM +0100 Stefano Mazzocchi <st...@apache.org>
wrote:

> sometimes devs don't have all the free time they'd like to :(

I understand.  Believe me, I understand. :)

>> > I don't want to have dependencies on stuff like that.
>> > 
>> > Can't you use reflection to instance the classes?
>> 
>> Ok.  I'll rewrite it with reflection and repost it.  Given that the other
>> would compile and run fine on all platforms I didn't bother before.
> 
> As a standard design pattern and development guideline, ant should not
> depend on packages for compilation that are platform dependent. Say I
> want to have a task that sets the windows registry, I use reflection.
> Say I want a task for compilation dependencies that uses another
> packages and that is redistributable, then yes, it's fine for me...
> we'll make the build.xml file work around its absence, if required. 

What do you mean by 'platform dependant'?  Do you mean 'This only works on
one platform', or 'This is only needed on one plaform'?  In this case it
seems you mean the second definition - I originally assumed the first.

It is a little annoying to use reflection for the whole thing.  How does
this setup look:

Add a package: org.apache.tools.ant.platform
with a sub-package: org.apache.tools.ant.platform.mac

add an interface

interface org.apache.tools.ant.argRunnable {
	Object run(Object[] args);
}

modify build.xml to exclude the platform package.  Add extra rules to
comile the individual platforms:

  <target name="compile" depends="prepare">
    <mkdir dir="${build.classes}"/>
    <javac srcdir="${src.dir}"
           destdir="${build.classes}"
           excludes="**/platform/**"
           classpath="${classpath}"
           debug="on"
           deprecation="on"
    />
  </target>

  <target name="mac" depends="compile">
    <javac srcdir="${src.dir}"
           destdir="${build.classes}"
           includes="**/platform/mac/**"
           classpath="${classpath}"
           debug="on"
           deprecation="on"
    />
  </target>

Then in the main code you can try to load the appropriate
platform-dependant class, make a new argRunnable instance and call it.
Most of the plaform dependant code goes into the argRunnable instance and
doesn't have to use reflection.  This gives you compile-time type checking,
etc.

> (BTW, have you guys looked at javadep?)

No, I hadn't.  I just went searching for it and found:

<http://ptolemy.eecs.berkeley.edu/~cxh/java/javadepend/>

and

<http://www.cs.McGill.CA/~stever/software/JavaDeps/>

It looks like both of these process the source to get the dependancies.
Arnout Kuiper's method of looking in the .class files looks cool too.

later,

\x/ill           :-}



Re: Copying meta-info on a mac (and small bug fix)

Posted by Stefano Mazzocchi <st...@apache.org>.
Will Uther wrote:
> 
> Hi,
>   Thankyou very much for the reply.  It's nice to know someone is alive :).

sometimes devs don't have all the free time they'd like to :(
 
> --On Mon, Feb 21, 2000 7:00 PM +0100 Stefano Mazzocchi <st...@apache.org>
> wrote:
> 
> [snip new copy code]
> 
> > I don't want to have dependencies on stuff like that.
> >
> > Can't you use reflection to instance the classes?
> 
> Ok.  I'll rewrite it with reflection and repost it.  Given that the other
> would compile and run fine on all platforms I didn't bother before.

As a standard design pattern and development guideline, ant should not
depend on packages for compilation that are platform dependent. Say I
want to have a task that sets the windows registry, I use reflection.
Say I want a task for compilation dependencies that uses another
packages and that is redistributable, then yes, it's fine for me...
we'll make the build.xml file work around its absence, if required. 

(BTW, have you guys looked at javadep?)

> > Anyway, isn't this a mac JDK bug?
> 
> No.  The Mac Java runtime uses the standard Java API to access the data
> forks of files and their filenames - just like it should.  The problem is
> that Macs have more info in their files than that.
> 
> I guess you could say it is a bug in Java (and UNIX)'s impoverished concept
> of a file.  Almost every OS I know of has meta-info with files (Apple II
> DOS 3.3, Apple II ProDOS, Apple IIGS GSOS, AmigaDOS, Microsoft Windows NT
> (some versions), BeOS).  Java provides no standard way to access it.

Well, Java is a common denominator between platform. You don't achieve
portability if some API are not possible to be implemented in some
operating systems.... but I see your point and I agree that when we can
we should provide all possible tools.
 
> I guess that they could also have provided a general copyTo() method the
> same way they made a renameTo() method...  anyway.
> 
> later,
> 
> \x/ill          :-}


-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------
 Come to the first official Apache Software Foundation Conference!  
------------------------- http://ApacheCon.Com ---------------------



Re: Copying meta-info on a mac (and small bug fix)

Posted by Will Uther <wi...@cs.cmu.edu>.
Hi,
  Thankyou very much for the reply.  It's nice to know someone is alive :).

--On Mon, Feb 21, 2000 7:00 PM +0100 Stefano Mazzocchi <st...@apache.org>
wrote:

[snip new copy code]

> I don't want to have dependencies on stuff like that.
> 
> Can't you use reflection to instance the classes? 

Ok.  I'll rewrite it with reflection and repost it.  Given that the other
would compile and run fine on all platforms I didn't bother before.

> Anyway, isn't this a mac JDK bug?

No.  The Mac Java runtime uses the standard Java API to access the data
forks of files and their filenames - just like it should.  The problem is
that Macs have more info in their files than that.

I guess you could say it is a bug in Java (and UNIX)'s impoverished concept
of a file.  Almost every OS I know of has meta-info with files (Apple II
DOS 3.3, Apple II ProDOS, Apple IIGS GSOS, AmigaDOS, Microsoft Windows NT
(some versions), BeOS).  Java provides no standard way to access it.

I guess that they could also have provided a general copyTo() method the
same way they made a renameTo() method...  anyway.

later,

\x/ill          :-}


Re: Copying meta-info on a mac (and small bug fix)

Posted by Stefano Mazzocchi <st...@apache.org>.
William Uther wrote:
> 
> Hi all,
>   As I'm sure most of you know, Macs carry meta-info around with their
> files.  Currently ANT's copyFile methods don't copy that.  I've modified
> the Project.copyFile() method to copy that data.  My modifications use this
> open source java library: <http://www.amug.org/~glguerin/sw/#macbinary>.
> 
>   At the same time I noticed that the copyFile method will leave the file
> open if an IOException is thrown.  I've added try/finally blocks to close
> the files.
> 
>   Both modifications should have no effect on Non-Mac platforms.  You'll
> need to download the library though.
> 
> later,
> 
> \x/ill         :-}
> 
> Here is the replacement copyFile method.  Sorry, I don't have a 'diff'
> utility on my Mac, so this is the entire method:
> 
>     public void copyFile(File sourceFile, File destFile, boolean filtering)
>         throws IOException
>     {
> 
>         if (destFile.lastModified() < sourceFile.lastModified()) {
>             log("Copy: " + sourceFile.getAbsolutePath() + " > "
>                     + destFile.getAbsolutePath(), MSG_VERBOSE);
> 
>             // ensure that parent dir of dest file exists!
>             // not using getParentFile method to stay 1.1 compat
>             File parent = new File(destFile.getParent());
>             if (!parent.exists()) {
>                 parent.mkdirs();
>             }
> 
>             if (filtering) {
>                 BufferedReader in = null;
>                 BufferedWriter out = null;
> 
>                 try {
>                         int length;
>                         String line;
>                         String newline = null;
> 
>                         in = new BufferedReader(new FileReader(sourceFile));
>                         out = new BufferedWriter(new FileWriter(destFile));
>                         line = in.readLine();
>                         while (line != null) {
>                             if (line.length() == 0) {
>                                 out.newLine();
>                             } else {
>                                 newline = replace(line, filters);
>                                 out.write(newline);
>                                 out.newLine();
>                             }
>                             line = in.readLine();
>                         }
>                 } finally {
>                         if (out != null)
>                                 out.close();
>                         if (in != null)
>                                 in.close();
>                 }
>             } else {
>                 FileInputStream in = null;
>                 FileOutputStream out = null;
> 
>                 try {
>                         in = new FileInputStream(sourceFile);
>                         out = new FileOutputStream(destFile);
> 
>                         byte[] buffer = new byte[8 * 1024];
>                         int count = 0;
>                         do {
>                             out.write(buffer, 0, count);
>                             count = in.read(buffer, 0, buffer.length);
>                         } while (count != -1);
>                                 } finally {
>                         if (in != null)
>                                 in.close();
>                                         if (out != null)
>                                 out.close();
>                 }
>             }
> 
>             // now copy the mac resource fork and other Meta-Info.
>             // Should never filter the Meta-Info!
>             if (glguerin.util.MacPlatform.getJDirectVersion() == 2) {
> 
>         glguerin.mac.io.MacFileForker.SetFactoryName("glguerin.mac.io.imp.macos.JD
> 2.JD2Forker");
>                 glguerin.mac.io.MacFileForker sourceFF =
>                         glguerin.mac.io.MacFileForker.MakeOne(
>                                 new glguerin.mac.io.MacFilePathname(sourceFile));
>                 glguerin.mac.io.MacFileForker destFF =
>                         glguerin.mac.io.MacFileForker.MakeOne(
>                                 new glguerin.mac.io.MacFilePathname(destFile));

-1

I don't want to have dependencies on stuff like that.

Can't you use reflection to instance the classes? 

Anyway, isn't this a mac JDK bug?

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<st...@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------
 Come to the first official Apache Software Foundation Conference!  
------------------------- http://ApacheCon.Com ---------------------



Re: Can't compile ANT (am I dumb???)

Posted by Pierpaolo Fumagalli <pi...@apache.org>.
Pierpaolo Fumagalli wrote:
> 
> I have a slight problem... I can't compile ant...
> I tried to do it by hand, and to download the nightly build of Feb. 18
> but in both cases, when I try to compile anything (even ANT) I get
> a nullpointerexception...
> Do someone have a recent working copy of the JAR that can mail to me?
> Thanks :)

Fixed... Sorry... I AM dumb :)

	Pier

-- 
--------------------------------------------------------------------
-          P              I              E              R          -
stable structure erected over water to allow the docking of seacraft
<ma...@betaversion.org>    <http://www.betaversion.org/~pier/>
--------------------------------------------------------------------
- ApacheCON Y2K: Come to the official Apache developers conference -
-------------------- <http://www.apachecon.com> --------------------

Can't compile ANT (am I dumb???)

Posted by Pierpaolo Fumagalli <pi...@apache.org>.
I have a slight problem... I can't compile ant...
I tried to do it by hand, and to download the nightly build of Feb. 18
but in both cases, when I try to compile anything (even ANT) I get
a nullpointerexception...
Do someone have a recent working copy of the JAR that can mail to me?
Thanks :)

	Pier

-- 
--------------------------------------------------------------------
-          P              I              E              R          -
stable structure erected over water to allow the docking of seacraft
<ma...@betaversion.org>    <http://www.betaversion.org/~pier/>
--------------------------------------------------------------------
- ApacheCON Y2K: Come to the official Apache developers conference -
-------------------- <http://www.apachecon.com> --------------------

Re: Copying meta-info on a mac (and small bug fix)

Posted by James Duncan Davidson <ja...@eng.sun.com>.
>   As I'm sure most of you know, Macs carry meta-info around with their
> files.  Currently ANT's copyFile methods don't copy that.  I've modified
> the Project.copyFile() method to copy that data.  My modifications use
this
> open source java library: <http://www.amug.org/~glguerin/sw/#macbinary>.

Looks like this library is under the Artistic license. This should create
any problems.

>   At the same time I noticed that the copyFile method will leave the file
> open if an IOException is thrown.  I've added try/finally blocks to close
> the files.

Good catch.

>   Both modifications should have no effect on Non-Mac platforms.  You'll
> need to download the library though.

Actually, there is an effect. The code isn't compiliable unless the
macbinary classes are present. Since the code is under the artistic, it's
probably possible to check this code into the repository and use it. Or
better yet, just reflect the classes and the methods so that there's no
compilation dependancy. If this is done, I welcome the changes, if not, then
I'll have to block as the tree has to be compiliable out of the box.

Any comments?