You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@manifoldcf.apache.org by kw...@apache.org on 2013/12/24 11:43:17 UTC
svn commit: r1553263 -
/manifoldcf/trunk/connectors/filesystem/connector/src/main/java/org/apache/manifoldcf/agents/output/filesystem/FileOutputConnector.java
Author: kwright
Date: Tue Dec 24 10:43:17 2013
New Revision: 1553263
URL: http://svn.apache.org/r1553263
Log:
File system output connector logic to avoid collisions. Part of CONNECTORS-814.
Modified:
manifoldcf/trunk/connectors/filesystem/connector/src/main/java/org/apache/manifoldcf/agents/output/filesystem/FileOutputConnector.java
Modified: manifoldcf/trunk/connectors/filesystem/connector/src/main/java/org/apache/manifoldcf/agents/output/filesystem/FileOutputConnector.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/connectors/filesystem/connector/src/main/java/org/apache/manifoldcf/agents/output/filesystem/FileOutputConnector.java?rev=1553263&r1=1553262&r2=1553263&view=diff
==============================================================================
--- manifoldcf/trunk/connectors/filesystem/connector/src/main/java/org/apache/manifoldcf/agents/output/filesystem/FileOutputConnector.java (original)
+++ manifoldcf/trunk/connectors/filesystem/connector/src/main/java/org/apache/manifoldcf/agents/output/filesystem/FileOutputConnector.java Tue Dec 24 10:43:17 2013
@@ -180,28 +180,78 @@ public class FileOutputConnector extends
if (specs.getRootPath() != null) {
path.append(specs.getRootPath());
}
- path.append("/");
- path.append(documentURItoFilePath(documentURI));
-
- File file = new File(path.toString());
-
- //System.out.println("File is '"+file+"'");
-
- /*
- * make directory
- */
- if (!file.getParentFile().exists()) {
- file.getParentFile().mkdirs();
- }
-
- /*
- * delete old file
- */
- if (file.exists()) {
- file.delete();
+
+ // If the path does not yet exist at the root level, it is dangerous to create it.
+ File currentPath = new File(path.toString());
+ if (!currentPath.exists())
+ throw new ManifoldCFException("Root path does not yet exist: '"+currentPath+"'");
+ if (!currentPath.isDirectory())
+ throw new ManifoldCFException("Root path is not a directory: '"+currentPath+"'");
+
+ String filePath = documentURItoFilePath(documentURI);
+
+ // Build path one level at a time. This is needed because there may be a collision at
+ // every level.
+ int index = 0;
+ while (true)
+ {
+ int currentIndex = filePath.indexOf("/",index);
+ if (currentIndex == -1)
+ break;
+ String dirName = filePath.substring(index,currentIndex);
+ File newPath = new File(currentPath, dirName);
+ index = currentIndex + 1;
+ int suffix = 1;
+ while (true)
+ {
+ if (newPath.exists() && newPath.isDirectory())
+ break;
+ // Try to create it. If we fail, check if it now exists as a file.
+ if (newPath.mkdir())
+ break;
+ // Hmm, didn't create. If it is a file, we suffered a collision, so try again with ".N" as a suffix.
+ if (newPath.exists())
+ {
+ if (newPath.isDirectory())
+ break;
+ newPath = new File(currentPath, dirName + "." + suffix);
+ suffix++;
+ }
+ else
+ throw new ManifoldCFException("Could not create directory '"+newPath+"'. Permission issue?");
+ }
+ // Directory successfully created!
+ currentPath = newPath;
+ // Go on to the next one.
+ }
+
+ // Path successfully created. Now create file.
+ FileOutputStream output = null;
+ String fileName = filePath.substring(index);
+ File outputPath = new File(currentPath, fileName);
+ int fileSuffix = 1;
+ while (true)
+ {
+ try
+ {
+ output = new FileOutputStream(outputPath);
+ break;
+ }
+ catch (FileNotFoundException e)
+ {
+ // Figure out why it could not be created.
+ if (outputPath.exists() && !outputPath.isFile())
+ {
+ // try a new file
+ outputPath = new File(currentPath, fileName + "." + fileSuffix);
+ fileSuffix++;
+ continue;
+ }
+ // Probably some other error
+ throw new ManifoldCFException("Could not create file '"+outputPath+"': "+e.getMessage(),e);
+ }
}
- FileOutputStream output = new FileOutputStream(file);
try {
/*
* lock file
@@ -209,7 +259,7 @@ public class FileOutputConnector extends
FileChannel channel = output.getChannel();
FileLock lock = channel.tryLock();
if (lock == null)
- throw new ServiceInterruption("Could not lock file: '"+file+"'",null,1000L,-1L,10,false);
+ throw new ServiceInterruption("Could not lock file: '"+outputPath+"'",null,1000L,-1L,10,false);
try {
@@ -217,7 +267,7 @@ public class FileOutputConnector extends
* write file
*/
InputStream input = document.getBinaryStream();
- byte buf[] = new byte[1024];
+ byte buf[] = new byte[65536];
int len;
while((len = input.read(buf)) != -1) {
output.write(buf, 0, len);
@@ -244,12 +294,12 @@ public class FileOutputConnector extends
} catch (URISyntaxException e) {
handleURISyntaxException(e);
return DOCUMENTSTATUS_REJECTED;
- } catch (SecurityException e) {
- handleSecurityException(e);
- return DOCUMENTSTATUS_REJECTED;
} catch (FileNotFoundException e) {
handleFileNotFoundException(e);
return DOCUMENTSTATUS_REJECTED;
+ } catch (SecurityException e) {
+ handleSecurityException(e);
+ return DOCUMENTSTATUS_REJECTED;
} catch (IOException e) {
handleIOException(e);
return DOCUMENTSTATUS_REJECTED;