/* | |
* 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 filname. | |
* @param fullFilename full filename | |
* @return the name of the file or folder | |
*/ | |
private String extractFileName(String fullFilename) { | |
int index = fullFilename.lastIndexOf(File.separator); | |
return fullFilename.substring(index + 1, fullFilename.length()); | |
} | |
/** | |
* get the path form 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.replace(" ", "%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; | |
} | |
} | |
/** | |
* 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.replace("\\", "\\\\"); | |
} 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; | |
} | |
} |