View Javadoc
1   package org.apache.maven.wagon.providers.file;
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.BufferedInputStream;
23  import java.io.BufferedOutputStream;
24  import java.io.File;
25  import java.io.FileInputStream;
26  import java.io.FileNotFoundException;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.io.OutputStream;
30  import java.util.ArrayList;
31  import java.util.List;
32  
33  import org.apache.maven.wagon.ConnectionException;
34  import org.apache.maven.wagon.InputData;
35  import org.apache.maven.wagon.LazyFileOutputStream;
36  import org.apache.maven.wagon.OutputData;
37  import org.apache.maven.wagon.ResourceDoesNotExistException;
38  import org.apache.maven.wagon.StreamWagon;
39  import org.apache.maven.wagon.TransferFailedException;
40  import org.apache.maven.wagon.authorization.AuthorizationException;
41  import org.apache.maven.wagon.resource.Resource;
42  import org.codehaus.plexus.util.FileUtils;
43  
44  /**
45   * Wagon Provider for Local File System
46   *
47   * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
48   *
49   * @plexus.component role="org.apache.maven.wagon.Wagon" role-hint="file" instantiation-strategy="per-lookup"
50   */
51  public class FileWagon
52      extends StreamWagon
53  {
54      public void fillInputData( InputData inputData )
55          throws TransferFailedException, ResourceDoesNotExistException
56      {
57          if ( getRepository().getBasedir() == null )
58          {
59              throw new TransferFailedException( "Unable to operate with a null basedir." );
60          }
61  
62          Resource resource = inputData.getResource();
63  
64          File file = new File( getRepository().getBasedir(), resource.getName() );
65  
66          if ( !file.exists() )
67          {
68              throw new ResourceDoesNotExistException( "File: " + file + " does not exist" );
69          }
70  
71          try
72          {
73              InputStream in = new BufferedInputStream( new FileInputStream( file ) );
74  
75              inputData.setInputStream( in );
76  
77              resource.setContentLength( file.length() );
78  
79              resource.setLastModified( file.lastModified() );
80          }
81          catch ( FileNotFoundException e )
82          {
83              throw new TransferFailedException( "Could not read from file: " + file.getAbsolutePath(), e );
84          }
85      }
86  
87      public void fillOutputData( OutputData outputData )
88          throws TransferFailedException
89      {
90          if ( getRepository().getBasedir() == null )
91          {
92              throw new TransferFailedException( "Unable to operate with a null basedir." );
93          }
94  
95          Resource resource = outputData.getResource();
96  
97          File file = new File( getRepository().getBasedir(), resource.getName() );
98  
99          createParentDirectories( file );
100 
101         OutputStream outputStream = new BufferedOutputStream( new LazyFileOutputStream( file ) );
102 
103         outputData.setOutputStream( outputStream );
104     }
105 
106     protected void openConnectionInternal()
107         throws ConnectionException
108     {
109         if ( getRepository() == null )
110         {
111             throw new ConnectionException( "Unable to operate with a null repository." );
112         }
113 
114         if ( getRepository().getBasedir() == null )
115         {
116             // This condition is possible when using wagon-file under integration testing conditions.
117             fireSessionDebug( "Using a null basedir." );
118             return;
119         }
120 
121         // Check the File repository exists
122         File basedir = new File( getRepository().getBasedir() );
123         if ( !basedir.exists() )
124         {
125             if ( !basedir.mkdirs() )
126             {
127                 throw new ConnectionException( "Repository path " + basedir + " does not exist,"
128                                                + " and cannot be created." );
129             }
130         }
131 
132         if ( !basedir.canRead() )
133         {
134             throw new ConnectionException( "Repository path " + basedir + " cannot be read" );
135         }
136     }
137 
138     public void closeConnection()
139     {
140     }
141 
142     public boolean supportsDirectoryCopy()
143     {
144         // TODO: should we test for null basedir here?
145         return true;
146     }
147 
148     public void putDirectory( File sourceDirectory, String destinationDirectory )
149         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
150     {
151         if ( getRepository().getBasedir() == null )
152         {
153             throw new TransferFailedException( "Unable to putDirectory() with a null basedir." );
154         }
155 
156         File path = resolveDestinationPath( destinationDirectory );
157 
158         try
159         {
160             /*
161              * Done to address issue found in HP-UX with regards to "." directory references. Details found in ..
162              * WAGON-30 - wagon-file failed when used by maven-site-plugin WAGON-33 - FileWagon#putDirectory() fails in
163              * HP-UX if destinationDirectory is "."
164              * http://www.nabble.com/With-maven-2.0.2-site%3Adeploy-doesn%27t-work-t934716.html for details. Using
165              * path.getCanonicalFile() ensures that the path is fully resolved before an attempt to create it. TODO:
166              * consider moving this to FileUtils.mkdirs()
167              */
168             File realFile = path.getCanonicalFile();
169             realFile.mkdirs();
170         }
171         catch ( IOException e )
172         {
173             // Fall back to standard way if getCanonicalFile() fails.
174             path.mkdirs();
175         }
176 
177         if ( !path.exists() || !path.isDirectory() )
178         {
179             String emsg = "Could not make directory '" + path.getAbsolutePath() + "'.";
180 
181             // Add assistive message in case of failure.
182             File basedir = new File( getRepository().getBasedir() );
183             if ( !basedir.canWrite() )
184             {
185                 emsg += "  The base directory " + basedir + " is read-only.";
186             }
187 
188             throw new TransferFailedException( emsg );
189         }
190 
191         try
192         {
193             FileUtils.copyDirectoryStructure( sourceDirectory, path );
194         }
195         catch ( IOException e )
196         {
197             throw new TransferFailedException( "Error copying directory structure", e );
198         }
199     }
200 
201     private File resolveDestinationPath( String destinationPath )
202     {
203         String basedir = getRepository().getBasedir();
204 
205         destinationPath = destinationPath.replace( "\\", "/" );
206 
207         File path;
208 
209         if ( destinationPath.equals( "." ) )
210         {
211             path = new File( basedir );
212         }
213         else
214         {
215             path = new File( basedir, destinationPath );
216         }
217 
218         return path;
219     }
220 
221     public List<String> getFileList( String destinationDirectory )
222         throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException
223     {
224         if ( getRepository().getBasedir() == null )
225         {
226             throw new TransferFailedException( "Unable to getFileList() with a null basedir." );
227         }
228 
229         File path = resolveDestinationPath( destinationDirectory );
230 
231         if ( !path.exists() )
232         {
233             throw new ResourceDoesNotExistException( "Directory does not exist: " + destinationDirectory );
234         }
235 
236         if ( !path.isDirectory() )
237         {
238             throw new ResourceDoesNotExistException( "Path is not a directory: " + destinationDirectory );
239         }
240 
241         File[] files = path.listFiles();
242 
243         List<String> list = new ArrayList<String>( files.length );
244         for ( File file : files )
245         {
246             String name = file.getName();
247             if ( file.isDirectory() && !name.endsWith( "/" ) )
248             {
249                 name += "/";
250             }
251             list.add( name );
252         }
253         return list;
254     }
255 
256     public boolean resourceExists( String resourceName )
257         throws TransferFailedException, AuthorizationException
258     {
259         if ( getRepository().getBasedir() == null )
260         {
261             throw new TransferFailedException( "Unable to getFileList() with a null basedir." );
262         }
263 
264         File file = resolveDestinationPath( resourceName );
265 
266         if ( resourceName.endsWith( "/" ) )
267         {
268             return file.isDirectory();
269         }
270 
271         return file.exists();
272     }
273 }