You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@excalibur.apache.org by le...@apache.org on 2004/09/07 15:03:24 UTC

svn commit: rev 43470 - excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools

Author: leif
Date: Tue Sep  7 06:03:23 2004
New Revision: 43470

Added:
   excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/ChangedFileOutputStream.java
Modified:
   excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/Component.java
   excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/ComponentMetaInfoCollector.java
   excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/Service.java
Log:
Modify the Meta generation so that meta files are only rewritten if their contents have changed.  This is necessary to keep Ant from rebuilding jars even when there were no changes to their contents.

Added: excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/ChangedFileOutputStream.java
==============================================================================
--- (empty file)
+++ excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/ChangedFileOutputStream.java	Tue Sep  7 06:03:23 2004
@@ -0,0 +1,179 @@
+/* 
+ * Copyright 2003-2004 The Apache Software Foundation
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at 
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.avalon.fortress.tools;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * OutputStream which will only update an existing file if its contents
+ *  actually change.  Needed to keep Ant from rebuilding jars even when
+ *  nothing has changed.
+ *
+ * @author <a href="mailto:dev@avalon.apache.org">The Avalon Team</a>
+ * @version CVS $Revision: 1.1 $ $Date: 2004/04/02 08:29:44 $
+ */
+public final class ChangedFileOutputStream
+    extends OutputStream
+{
+    /** The file to write to. */
+    private File m_file;
+    
+    /** The output stream used to buffer data being writen. */
+    private ByteArrayOutputStream m_bos;
+    
+    /*---------------------------------------------------------------
+     * Constructor
+     *-------------------------------------------------------------*/
+    /**
+     * Creates a new ChangedFileOutputStream.
+     *
+     * @param file The file to write to.
+     */
+    public ChangedFileOutputStream( File file )
+    {
+        m_file = file;
+        m_bos = new ByteArrayOutputStream();
+    }
+    
+    /*---------------------------------------------------------------
+     * OutputStream Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Writes the specified byte to this output stream.
+     *
+     * @param b Byte to write.
+     *
+     * @throws IOException If an I/O error occurs.
+     */
+    public void write( int b )
+        throws IOException
+    {
+        m_bos.write( b );
+    }
+    
+    /**
+     * Close the stream.
+     *
+     * @throws IOException If an I/O error occurs.
+     */
+    public void close()
+        throws IOException
+    {
+        byte[] newContent = m_bos.toByteArray();
+        m_bos.close();
+        
+        boolean changed;
+        if ( m_file.exists() )
+        {
+            byte[] oldContent = readBytes( m_file );
+            
+            // Compare the old and new bytes.
+            if ( newContent.length != oldContent.length )
+            {
+                changed = true;
+            }
+            else
+            {
+                changed = false;
+                for ( int i = 0; i < newContent.length; i++ )
+                {
+                    if ( newContent[i] != oldContent[i] )
+                    {
+                        changed = true;
+                        break;
+                    }
+                }
+            }
+        }
+        else
+        {
+            // File does not exist.
+            changed = true;
+        }
+        
+        if ( changed )
+        {
+            writeBytes( m_file, newContent );
+        }
+    }
+    
+    /*---------------------------------------------------------------
+     * Methods
+     *-------------------------------------------------------------*/
+    /**
+     * Reads the full contents of a file into a byte array.  The file contents
+     *  are treated as binary data.
+     *
+     * @param file File to read.
+     *
+     * @return The contents of the file as a byte array.
+     *
+     * @throws IOException If the file could not be read for any reason.
+     */
+    private byte[] readBytes( File file )
+        throws IOException
+    {
+        byte[] bytes = new byte[(int)file.length()];
+        
+        FileInputStream is = new FileInputStream( file );
+        try
+        {
+            // Make sure all bytes are read in.
+            int pos = 0;
+            int read;
+            while ( ( pos < bytes.length ) &&
+                ( ( read = is.read( bytes, pos, bytes.length - pos ) ) >= 0 ) )
+            {
+                pos += read;
+            }
+        }
+        finally
+        {
+            is.close();
+        }
+        
+        return bytes;
+    }
+    
+    /**
+     * Reads the full contents of a byte array out to a file.
+     *
+     * @param file File to write to.
+     * @param bytes The binary data to write.
+     *
+     * @throws IOException If the file could not be written to for any reason.
+     */
+    private void writeBytes( File file, byte[] bytes )
+        throws IOException
+    {
+        FileOutputStream os = new FileOutputStream( file );
+        try
+        {
+            os.write( bytes, 0, bytes.length );
+        }
+        finally
+        {
+            os.close();
+        }
+    }
+}

Modified: excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/Component.java
==============================================================================
--- excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/Component.java	(original)
+++ excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/Component.java	Tue Sep  7 06:03:23 2004
@@ -23,8 +23,12 @@
 import org.apache.tools.ant.BuildException;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
 import java.util.*;
 
 /**
@@ -286,6 +290,48 @@
     {
         m_attributes.setProperty( name, value );
     }
+    
+    /**
+     * Only writes the properties file if it is new or if the existing file
+     *  contains different values.
+     */
+    private void writeIfChanged( Properties props, File file, String desc )
+        throws IOException
+    {
+        boolean changed;
+        if ( file.exists() )
+        {
+            Properties oldProps = new Properties();
+            FileInputStream is = new FileInputStream( file );
+            try
+            {
+                oldProps.load( is );
+            }
+            finally
+            {
+                is.close();
+            }
+            
+            changed = !props.equals( oldProps );
+        }
+        else
+        {
+            changed = true;
+        }
+        
+        if ( changed )
+        {
+            FileOutputStream os = new FileOutputStream( file );
+            try
+            {
+                props.store( os, desc );
+            }
+            finally
+            {
+                os.close();
+            }
+        }
+    }
 
     /**
      * Output the meta information.
@@ -297,35 +343,32 @@
     {
         final String fileName = getType().replace( '.', '/' ).concat( ".meta" );
         final String depsName = getType().replace( '.', '/' ).concat( ".deps" );
-        File output = new File( rootDir, fileName );
-        FileOutputStream writer = null;
-
-        try
-        {
-            writer = new FileOutputStream( output );
-            m_attributes.store( writer, "Meta information for " + getType() );
-
-            if ( m_dependencies.size() > 0 )
+        
+        // Write out the meta file if it has changed.
+        writeIfChanged( m_attributes, new File( rootDir, fileName ),
+            "Meta information for " + getType() );
+        
+        final File depsFile = new File( rootDir, depsName );
+        if ( m_dependencies.size() > 0 )
+        {
+            final PrintWriter writer = new PrintWriter( new OutputStreamWriter(
+                new ChangedFileOutputStream( depsFile ), "UTF-8" ) );
+            try
             {
-                writer.close();
-                output = new File( rootDir, depsName );
-                writer = new FileOutputStream( output );
-
-                Iterator it = m_dependencies.iterator();
-                while ( it.hasNext() )
+                for ( Iterator iter = m_dependencies.iterator(); iter.hasNext(); )
                 {
-                    Service service = (Service) it.next();
-                    String name = service.getType() + "\n";
-                    writer.write( name.getBytes() );
+                    Service service = (Service)iter.next();
+                    writer.println( service.getType() );
                 }
             }
-        }
-        finally
-        {
-            if ( null != writer )
+            finally
             {
                 writer.close();
             }
+        }
+        else if ( depsFile.exists() )
+        {
+            depsFile.delete();
         }
     }
 

Modified: excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/ComponentMetaInfoCollector.java
==============================================================================
--- excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/ComponentMetaInfoCollector.java	(original)
+++ excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/ComponentMetaInfoCollector.java	Tue Sep  7 06:03:23 2004
@@ -28,8 +28,8 @@
 import org.apache.tools.ant.Project;
 
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 
 import java.util.ArrayList;
@@ -125,7 +125,7 @@
 
         DirectedAcyclicGraphVerifier.verify( dagVerifyList );
     }
-
+    
     /**
      * Write the service list to the "/service.list" file.
      *
@@ -134,16 +134,22 @@
      */
     public void writeServiceList( final Iterator it ) throws IOException
     {
-        final PrintWriter writer = new PrintWriter( new FileWriter( m_serviceFile ) );
         int numServices = 0;
-
-        while ( it.hasNext() )
+    
+        final PrintWriter writer = new PrintWriter(
+            new OutputStreamWriter( new ChangedFileOutputStream( m_serviceFile ), "UTF-8" ) );
+        try
         {
-            writer.println( ( (Service) it.next() ).getType() );
-            numServices++;
+            while ( it.hasNext() )
+            {
+                writer.println( ( (Service) it.next() ).getType() );
+                numServices++;
+            }
+        }
+        finally
+        {
+            writer.close();
         }
-
-        writer.close();
 
         if ( numServices == 0 )
         {

Modified: excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/Service.java
==============================================================================
--- excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/Service.java	(original)
+++ excalibur/trunk/fortress/meta/src/java/org/apache/avalon/fortress/tools/Service.java	Tue Sep  7 06:03:23 2004
@@ -18,8 +18,8 @@
 package org.apache.avalon.fortress.tools;
 
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -89,12 +89,11 @@
         if ( m_components.isEmpty() ) return;
 
         final File serviceFile = new File( rootDir, "META-INF/services/" + getType() );
-        PrintWriter writer = null;
-
+        
+        final PrintWriter writer = new PrintWriter(
+            new OutputStreamWriter( new ChangedFileOutputStream( serviceFile ), "UTF-8" ) );
         try
         {
-            writer = new PrintWriter( new FileWriter( serviceFile ) );
-
             final Iterator it = m_components.iterator();
             while ( it.hasNext() )
             {
@@ -104,10 +103,7 @@
         }
         finally
         {
-            if ( null != writer )
-            {
-                writer.close();
-            }
+            writer.close();
         }
     }
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: scm-unsubscribe@excalibur.apache.org
For additional commands, e-mail: scm-help@excalibur.apache.org