View Javadoc
1   package org.eclipse.aether.internal.impl;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   * 
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.FileInputStream;
24  import java.io.FileOutputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.io.OutputStream;
28  import java.nio.ByteBuffer;
29  import java.nio.charset.StandardCharsets;
30  
31  import javax.inject.Named;
32  
33  import org.eclipse.aether.spi.io.FileProcessor;
34  
35  /**
36   * A utility class helping with file-based operations.
37   */
38  @Named
39  public class DefaultFileProcessor
40      implements FileProcessor
41  {
42  
43      /**
44       * Thread-safe variant of {@link File#mkdirs()}. Creates the directory named by the given abstract pathname,
45       * including any necessary but nonexistent parent directories. Note that if this operation fails it may have
46       * succeeded in creating some of the necessary parent directories.
47       * 
48       * @param directory The directory to create, may be {@code null}.
49       * @return {@code true} if and only if the directory was created, along with all necessary parent directories;
50       *         {@code false} otherwise
51       */
52      public boolean mkdirs( File directory )
53      {
54          if ( directory == null )
55          {
56              return false;
57          }
58  
59          if ( directory.exists() )
60          {
61              return false;
62          }
63          if ( directory.mkdir() )
64          {
65              return true;
66          }
67  
68          File canonDir;
69          try
70          {
71              canonDir = directory.getCanonicalFile();
72          }
73          catch ( IOException e )
74          {
75              return false;
76          }
77  
78          File parentDir = canonDir.getParentFile();
79          return ( parentDir != null && ( mkdirs( parentDir ) || parentDir.exists() ) && canonDir.mkdir() );
80      }
81  
82      public void write( File target, String data )
83          throws IOException
84      {
85          mkdirs( target.getAbsoluteFile().getParentFile() );
86  
87          OutputStream out = null;
88          try
89          {
90              out = new FileOutputStream( target );
91  
92              if ( data != null )
93              {
94                  out.write( data.getBytes( StandardCharsets.UTF_8 ) );
95              }
96  
97              out.close();
98              out = null;
99          }
100         finally
101         {
102             try
103             {
104                 if ( out != null )
105                 {
106                     out.close();
107                 }
108             }
109             catch ( final IOException e )
110             {
111                 // Suppressed due to an exception already thrown in the try block.
112             }
113         }
114     }
115 
116     public void write( File target, InputStream source )
117         throws IOException
118     {
119         mkdirs( target.getAbsoluteFile().getParentFile() );
120 
121         OutputStream out = null;
122         try
123         {
124             out = new FileOutputStream( target );
125 
126             copy( out, source, null );
127 
128             out.close();
129             out = null;
130         }
131         finally
132         {
133             try
134             {
135                 if ( out != null )
136                 {
137                     out.close();
138                 }
139             }
140             catch ( final IOException e )
141             {
142                 // Suppressed due to an exception already thrown in the try block.
143             }
144         }
145     }
146 
147     public void copy( File source, File target )
148         throws IOException
149     {
150         copy( source, target, null );
151     }
152 
153     public long copy( File source, File target, ProgressListener listener )
154         throws IOException
155     {
156         long total = 0L;
157 
158         InputStream in = null;
159         OutputStream out = null;
160         try
161         {
162             in = new FileInputStream( source );
163 
164             mkdirs( target.getAbsoluteFile().getParentFile() );
165 
166             out = new FileOutputStream( target );
167 
168             total = copy( out, in, listener );
169 
170             out.close();
171             out = null;
172 
173             in.close();
174             in = null;
175         }
176         finally
177         {
178             try
179             {
180                 if ( out != null )
181                 {
182                     out.close();
183                 }
184             }
185             catch ( final IOException e )
186             {
187                 // Suppressed due to an exception already thrown in the try block.
188             }
189             finally
190             {
191                 try
192                 {
193                     if ( in != null )
194                     {
195                         in.close();
196                     }
197                 }
198                 catch ( final IOException e )
199                 {
200                     // Suppressed due to an exception already thrown in the try block.
201                 }
202             }
203         }
204 
205         return total;
206     }
207 
208     private long copy( OutputStream os, InputStream is, ProgressListener listener )
209         throws IOException
210     {
211         long total = 0L;
212 
213         ByteBuffer buffer = ByteBuffer.allocate( 1024 * 32 );
214         byte[] array = buffer.array();
215 
216         while ( true )
217         {
218             int bytes = is.read( array );
219             if ( bytes < 0 )
220             {
221                 break;
222             }
223 
224             os.write( array, 0, bytes );
225 
226             total += bytes;
227 
228             if ( listener != null && bytes > 0 )
229             {
230                 try
231                 {
232                     buffer.rewind();
233                     buffer.limit( bytes );
234                     listener.progressed( buffer );
235                 }
236                 catch ( Exception e )
237                 {
238                     // too bad
239                 }
240             }
241         }
242 
243         return total;
244     }
245 
246     public void move( File source, File target )
247         throws IOException
248     {
249         if ( !source.renameTo( target ) )
250         {
251             copy( source, target );
252 
253             target.setLastModified( source.lastModified() );
254 
255             source.delete();
256         }
257     }
258 
259 }