Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interlok 4121 fs helper improvements #1194

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 21 additions & 8 deletions interlok-core/src/main/java/com/adaptris/core/fs/FsConsumer.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,31 @@
* File system implementation of <code>AdaptrisMessageConsumer</code> based on the <code>com.adaptris.fs</code> package.
* </p>
* <p>
* The configured <code>Destination</code> may return a string in one of two formats
* The configured <code>Base Directory URL</code> may return a string in one of two formats
* </p>
* <ul>
* <li>If a <code>file</code> based url is used. e.g. file:///c:/path/to/my/directory or file:////path/to/my/directory then the
* patch is considered to be fully qualified</li>
* <li>If just a path is returned, then it is considered to be relative to the current working directory. e.g. if /opt/fred is used,
* and the adapter is installed to /opt/adapter, then the fully qualified name is /opt/adapter/opt/fred.</li>
* <li>
* Supports URLs with both the {@code file scheme} and without.
* </li>
* <li>
* If you define a directory without any leading slash or
* if it starts with a slash is deemed to be an <strong>absolute</strong> path.
* </li>
* <li>
* If "./" or "../" is used at the start of your definition then
* the path is deemed to be <strong>relative</strong>.</li>
* <li>
* This is true whether using the {@code file scheme} or not.
* </li>
* <li>
* With Windows systems the above is above is true, plus if you simply define the <strong>absolute</strong> path including the drive letter
* e.g. 'c://my/path' this is also valid.
* </li>
* <li>
* Both / and \ slashes are supported.
* </li>
* </ul>
* <p>
* On windows based platforms, you should always use a file based url.
* </p>
* <p>
* Once A file has been consumed from the file-system a standard set of metadata is added to the resulting message;
* <table>
* <th>Metadata Key</th>
Expand Down
50 changes: 10 additions & 40 deletions interlok-core/src/main/java/com/adaptris/core/fs/FsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
public abstract class FsHelper {

private static transient Logger log = LoggerFactory.getLogger(FsHelper.class);
private static final String WIN_DRIVE_REGEX = "^[a-zA-Z]{1}$"; //matches an alphabetic character exactly 1 time in the string.

/**
* Go straight to a {@link File} from a url style string.
Expand Down Expand Up @@ -88,32 +89,16 @@ public static File createFileReference(URL url, String charset) throws Unsupport
/**
* Creates a {@link URL} based on the passed destination.
* <p>
* If a {@code scheme} is present and is equal to {@code file} then the URL is deemed to be <strong>absolute</strong> and is used
* as is. If the {@code scheme} is null then the URL is considered a {@code "file"} URL, and <strong>relative</strong> to the
* current working directory.
* Supports URLs with both the {@code file scheme} and without. If you define a directory without any leading slash or
* if it starts with a slash is deemed to be an <strong>absolute</strong> path. If "./" or "../" is used at the start of your definition then
* the path is deemed to be <strong>relative</strong> . This is true when using the {@code file scheme} or not.
* </p>
* <p>
* Note that this method will not convert backslashes into forward slashes, so passing in a string like {@code ..\dir\} will fail
* with a URISyntaxException; use {@link #createUrlFromString(String, boolean)} to convert backslashes into forward slashes prior
* to processing.
* With Windows systems the above is above is true, plus if you simply define the <strong>absolute</strong> path including the drive letter
* e.g. 'c://my/path' this is also valid.
* </p>
*
* @param s the String to convert to a URL.
* @return a new URL
* @see #createUrlFromString(String, boolean)
* @deprecated use {@link #createUrlFromString(String, boolean)} since 3.0.3
*/
@Deprecated
public static URL createUrlFromString(String s) throws IOException, URISyntaxException {
return createUrlFromString(s, false);
}

/**
* Creates a {@link URL} based on the passed destination.
* <p>
* If a {@code scheme} is present and is equal to {@code file} then the URL is deemed to be <strong>absolute</strong> and is used
* as is. If the {@code scheme} is null then the URL is considered a {@code "file"} URL, and <strong>relative</strong> to the
* current working directory.
* Both / and \ slashes are supported.
* </p>
*
* @param s the string to convert to a URL.
Expand Down Expand Up @@ -143,10 +128,12 @@ public static URL createUrlFromString(String s, boolean backslashConvert) throws
// nb for some reason, configuredUri.toUrl() doesn't work...
// return configuredUri.toURL();
return new URL(configuredUri.toString());
}
}
else {
if (scheme == null) {
return new URL("file:///" + configuredUri.toString());
} else if (scheme.matches(WIN_DRIVE_REGEX)) {
return new URL("file:///" + configuredUri.toString());
}
else {
throw new IllegalArgumentException("Illegal URL [" + s + "]");
Expand Down Expand Up @@ -184,23 +171,6 @@ public static File renameFile(File file, String suffix, FsWorker worker) throws
return newFile;
}

// /**
// *
// * @param uri the relative <code>URI</code> to process
// * @return a <code>file:/// URL</code> based on the current working directory (obtained by
// calling
// * <code>System.getProperty("user.dir")</code>) plus the passed relative <code>uri</code>
// * @throws Exception wrapping any underlying <code>Exception</code>
// */
// private static URL relativeConfig(URI uri) throws IOException {
// String pwd = System.getProperty("user.dir");
//
// String path = pwd + "/" + uri; // ok even if uri starts with a /
// URL result = new URL("file:///" + path);
//
// return result;
// }

private static String backslashToSlash(String url) {
if (!isEmpty(url)) {
return url.replaceAll("\\\\", "/");
Expand Down
27 changes: 27 additions & 0 deletions interlok-core/src/main/java/com/adaptris/core/fs/FsProducer.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,34 @@
import lombok.Setter;

/**
* <p>
* {@link com.adaptris.core.AdaptrisMessageProducer} implementation that writes to the file system.
* </p>
* <p>
* The configured <code>Base Directory URL</code> may return a string in one of two formats
* </p>
* <ul>
* <li>
* Supports URLs with both the {@code file scheme} and without.
* </li>
* <li>
* If you define a directory without any leading slash or
* if it starts with a slash is deemed to be an <strong>absolute</strong> path.
* </li>
* <li>
* If "./" or "../" is used at the start of your definition then
* the path is deemed to be <strong>relative</strong>.</li>
* <li>
* This is true whether using the {@code file scheme} or not.
* </li>
* <li>
* With Windows systems The above is above is true plus if you simply define the <strong>absolute</strong> path including the drive letter
* e.g. 'c://my/path' this is also valid.
* </li>
* <li>
* Both / and \ slashes are supported.
* </li>
* </ul>
*
* @config fs-producer
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,30 @@
* changes.
* </p>
* <p>
* The configured <code>Destination</code> may return a string in one of two formats
* The configured <code>Base Directory URL</code> may return a string in one of two formats
* </p>
* <ul>
* <li>If a <code>file</code> based url is used. e.g. file:///c:/path/to/my/directory or file:////path/to/my/directory then the
* patch is considered to be fully qualified</li>
* <li>If just a path is returned, then it is considered to be relative to the current working directory. e.g. if /opt/fred is used,
* and the adapter is installed to /opt/adapter, then the fully qualified name is /opt/adapter/opt/fred.</li>
* <li>
* Supports URLs with both the {@code file scheme} and without.
* </li>
* <li>
* If you define a directory without any leading slash or
* if it starts with a slash is deemed to be an <strong>absolute</strong> path.
* </li>
* <li>
* If "./" or "../" is used at the start of your definition then
* the path is deemed to be <strong>relative</strong>.</li>
* <li>
* This is true whether using the {@code file scheme} or not.
* </li>
* <li>
* With Windows systems the above is above is true, plus if you simply define the <strong>absolute</strong> path including the drive letter
* e.g. 'c://my/path' this is also valid.
* </li>
* <li>
* Both / and \ slashes are supported.
* </li>
* </ul>
* <p>
* On windows based platforms, you should always use a file based url.
* </p>
*
* @config non-deleting-fs-consumer
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,31 @@
* <p>
* File system implementation of <code>AdaptrisMessageConsumer</code> with large message support.
* </p>
* <ul>
* <li>If a <code>file</code> based url is used. e.g. file:///c:/path/to/my/directory or file:////path/to/my/directory then the
* patch is considered to be fully qualified</li>
* <li>If just a path is returned, then it is considered to be relative to the current working directory. e.g. if /opt/fred is used,
* and the adapter is installed to /opt/adapter, then the fully qualified name is /opt/adapter/opt/fred.</li>
* </ul>
* <p>
* On windows based platforms, you should always use a file based url.
* The configured <code>Base Directory URL</code> may return a string in one of two formats
* </p>
* <ul>
* <li>
* Supports URLs with both the {@code file scheme} and without.
* </li>
* <li>
* If you define a directory without any leading slash or
* if it starts with a slash is deemed to be an <strong>absolute</strong> path.
* </li>
* <li>
* If "./" or "../" is used at the start of your definition then
* the path is deemed to be <strong>relative</strong>.</li>
* <li>
* This is true whether using the {@code file scheme} or not.
* </li>
* <li>
* With Windows systems the above is above is true, plus if you simply define the <strong>absolute</strong> path including the drive letter
* e.g. 'c://my/path' this is also valid.
* </li>
* <li>
* Both / and \ slashes are supported.
* </li>
* </ul>
* <p>
* Additionally the behaviour of this consumer is subtly different from the standard {@link FsConsumer} :
* </p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,32 @@
* <p>
* File system implementation of <code>AdaptrisMessageProducer</code> with large message support.
* </p>
* *
* <p>
* The configured <code>Destination</code> may return a string in one of two formats
* The configured <code>Base Directory URL</code> may return a string in one of two formats
* </p>
* <ul>
* <li>If a <code>file</code> based url is used. e.g. file:///c:/path/to/my/directory or file:////path/to/my/directory then the
* patch is considered to be fully qualified</li>
* <li>If just a path is returned, then it is considered to be relative to the current working directory. e.g. if /opt/fred is used,
* and the adapter is installed to /opt/adapter, then the fully qualified name is /opt/adapter/opt/fred.</li>
* <li>
* Supports URLs with both the {@code file scheme} and without.
* </li>
* <li>
* If you define a directory without any leading slash or
* if it starts with a slash is deemed to be an <strong>absolute</strong> path.
* </li>
* <li>
* If "./" or "../" is used at the start of your definition then
* the path is deemed to be <strong>relative</strong>.</li>
* <li>
* This is true whether using the {@code file scheme} or not.
* </li>
* <li>
* With Windows systems the above is above is true, plus if you simply define the <strong>absolute</strong> path including the drive letter
* e.g. 'c://my/path' this is also valid.
* </li>
* <li>
* Both / and \ slashes are supported.
* </li>
* </ul>
* <p>
* On windows based platforms, you should always use a file based url.
* </p>
* <p>
* Additionally the behaviour of this consumer is subtly different from the standard {@link FsProducer} :
* </p>
* <ul>
Expand Down
56 changes: 38 additions & 18 deletions interlok-core/src/test/java/com/adaptris/core/fs/FsHelperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,38 +41,44 @@ public class FsHelperTest extends FsHelper {

@Test
public void testUnixStyleFullURI() throws Exception {
assertNotNull(FsHelper.createUrlFromString("file:////home/fred"));
assertNotNull(FsHelper.createUrlFromString("file:////home/fred", true));
}

@Test
public void testUnixStyleURI() throws Exception {
URL url = FsHelper.createUrlFromString("/home/fred");
public void testUnixStyleAbsoluteURI() throws Exception {
URL url = FsHelper.createUrlFromString("/home/fred", true);
assertEquals("fred", new File(url.toURI()).getName());
}

@Test
public void testUnixStyleRelativeURI() throws Exception {
URL url = FsHelper.createUrlFromString("./home/fred", true);
assertEquals("fred", new File(url.toURI()).getName());
}

@Test
public void testWindowsFullURI() throws Exception {
URL url = FsHelper.createUrlFromString("file:///c:/home/fred");
URL url = FsHelper.createUrlFromString("file:///c:/home/fred", true);
assertEquals("fred", new File(url.toURI()).getName());
}

@Test
public void testFullURIWithColons() throws Exception {
URL url = FsHelper.createUrlFromString("file:///c:/home/fred/d:/home/fred");
URL url = FsHelper.createUrlFromString("file:///c:/home/fred/d:/home/fred", true);
assertEquals("fred", new File(url.toURI()).getName());
}

@Test
public void testCreateFileRef() throws Exception {
URL url = FsHelper.createUrlFromString("file:///home/fred");
URL url = FsHelper.createUrlFromString("file:///home/fred", true);
assertEquals(new File("/home/fred"), FsHelper.createFileReference(url));
assertEquals(new File("/home/fred"), FsHelper.createFileReference(url, "UTF-8"));
}

@Test
public void testCreateFileRefWithSpaces() throws Exception {
URL url = FsHelper
.createUrlFromString("file:///home/directory%20with/some/spaces");
.createUrlFromString("file:///home/directory%20with/some/spaces", true);
File f = FsHelper.createFileReference(url);
assertEquals(new File("/home/directory with/some/spaces"), f);
}
Expand All @@ -85,13 +91,8 @@ public void testCreateFileRefWithBackSlash() throws Exception {

@Test
public void testWindowsURI() throws Exception {
try {
FsHelper.createUrlFromString("c:/home/fred");
}
catch (IllegalArgumentException e) {
// This is expected. as c:/home/fred is in fact wrong.
// Other exceptions are not falid though.
}
URL url = FsHelper.createUrlFromString("c:/home/fred", true);
assertEquals("fred", new File(url.toURI()).getName());
}

@Test
Expand Down Expand Up @@ -148,18 +149,37 @@ public void testCreateUrlFromString() throws Exception {
String urlString3 = "../dir/";
URL url3 = FsHelper.createUrlFromString(urlString3, true);
assertTrue("file".equals(url3.getProtocol()));
assertTrue("/../dir/".equals(url3.getPath()));

String urlString4 = "..\\dir\\";
URL url4 = FsHelper.createUrlFromString(urlString4, true);
assertTrue("file".equals(url4.getProtocol()));
assertTrue("/../dir/".equals(url4.getPath()));

String urlString5 = "c:\\dir\\";
URL url5 = FsHelper.createUrlFromString(urlString5, true);
assertTrue("file".equals(url5.getProtocol()));
assertTrue("/c:/dir/".equals(url5.getPath()));

String urlString6 = "D:\\dir\\";
URL url6 = FsHelper.createUrlFromString(urlString6, true);
assertTrue("file".equals(url6.getProtocol()));
assertTrue("/D:/dir/".equals(url6.getPath()));

tryExpectingException(() -> {
FsHelper.createUrlFromString("..\\dir\\");
FsHelper.createUrlFromString("..\\dir\\", false);
});
tryExpectingException(() -> {
FsHelper.createUrlFromString("c:\\dir\\", false);
});
tryExpectingException(() -> {
FsHelper.createUrlFromString("c:\\dir\\");
FsHelper.createUrlFromString("http://file/", true);
});
tryExpectingException(() -> {
FsHelper.createUrlFromString("http://file/");
FsHelper.createUrlFromString("5://file/", true);
});
tryExpectingException(() -> {
FsHelper.createUrlFromString("file:\\\file\\");
FsHelper.createUrlFromString("file:\\\file\\", true);
});
tryExpectingException(() -> {
FsHelper.createUrlFromString(null, true);
Expand Down