001package org.apache.maven.wagon.providers.file; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.BufferedInputStream; 023import java.io.BufferedOutputStream; 024import java.io.File; 025import java.io.FileInputStream; 026import java.io.FileNotFoundException; 027import java.io.IOException; 028import java.io.InputStream; 029import java.io.OutputStream; 030import java.util.ArrayList; 031import java.util.List; 032 033import org.apache.maven.wagon.ConnectionException; 034import org.apache.maven.wagon.InputData; 035import org.apache.maven.wagon.LazyFileOutputStream; 036import org.apache.maven.wagon.OutputData; 037import org.apache.maven.wagon.ResourceDoesNotExistException; 038import org.apache.maven.wagon.StreamWagon; 039import org.apache.maven.wagon.TransferFailedException; 040import org.apache.maven.wagon.authorization.AuthorizationException; 041import org.apache.maven.wagon.resource.Resource; 042import org.codehaus.plexus.util.FileUtils; 043 044/** 045 * Wagon Provider for Local File System 046 * 047 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a> 048 * 049 * @plexus.component role="org.apache.maven.wagon.Wagon" role-hint="file" instantiation-strategy="per-lookup" 050 */ 051public class FileWagon 052 extends StreamWagon 053{ 054 public void fillInputData( InputData inputData ) 055 throws TransferFailedException, ResourceDoesNotExistException 056 { 057 if ( getRepository().getBasedir() == null ) 058 { 059 throw new TransferFailedException( "Unable to operate with a null basedir." ); 060 } 061 062 Resource resource = inputData.getResource(); 063 064 File file = new File( getRepository().getBasedir(), resource.getName() ); 065 066 if ( !file.exists() ) 067 { 068 throw new ResourceDoesNotExistException( "File: " + file + " does not exist" ); 069 } 070 071 try 072 { 073 InputStream in = new BufferedInputStream( new FileInputStream( file ) ); 074 075 inputData.setInputStream( in ); 076 077 resource.setContentLength( file.length() ); 078 079 resource.setLastModified( file.lastModified() ); 080 } 081 catch ( FileNotFoundException e ) 082 { 083 throw new TransferFailedException( "Could not read from file: " + file.getAbsolutePath(), e ); 084 } 085 } 086 087 public void fillOutputData( OutputData outputData ) 088 throws TransferFailedException 089 { 090 if ( getRepository().getBasedir() == null ) 091 { 092 throw new TransferFailedException( "Unable to operate with a null basedir." ); 093 } 094 095 Resource resource = outputData.getResource(); 096 097 File file = new File( getRepository().getBasedir(), resource.getName() ); 098 099 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}