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.commons.lang.StringUtils; 034import org.apache.maven.wagon.ConnectionException; 035import org.apache.maven.wagon.InputData; 036import org.apache.maven.wagon.LazyFileOutputStream; 037import org.apache.maven.wagon.OutputData; 038import org.apache.maven.wagon.ResourceDoesNotExistException; 039import org.apache.maven.wagon.StreamWagon; 040import org.apache.maven.wagon.TransferFailedException; 041import org.apache.maven.wagon.authorization.AuthorizationException; 042import org.apache.maven.wagon.resource.Resource; 043import org.codehaus.plexus.util.FileUtils; 044 045/** 046 * Wagon Provider for Local File System 047 * 048 * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a> 049 * 050 * @plexus.component role="org.apache.maven.wagon.Wagon" role-hint="file" instantiation-strategy="per-lookup" 051 */ 052public class FileWagon 053 extends StreamWagon 054{ 055 public void fillInputData( InputData inputData ) 056 throws TransferFailedException, ResourceDoesNotExistException 057 { 058 if ( getRepository().getBasedir() == null ) 059 { 060 throw new TransferFailedException( "Unable to operate with a null basedir." ); 061 } 062 063 Resource resource = inputData.getResource(); 064 065 File file = new File( getRepository().getBasedir(), resource.getName() ); 066 067 if ( !file.exists() ) 068 { 069 throw new ResourceDoesNotExistException( "File: " + file + " does not exist" ); 070 } 071 072 try 073 { 074 InputStream in = new BufferedInputStream( new FileInputStream( file ) ); 075 076 inputData.setInputStream( in ); 077 078 resource.setContentLength( file.length() ); 079 080 resource.setLastModified( file.lastModified() ); 081 } 082 catch ( FileNotFoundException e ) 083 { 084 throw new TransferFailedException( "Could not read from file: " + file.getAbsolutePath(), e ); 085 } 086 } 087 088 public void fillOutputData( OutputData outputData ) 089 throws TransferFailedException 090 { 091 if ( getRepository().getBasedir() == null ) 092 { 093 throw new TransferFailedException( "Unable to operate with a null basedir." ); 094 } 095 096 Resource resource = outputData.getResource(); 097 098 File file = new File( getRepository().getBasedir(), resource.getName() ); 099 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 ( File file : files ) 246 { 247 String name = file.getName(); 248 if ( file.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}