org.apache.camel.component.file.remote.FtpUtils Maven / Gradle / Ivy
/*
* 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.camel.component.file.remote;
import java.io.File;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
import org.apache.camel.Component;
import org.apache.camel.util.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Various FTP utils.
*/
public final class FtpUtils {
private static final Logger LOG = LoggerFactory.getLogger(FtpUtils.class);
private FtpUtils() {
}
public static String extractDirNameFromAbsolutePath(String path) {
// default is unix so try with '/'
// otherwise force File.separator
if (path.endsWith("/") || path.endsWith("\\")) {
path = path.substring(0, path.length() - 1);
}
return FileUtil.stripPath(path);
}
/**
* Compacts a path by stacking it and reducing .., and uses OS specific file separators (eg
* {@link java.io.File#separator}).
*
* Important: This implementation works for the camel-ftp component for various FTP clients and FTP servers
* using different platforms and whatnot. This implementation has been working for many Camel releases, and is
* included here to restore patch compatibility with the Camel releases.
*/
public static String compactPath(String path) {
if (path == null) {
return null;
}
// only normalize if contains a path separator
if (path.indexOf(File.separator) == -1) {
return path;
}
// preserve ending slash if given in input path
boolean endsWithSlash = path.endsWith("/") || path.endsWith("\\");
// preserve starting slash if given in input path
boolean startsWithSlash = path.startsWith("/") || path.startsWith("\\");
Deque stack = new ArrayDeque<>();
String separatorRegex = File.separator;
if (FileUtil.isWindows()) {
separatorRegex = "\\\\";
}
String[] parts = path.split(separatorRegex);
for (String part : parts) {
if (part.equals("..") && !stack.isEmpty() && !"..".equals(stack.peek())) {
// only pop if there is a previous path, which is not a ".."
// path either
stack.pop();
} else if (part.equals(".") || part.isEmpty()) {
// do nothing because we don't want a path like foo/./bar or
// foo//bar
} else {
stack.push(part);
}
}
// build path based on stack
StringBuilder sb = new StringBuilder(256);
if (startsWithSlash) {
sb.append(File.separator);
}
// now we build back using FIFO so need to use descending
for (Iterator it = stack.descendingIterator(); it.hasNext();) {
sb.append(it.next());
if (it.hasNext()) {
sb.append(File.separator);
}
}
if (endsWithSlash && !stack.isEmpty()) {
sb.append(File.separator);
}
// there has been problems with double slashes,
// so avoid this by removing any 2nd slash
if (sb.length() >= 2) {
boolean firstSlash = sb.charAt(0) == '/' || sb.charAt(0) == '\\';
boolean secondSlash = sb.charAt(1) == '/' || sb.charAt(1) == '\\';
if (firstSlash && secondSlash) {
// remove 2nd clash
sb = sb.replace(1, 2, "");
}
}
return sb.toString();
}
/**
* Checks whether directory used in ftp/ftps/sftp endpoint URI is relative. Absolute path will be converted to
* relative path and a WARN will be printed.
*
* @see FTP/SFTP/FTPS Component
* @param ftpComponent
* @param configuration
*/
public static void ensureRelativeFtpDirectory(Component ftpComponent, RemoteFileConfiguration configuration) {
if (FileUtil.hasLeadingSeparator(configuration.getDirectoryName())) {
String relativePath = FileUtil.stripLeadingSeparator(configuration.getDirectoryName());
LOG.warn("{} doesn't support absolute paths, \"{}\" will be converted to \"{}\". "
+ "After Camel 2.16, absolute paths will be invalid.",
ftpComponent.getClass().getSimpleName(), configuration.getDirectoryName(), relativePath);
configuration.setDirectory(relativePath);
configuration.setDirectoryName(relativePath);
}
}
}