blob: 433b6d54badc1ae317cb2f720107747f938a0bc0 [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.sandbox.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 null;
}
}
/**
* 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;
}
}