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