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.Buffer;
29  import java.nio.ByteBuffer;
30  import java.nio.charset.StandardCharsets;
31  
32  import javax.inject.Named;
33  
34  import org.eclipse.aether.spi.io.FileProcessor;
35  
36  /**
37   * A utility class helping with file-based operations.
38   */
39  @Named
40  public class DefaultFileProcessor
41      implements FileProcessor
42  {
43  
44      /**
45       * Thread-safe variant of {@link File#mkdirs()}. Creates the directory named by the given abstract pathname,
46       * including any necessary but nonexistent parent directories. Note that if this operation fails it may have
47       * succeeded in creating some of the necessary parent directories.
48       *
49       * @param directory The directory to create, may be {@code null}.
50       * @return {@code true} if and only if the directory was created, along with all necessary parent directories;
51       *         {@code false} otherwise
52       */
53      public boolean mkdirs( File directory )
54      {
55          if ( directory == null )
56          {
57              return false;
58          }
59  
60          if ( directory.exists() )
61          {
62              return false;
63          }
64          if ( directory.mkdir() )
65          {
66              return true;
67          }
68  
69          File canonDir;
70          try
71          {
72              canonDir = directory.getCanonicalFile();
73          }
74          catch ( IOException e )
75          {
76              return false;
77          }
78  
79          File parentDir = canonDir.getParentFile();
80          return ( parentDir != null && ( mkdirs( parentDir ) || parentDir.exists() ) && canonDir.mkdir() );
81      }
82  
83      public void write( File target, String data )
84          throws IOException
85      {
86          mkdirs( target.getAbsoluteFile().getParentFile() );
87  
88          OutputStream out = null;
89          try
90          {
91              out = new FileOutputStream( target );
92  
93              if ( data != null )
94              {
95                  out.write( data.getBytes( StandardCharsets.UTF_8 ) );
96              }
97  
98              out.close();
99              out = null;
100         }
101         finally
102         {
103             try
104             {
105                 if ( out != null )
106                 {
107                     out.close();
108                 }
109             }
110             catch ( final IOException e )
111             {
112                 // Suppressed due to an exception already thrown in the try block.
113             }
114         }
115     }
116 
117     public void write( File target, InputStream source )
118         throws IOException
119     {
120         mkdirs( target.getAbsoluteFile().getParentFile() );
121 
122         OutputStream out = null;
123         try
124         {
125             out = new FileOutputStream( target );
126 
127             copy( out, source, null );
128 
129             out.close();
130             out = null;
131         }
132         finally
133         {
134             try
135             {
136                 if ( out != null )
137                 {
138                     out.close();
139                 }
140             }
141             catch ( final IOException e )
142             {
143                 // Suppressed due to an exception already thrown in the try block.
144             }
145         }
146     }
147 
148     public void copy( File source, File target )
149         throws IOException
150     {
151         copy( source, target, null );
152     }
153 
154     public long copy( File source, File target, ProgressListener listener )
155         throws IOException
156     {
157         long total = 0L;
158 
159         InputStream in = null;
160         OutputStream out = null;
161         try
162         {
163             in = new FileInputStream( source );
164 
165             mkdirs( target.getAbsoluteFile().getParentFile() );
166 
167             out = new FileOutputStream( target );
168 
169             total = copy( out, in, listener );
170 
171             out.close();
172             out = null;
173 
174             in.close();
175             in = null;
176         }
177         finally
178         {
179             try
180             {
181                 if ( out != null )
182                 {
183                     out.close();
184                 }
185             }
186             catch ( final IOException e )
187             {
188                 // Suppressed due to an exception already thrown in the try block.
189             }
190             finally
191             {
192                 try
193                 {
194                     if ( in != null )
195                     {
196                         in.close();
197                     }
198                 }
199                 catch ( final IOException e )
200                 {
201                     // Suppressed due to an exception already thrown in the try block.
202                 }
203             }
204         }
205 
206         return total;
207     }
208 
209     private long copy( OutputStream os, InputStream is, ProgressListener listener )
210         throws IOException
211     {
212         long total = 0L;
213 
214         ByteBuffer buffer = ByteBuffer.allocate( 1024 * 32 );
215         byte[] array = buffer.array();
216 
217         while ( true )
218         {
219             int bytes = is.read( array );
220             if ( bytes < 0 )
221             {
222                 break;
223             }
224 
225             os.write( array, 0, bytes );
226 
227             total += bytes;
228 
229             if ( listener != null && bytes > 0 )
230             {
231                 try
232                 {
233                     ( (Buffer) buffer ).rewind();
234                     ( (Buffer) buffer ).limit( bytes );
235                     listener.progressed( buffer );
236                 }
237                 catch ( Exception e )
238                 {
239                     // too bad
240                 }
241             }
242         }
243 
244         return total;
245     }
246 
247     public void move( File source, File target )
248         throws IOException
249     {
250         if ( !source.renameTo( target ) )
251         {
252             copy( source, target );
253 
254             target.setLastModified( source.lastModified() );
255 
256             source.delete();
257         }
258     }
259 
260 }