📄 cmsfileutil.java
字号:
/**
* Normalizes a file path that might contain <code>'../'</code> or <code>'./'</code> or <code>'//'</code>
* elements to a normal absolute path, the path separator char used is {@link File#separatorChar}.<p>
*
* @param path the path to normalize
*
* @return the normalized path
*
* @see #normalizePath(String, char)
*/
public static String normalizePath(String path) {
return normalizePath(path, File.separatorChar);
}
/**
* Normalizes a file path that might contain <code>'../'</code> or <code>'./'</code> or <code>'//'</code>
* elements to a normal absolute path.<p>
*
* Can also handle Windows like path information containing a drive letter,
* like <code>C:\path\..\</code>.<p>
*
* @param path the path to normalize
* @param separatorChar the file separator char to use, for example {@link File#separatorChar}
*
* @return the normalized path
*/
public static String normalizePath(String path, char separatorChar) {
if (CmsStringUtil.isNotEmpty(path)) {
// ensure all File separators are '/'
path = path.replace('\\', '/');
String drive = null;
if ((path.length() > 1) && (path.charAt(1) == ':')) {
// windows path like C:\home\
drive = path.substring(0, 2);
path = path.substring(2);
}
if (path.charAt(0) == '/') {
// trick to resolve all ../ inside a path
path = '.' + path;
}
// resolve all '../' or './' elements in the path
path = CmsLinkManager.getAbsoluteUri(path, "/");
// re-append drive if required
if (drive != null) {
path = drive.concat(path);
}
// still some '//' elements might persist
path = CmsStringUtil.substitute(path, "//", "/");
// switch '/' back to OS dependend File separator if required
if (separatorChar != '/') {
path = path.replace('/', separatorChar);
}
}
return path;
}
/**
* Returns the normalized file path created from the given URL.<p>
*
* The path part {@link URL#getPath()} is used, unescaped and
* normalized using {@link #normalizePath(String, char)} using {@link File#separatorChar}.<p>
*
* @param url the URL to extract the path information from
*
* @return the normalized file path created from the given URL using {@link File#separatorChar}
*
* @see #normalizePath(URL, char)
*/
public static String normalizePath(URL url) {
return normalizePath(url, File.separatorChar);
}
/**
* Returns the normalized file path created from the given URL.<p>
*
* The path part {@link URL#getPath()} is used, unescaped and
* normalized using {@link #normalizePath(String, char)}.<p>
*
* @param url the URL to extract the path information from
* @param separatorChar the file separator char to use, for example {@link File#separatorChar}
*
* @return the normalized file path created from the given URL
*/
public static String normalizePath(URL url, char separatorChar) {
// get the path part from the URL
String path = new File(url.getPath()).getAbsolutePath();
// trick to get the OS default encoding, taken from the official Java i18n FAQ
String systemEncoding = (new OutputStreamWriter(new ByteArrayOutputStream())).getEncoding();
// decode url in order to remove spaces and escaped chars from path
return CmsFileUtil.normalizePath(CmsEncoder.decode(path, systemEncoding), separatorChar);
}
/**
* Deletes a directory in the file system and all subfolders of that directory.<p>
*
* @param directory the directory to delete
*/
public static void purgeDirectory(File directory) {
if (directory.canRead() && directory.isDirectory()) {
File[] files = directory.listFiles();
for (int i = 0; i < files.length; i++) {
File f = files[i];
if (f.isDirectory()) {
purgeDirectory(f);
}
if (f.canWrite()) {
f.delete();
}
}
directory.delete();
}
}
/**
* Reads a file from the RFS and returns the file content.<p>
*
* @param file the file to read
* @return the read file content
*
* @throws IOException in case of file access errors
*/
public static byte[] readFile(File file) throws IOException {
// create input and output stream
FileInputStream in = new FileInputStream(file);
// read the content
return readFully(in, (int)file.length());
}
/**
* Reads a file with the given name from the class loader and returns the file content.<p>
*
* @param filename the file to read
* @return the read file content
*
* @throws IOException in case of file access errors
*/
public static byte[] readFile(String filename) throws IOException {
// create input and output stream
InputStream in = CmsFileUtil.class.getClassLoader().getResourceAsStream(filename);
if (in == null) {
throw new FileNotFoundException(filename);
}
return readFully(in);
}
/**
* Reads a file from the class loader and converts it to a String with the specified encoding.<p>
*
* @param filename the file to read
* @param encoding the encoding to use when converting the file content to a String
* @return the read file convered to a String
* @throws IOException in case of file access errors
*/
public static String readFile(String filename, String encoding) throws IOException {
return new String(readFile(filename), encoding);
}
/**
* Reads all bytes from the given input stream and returns the result in an array.<p>
*
* @param in the input stream to read the bytes from
* @return the byte content of the input stream
*
* @throws IOException in case of errors in the underlying java.io methods used
*/
public static byte[] readFully(InputStream in) throws IOException {
if (in instanceof ByteArrayInputStream) {
// content can be read in one pass
return readFully(in, in.available());
}
// copy buffer
int xferSize = in.available();
byte[] xfer = new byte[xferSize == 0 ? 2048 : xferSize];
// output buffer
ByteArrayOutputStream out = new ByteArrayOutputStream(xfer.length);
// transfer data from input to output in xfer-sized chunks.
for (int bytesRead = in.read(xfer, 0, xfer.length); bytesRead >= 0; bytesRead = in.read(xfer, 0, xfer.length)) {
if (bytesRead > 0) {
out.write(xfer, 0, bytesRead);
}
}
in.close();
out.close();
return out.toByteArray();
}
/**
* Reads the specified number of bytes from the given input stream and returns the result in an array.<p>
*
* @param in the input stream to read the bytes from
* @param size the number of bytes to read
*
* @return the byte content read from the input stream
*
* @throws IOException in case of errors in the underlying java.io methods used
*/
public static byte[] readFully(InputStream in, int size) throws IOException {
// create the byte array to hold the data
byte[] bytes = new byte[size];
// read in the bytes
int offset = 0;
int numRead = 0;
while ((offset < bytes.length) && ((numRead = in.read(bytes, offset, bytes.length - offset)) >= 0)) {
offset += numRead;
}
// close the input stream and return bytes
in.close();
// ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not read requested " + size + " bytes from input stream");
}
return bytes;
}
/**
* Removes all resource names in the given List that are "redundant" because the parent folder name
* is also contained in the List.<p>
*
* The content of the input list is not modified.<p>
*
* @param resourcenames a list of VFS pathnames to check for redundencies (Strings)
*
* @return a the given list with all redundancies removed
*
* @see #removeRedundantResources(List)
*/
public static List removeRedundancies(List resourcenames) {
if ((resourcenames == null) || (resourcenames.isEmpty())) {
return new ArrayList();
}
if (resourcenames.size() == 1) {
// if there is only one resource name in the list, there can be no redundancies
return new ArrayList(resourcenames);
}
// check all resources names and see if a parent folder name is contained
List result = new ArrayList(resourcenames.size());
List base = new ArrayList(resourcenames);
Collections.sort(base);
Iterator i = base.iterator();
while (i.hasNext()) {
// check all resource names in the list
String resourcename = (String)i.next();
if (CmsStringUtil.isEmptyOrWhitespaceOnly(resourcename)) {
// skip empty strings
continue;
}
boolean valid = true;
for (int j = (result.size() - 1); j >= 0; j--) {
// check if this resource name is indirectly contained because a parent folder name is contained
String check = (String)result.get(j);
if (resourcename.startsWith(check)) {
valid = false;
break;
}
}
if (valid) {
// a parent folder name is not already contained in the result
result.add(resourcename);
}
}
return result;
}
/**
* Removes all resources in the given List that are "redundant" because the parent folder
* is also contained in the List.<p>
*
* The content of the input list is not modified.<p>
*
* @param resources a list of <code>{@link CmsResource}</code> objects to check for redundencies
*
* @return a the given list with all redundancies removed
*
* @see #removeRedundancies(List)
*/
public static List removeRedundantResources(List resources) {
if ((resources == null) || (resources.isEmpty())) {
return new ArrayList();
}
if (resources.size() == 1) {
// if there is only one resource in the list, there can be no redundancies
return new ArrayList(resources);
}
// check all resources and see if a parent folder name is contained
List result = new ArrayList(resources.size());
List base = new ArrayList(resources);
Collections.sort(base);
Iterator i = base.iterator();
while (i.hasNext()) {
// check all folders in the list
CmsResource resource = (CmsResource)i.next();
boolean valid = true;
for (int j = (result.size() - 1); j >= 0; j--) {
// check if this resource is indirectly contained because a parent folder is contained
String check = ((CmsResource)result.get(j)).getRootPath();
if (resource.getRootPath().startsWith(check)) {
valid = false;
break;
}
}
if (valid) {
// the parent folder is not already contained in the result
result.add(resource);
}
}
return result;
}
/**
* Searches for the OpenCms web application 'WEB-INF' folder during system startup, code or
* <code>null</code> if the 'WEB-INF' folder can not be found.<p>
*
* @param startFolder the folder where to start searching
*
* @return String the path of the 'WEB-INF' folder in the 'real' file system, or <code>null</code>
*/
public static String searchWebInfFolder(String startFolder) {
if (CmsStringUtil.isEmpty(startFolder)) {
return null;
}
File f = new File(startFolder);
if (!f.exists() || !f.isDirectory()) {
return null;
}
File configFile = new File(f, CmsSystemInfo.FOLDER_CONFIG + CmsConfigurationManager.DEFAULT_XML_FILE_NAME);
if (configFile.exists() && configFile.isFile()) {
return f.getAbsolutePath();
}
String webInfFolder = null;
File[] subFiles = f.listFiles();
for (int i = 0; i < subFiles.length; i++) {
if (subFiles[i].isDirectory()) {
webInfFolder = searchWebInfFolder(subFiles[i].getAbsolutePath());
if (webInfFolder != null) {
break;
}
}
}
return webInfFolder;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -