blob: bd9e693eb5c79c49654e62a0fcf5b5152c266a19 [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.obr.plugin;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.channels.FileChannel;
/**
* this class provide some functions to simplify file manipulation.
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class PathFile
{
/**
* full filename.
*/
private String m_fullFilename;
/**
* store only the filename of the file.
*/
private String m_fileName;
/**
* store only the path of this file.
*/
private String m_pathFile;
/**
* store the base Directory in case of relative path.
*/
private String m_baseDir;
/**
* store the protocol used (ie:file, http...).
*/
private String m_protocol;
/**
* if the path is relative or absolute.
*/
private boolean m_relative;
/**
* if this file is a folder.
*/
private boolean m_folder;
/**
* if the file exist or not.
*/
private boolean m_exist;
/**
* if this file is a file (not a folder).
*/
private boolean m_file;
/**
* if this filename is valid or incomplete.
*/
private boolean m_valid;
/**
* build all the attribute information.
* @param filename path to the file
*/
public PathFile( String filename )
{
this.m_fullFilename = filename;
if ( filename == null )
{
this.m_valid = false;
return;
}
this.m_valid = true;
m_protocol = extractProtocol( filename );
m_pathFile = extractPathFile( filename );
if ( m_pathFile.startsWith( "//" ) )
{
// avoid problems on Unix like system
m_pathFile = m_pathFile.substring( 1 );
}
m_fileName = extractFileName( filename );
m_relative = extractRelative();
if ( !m_relative && ( getProtocol().compareTo( "file" ) == 0 || getProtocol().compareTo( "" ) == 0 ) )
{
File f = new File( getOnlyAbsoluteFilename() );
m_file = f.isFile();
m_folder = f.isDirectory();
m_exist = f.exists();
if ( m_folder )
{
m_pathFile = m_pathFile + m_fileName + File.separator;
m_fileName = "";
}
}
if ( m_exist )
{
m_protocol = "file";
}
else
{
if ( m_fileName.compareTo( "" ) == 0 )
{
m_folder = true;
m_file = false;
}
else
{
m_folder = false;
m_file = true;
}
}
// add the '/' before the complete path if it is absolute path
if ( !this.isRelative() && !m_pathFile.startsWith( "/" ) )
{
m_pathFile = "/".concat( m_pathFile );
}
}
/**
* get if the filename is relative or absolute.
* @return true if the path is relative, else false
*/
private boolean extractRelative()
{
if ( m_pathFile.startsWith( "." + File.separator, 1 ) || m_pathFile.startsWith( ".." + File.separator, 1 ) )
{
m_pathFile = m_pathFile.substring( 1 );
m_valid = false;
return true;
}
return false;
}
/**
* get only the name from the filename.
* @param fullFilename full filename
* @return the name of the file or folder
*/
private String extractFileName( String fullFilename )
{
int index = fullFilename.lastIndexOf( '/' ); // Given path
return fullFilename.substring( index + 1, fullFilename.length() );
}
/**
* get the path from the filename.
* @param fullFilename full filename
* @return the path of the file
*/
private String extractPathFile( String fullFilename )
{
String substring;
if ( extractFileName( fullFilename ).compareTo( "" ) == 0 )
{
// it is a folder
substring = fullFilename;
}
else
{
substring = fullFilename.substring( 0, fullFilename.indexOf( extractFileName( fullFilename ) ) );
}
if ( getProtocol().compareTo( "" ) != 0 )
{
substring = substring.substring( 5 );
}
return substring;
}
/**
* determine which protocol is used.
* @param filename the full fileneme
* @return "file" or "http" or ""
*/
private String extractProtocol( String filename )
{
if ( filename.startsWith( "file:" ) )
{
return "file";
}
if ( filename.startsWith( "http:" ) )
{
return "http";
}
return "";
}
/**
* set the base directory.
* @param baseDir new value for the base directory
*/
public void setBaseDir( String baseDir )
{
this.m_baseDir = baseDir;
if ( isRelative() && this.m_fullFilename != null )
{
this.m_valid = true;
if ( getProtocol().compareTo( "file" ) == 0 || getProtocol().compareTo( "" ) == 0 )
{
File f = new File( getOnlyAbsoluteFilename() );
m_file = f.isFile();
m_folder = f.isDirectory();
m_exist = f.exists();
}
if ( m_exist )
{
m_protocol = "file";
}
}
}
/**
* get the base directory.
* @return base directory
*/
public String getBaseDir()
{
return this.m_baseDir;
}
public boolean isValid()
{
return m_valid;
}
public boolean isRelative()
{
return m_relative;
}
public boolean isExists()
{
return m_exist;
}
public boolean isFile()
{
return m_file;
}
public boolean isFolder()
{
return m_folder;
}
/**
* get a File which points on the same file.
* @return a File object
*/
public File getFile()
{
if ( !this.isValid() )
{
return null;
}
String path = PathFile.uniformSeparator( this.getOnlyAbsoluteFilename() );
if ( File.separatorChar == '\\' )
{
path = path.replace( '\\', '/' );
}
File f = new File( path );
return f;
}
/**
* get an URI which points on the same file.
* @return an URI object
*/
public URI getUri()
{
if ( !this.isValid() )
{
return null;
}
String path = PathFile.uniformSeparator( getAbsoluteFilename() );
if ( File.separatorChar == '\\' )
{
path = path.replace( '\\', '/' );
}
path = path.replaceAll( " ", "%20" );
URI uri = null;
try
{
uri = new URI( path );
}
catch ( URISyntaxException e )
{
System.err.println( "Malformed URI: " + path );
System.err.println( e.getMessage() );
return null;
}
return uri;
}
/**
* get protocol + relative path of this file.
* @return the relative path or null if it is not valid
*/
public String getRelativePath()
{
if ( !this.isValid() )
{
return null;
}
return getProtocol() + ":/" + getOnlyRelativePath();
}
/**
* get only (without protocol) relative path of this file.
* @return the relative path or null if it is not valid
*/
public String getOnlyRelativePath()
{
if ( !this.isValid() )
{
return null;
}
if ( this.isRelative() )
{
return m_pathFile;
}
else
{
if ( m_baseDir != null )
{
// System.err.println(m_pathFile);
// System.err.println(m_baseDir);
if ( m_pathFile.startsWith( m_baseDir ) )
{
/*
* String ch1 = m_pathFile; String ch2 = m_baseDir; System.err.println(ch1); System.err.println(ch2); System.err.println("."+File.separator+ch1.substring(ch2.length()));
*/
return "." + File.separator + m_pathFile.substring( m_baseDir.length() );
}
}
return m_pathFile;
}
}
/**
* calcul absolute path from relative path.
* @param baseDir base directory
* @param path path to convert
* @return the absolute path or null
*/
private String calculAbsolutePath( String baseDir, String path )
{
if ( path.startsWith( ".." + File.separatorChar ) )
{
String base = baseDir;
int lastIndex;
lastIndex = base.lastIndexOf( File.separator );
if ( lastIndex == base.length() )
{
base = base.substring( 0, base.length() - 1 );
lastIndex = base.lastIndexOf( File.separator );
}
if ( lastIndex < base.length() )
{
return calculAbsolutePath( base.substring( 0, lastIndex + 1 ), path.substring( 3 ) );
}
else
{
return null;
}
}
else if ( path.startsWith( "." + File.separatorChar ) )
{
String res;
if ( File.separatorChar == '\\' )
{
res = path.replaceFirst( ".", baseDir.replace( '\\', '/' ) );
}
else
{
res = path.replaceFirst( ".", baseDir );
}
return PathFile.uniformSeparator( res );
}
else
{
return PathFile.uniformSeparator( baseDir + path );
}
}
/**
* get only (without protocol) absolute path (without filename).
* @return absolute path
*/
public String getOnlyAbsolutePath()
{
if ( !this.isValid() )
{
return null;
}
if ( isRelative() )
{
return calculAbsolutePath( m_baseDir, m_pathFile );
}
else
{
return m_pathFile;
}
}
/**
* get protocol + absolute path (without filename).
* @return absolute path
*/
public String getAbsolutePath()
{
if ( isRelative() )
{
return getProtocol() + ":/" + calculAbsolutePath( m_baseDir, m_pathFile );
}
else
{
if ( getProtocol().compareTo( "" ) == 0 || m_pathFile == null )
{
return m_pathFile;
}
else
{
return getProtocol() + ":" + m_pathFile;
}
}
}
/**
* get only (without protocol) absolute path + filename.
* @return absolute filename
*/
public String getOnlyAbsoluteFilename()
{
if ( getOnlyAbsolutePath() != null && getFilename() != null )
{
return getOnlyAbsolutePath() + getFilename();
}
else
{
return null;
}
}
/**
* get protocol + absolute path + filename.
* @return absolute filenama
*/
public String getAbsoluteFilename()
{
if ( getAbsolutePath() != null && getFilename() != null )
{
return getAbsolutePath() + getFilename();
}
else
{
return null;
}
}
/**
* get only (without protocol) relative path + filename.
* @return relative filename
*/
public String getOnlyRelativeFilename()
{
if ( !this.isValid() )
{
return "";
}
return getOnlyRelativePath() + getFilename();
}
/**
* get protocol + relative path + filename.
* @return relative filename
*/
public String getRelativeFilename()
{
if ( !this.isValid() )
{
return "";
}
if ( this.isRelative() )
{
return getRelativePath() + getFilename();
}
else
{
return getAbsoluteFilename();
}
}
public String getFilename()
{
return m_fileName;
}
public String getProtocol()
{
return m_protocol;
}
/**
* create all the directories not also present in the current path.
* @return true if all directories was created, else false
*/
public boolean createPath()
{
File path = new File( this.getOnlyAbsolutePath() );
if ( path.exists() )
{
return true;
}
return path.mkdirs();
}
/**
* create all the directories not also present in the current path and the file.
* @return true it was created, else false
*/
public boolean createFile()
{
File path = new File( this.getOnlyAbsolutePath() );
if ( !path.exists() )
{
if ( !this.createPath() )
{
return false;
}
}
path = new File( this.getOnlyAbsoluteFilename() );
try
{
return path.createNewFile();
}
catch ( IOException e )
{
return false;
}
}
/**
* delete the current file.
* @return true if it was deleted, else false
*/
public boolean delete()
{
File path = new File( this.getAbsoluteFilename() );
if ( path.exists() )
{
return path.delete();
}
else
{
return true;
}
}
private static final String REGEXP_BACKSLASH = "\\\\";
/**
* replace all '\' by '\\' in the given string.
* @param path string where replace the search pattern
* @return string replaced
*/
public static String doubleSeparator( String path )
{
// double the '\' in the path
if ( path != null && File.separatorChar == '\\' )
{
return path.replaceAll( REGEXP_BACKSLASH, REGEXP_BACKSLASH + REGEXP_BACKSLASH );
}
else
{
return null;
}
}
/**
* file separator('\' or '/') by the one of the current system.
* @param path string where replace the search pattern
* @return string replaced
*/
public static String uniformSeparator( String path )
{
if ( File.separatorChar == '\\' )
{
if ( path.startsWith( "/" ) )
{
return path.substring( 1 ).replace( '/', File.separatorChar );
}
else
{
return path.replace( '/', File.separatorChar );
}
}
else
{
return path.replace( '\\', File.separatorChar );
}
}
/**
* copy file from src to dest.
* @param src source file
* @param dest destination file
* @return true if the file was correctly copied, else false
*/
public static boolean copyFile( PathFile src, PathFile dest )
{
FileChannel in = null;
FileChannel out = null;
if ( !src.isExists() )
{
System.err.println( "src file must exist: " + src.getAbsoluteFilename() );
return false;
}
if ( !dest.isExists() )
{
dest.createFile();
}
try
{
in = new FileInputStream( src.getOnlyAbsoluteFilename() ).getChannel();
out = new FileOutputStream( dest.getOnlyAbsoluteFilename() ).getChannel();
in.transferTo( 0, in.size(), out );
}
catch ( Exception e )
{
e.printStackTrace();
}
finally
{
if ( in != null )
{
try
{
in.close();
}
catch ( IOException e )
{
return false;
}
}
if ( out != null )
{
try
{
out.close();
}
catch ( IOException e )
{
return false;
}
}
}
return true;
}
}