blob: c6958b297d8e5fe361def50f93bf4495537ca62d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.obrplugin;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;
import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.UnsupportedProtocolException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.WagonException;
import org.apache.maven.wagon.authentication.AuthenticationException;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.repository.Repository;
/**
* this class is used to manage all connections by wagon.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class RemoteFileManager
{
/**
* save the connection.
*/
private Wagon m_wagon;
/**
* the wagon manager.
*/
private WagonManager m_wagonManager;
/**
* the project settings.
*/
private Settings m_settings;
/**
* logger instance.
*/
private Log m_log;
/**
* initialize main information.
* @param wm WagonManager provides by maven
* @param settings settings of the current project provides by maven
* @param log logger
*/
public RemoteFileManager( WagonManager wm, Settings settings, Log log )
{
m_wagonManager = wm;
m_settings = settings;
m_log = log;
m_wagon = null;
}
/**
* disconnect the current object.
*/
public void disconnect()
{
try
{
if ( m_wagon != null )
{
m_wagon.disconnect();
}
}
catch ( ConnectionException e )
{
m_log.error( "Error disconnecting Wagon", e );
}
}
/**
* connect the current object to repository given in constructor.
* @param id repository id
* @param url repository url
* @throws MojoExecutionException
*/
public void connect( String id, String url ) throws MojoExecutionException
{
Repository repository = new Repository( id, url );
try
{
m_wagon = m_wagonManager.getWagon( repository );
}
catch ( UnsupportedProtocolException e )
{
throw new MojoExecutionException( "Unsupported protocol: '" + repository.getProtocol() + "'", e );
}
catch ( WagonException e )
{
throw new MojoExecutionException( "Unable to configure Wagon: '" + repository.getProtocol() + "'", e );
}
try
{
ProxyInfo proxyInfo = getProxyInfo( m_settings );
if ( proxyInfo != null )
{
m_wagon.connect( repository, m_wagonManager.getAuthenticationInfo( id ), proxyInfo );
}
else
{
m_wagon.connect( repository, m_wagonManager.getAuthenticationInfo( id ) );
}
}
catch ( ConnectionException e )
{
throw new MojoExecutionException( "Connection failed", e );
}
catch ( AuthenticationException e )
{
throw new MojoExecutionException( "Authentication failed", e );
}
}
/**
* get a file from the current repository connected.
* @param url url to the targeted file
* @param suffix suggested file suffix
* @return get a file descriptor on the required resource
* @throws MojoExecutionException
*/
public File get( String url, String suffix ) throws MojoExecutionException
{
if ( m_wagon == null )
{
m_log.error( "must be connected first!" );
return null;
}
File file = null;
try
{
file = File.createTempFile( String.valueOf( System.currentTimeMillis() ), suffix );
}
catch ( IOException e )
{
throw new MojoExecutionException( "I/O problem", e );
}
try
{
m_wagon.get( url, file );
}
catch ( TransferFailedException e )
{
file.delete(); // cleanup on failure
throw new MojoExecutionException( "Transfer failed", e );
}
catch ( AuthorizationException e )
{
file.delete(); // cleanup on failure
throw new MojoExecutionException( "Authorization failed", e );
}
catch ( ResourceDoesNotExistException e )
{
file.delete(); // return non-existent file
}
return file;
}
/**
* put a file on the current repository connected.
* @param file file to upload
* @param url url to copy file
* @throws MojoExecutionException
*/
public void put( File file, String url ) throws MojoExecutionException
{
if ( m_wagon == null )
{
m_log.error( "must be connected first!" );
return;
}
try
{
m_wagon.put( file, url );
}
catch ( TransferFailedException e )
{
throw new MojoExecutionException( "Transfer failed", e );
}
catch ( AuthorizationException e )
{
throw new MojoExecutionException( "Authorization failed", e );
}
catch ( ResourceDoesNotExistException e )
{
throw new MojoExecutionException( "Resource does not exist:" + file, e );
}
}
/**
* Convenience method to map a Proxy object from the user system settings to a ProxyInfo object.
* @param settings project settings given by maven
* @return a proxyInfo object instancied or null if no active proxy is define in the settings.xml
*/
public static ProxyInfo getProxyInfo( Settings settings )
{
ProxyInfo proxyInfo = null;
if ( settings != null && settings.getActiveProxy() != null )
{
Proxy settingsProxy = settings.getActiveProxy();
proxyInfo = new ProxyInfo();
proxyInfo.setHost( settingsProxy.getHost() );
proxyInfo.setType( settingsProxy.getProtocol() );
proxyInfo.setPort( settingsProxy.getPort() );
proxyInfo.setNonProxyHosts( settingsProxy.getNonProxyHosts() );
proxyInfo.setUserName( settingsProxy.getUsername() );
proxyInfo.setPassword( settingsProxy.getPassword() );
}
return proxyInfo;
}
public void lockFile( String fileName, boolean ignoreLock ) throws MojoExecutionException
{
if ( !ignoreLock )
{
int countError = 0;
while ( isLockedFile( fileName ) && countError < 2 )
{
countError++;
m_log.warn( "File is currently locked, retry in 10s" );
try
{
Thread.sleep( 10000 );
}
catch ( InterruptedException e )
{
m_log.warn( "Sleep interrupted" );
}
}
if ( countError == 2 )
{
m_log.error( "File " + fileName + " is locked. Use -DignoreLock to force uploading" );
throw new MojoExecutionException( "Remote file locked" );
}
}
File file = null;
try
{
// create a non-empty file used to lock the remote file
file = File.createTempFile( String.valueOf( System.currentTimeMillis() ), ".lock" );
Writer writer = new BufferedWriter( new FileWriter( file ) );
writer.write( "LOCKED" );
writer.close();
put( file, fileName + ".lock" );
}
catch ( IOException e )
{
throw new MojoExecutionException( "I/O problem", e );
}
finally
{
if ( null != file )
{
file.delete();
}
}
}
public void unlockFile( String fileName ) throws MojoExecutionException
{
File file = null;
try
{
// clear the contents of the file used to lock the remote file
file = File.createTempFile( String.valueOf( System.currentTimeMillis() ), ".lock" );
Writer writer = new BufferedWriter( new FileWriter( file ) );
writer.write( " " ); // write 1 byte to force wagon upload
writer.close();
put( file, fileName + ".lock" );
}
catch ( IOException e )
{
throw new MojoExecutionException( "I/O problem", e );
}
finally
{
if ( null != file )
{
file.delete();
}
}
}
/**
* this method indicates if the targeted file is locked or not.
* @param fileName name targeted
* @return true if the required file is locked, else false
* @throws MojoExecutionException
*/
public boolean isLockedFile( String fileName ) throws MojoExecutionException
{
File file = null;
try
{
file = get( fileName + ".lock", ".lock" );
// file is locked with contents "LOCKED"
if ( null != file && file.length() <= 2 )
{
return false;
}
}
finally
{
if ( null != file )
{
file.delete();
}
}
return true;
}
public String toString()
{
return m_wagon.getRepository().getUrl();
}
}