mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
A new flavor of createFile. Slightly slower. Significantly safer.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3277 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
package org.alfresco.repo.avm;
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -171,10 +172,13 @@ class AVMCrawler implements Runnable
|
|||||||
for (int i = 0; i < 1; i++)
|
for (int i = 0; i < 1; i++)
|
||||||
{
|
{
|
||||||
String name = randomName();
|
String name = randomName();
|
||||||
PrintStream out = new PrintStream(fService.createFile(dir.getPath(), name));
|
fService.createFile(dir.getPath(), name,
|
||||||
|
new ByteArrayInputStream(("I am " + name).getBytes()));
|
||||||
fOpCount++;
|
fOpCount++;
|
||||||
out.println("I am " + name);
|
// PrintStream out = new PrintStream(fService.createFile(dir.getPath(), name));
|
||||||
out.close();
|
// fOpCount++;
|
||||||
|
// out.println("I am " + name);
|
||||||
|
// out.close();
|
||||||
}
|
}
|
||||||
// 1 in 100 times create a directory.
|
// 1 in 100 times create a directory.
|
||||||
if (fRandom.nextInt(100) == 0)
|
if (fRandom.nextInt(100) == 0)
|
||||||
|
@@ -86,6 +86,15 @@ public interface AVMService
|
|||||||
*/
|
*/
|
||||||
public OutputStream createFile(String path, String name);
|
public OutputStream createFile(String path, String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new File. Guarantees that the entire contents of the
|
||||||
|
* input stream will be loaded atomically.
|
||||||
|
* @param path The path to the parent directory.
|
||||||
|
* @param name The name for the new file.
|
||||||
|
* @param in An input stream with data for the file.
|
||||||
|
*/
|
||||||
|
public void createFile(String path, String name, InputStream in);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new directory.
|
* Create a new directory.
|
||||||
* @param path The simple absolute path to the parent.
|
* @param path The simple absolute path to the parent.
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
package org.alfresco.repo.avm;
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
@@ -356,6 +358,58 @@ public class AVMServiceImpl implements AVMService
|
|||||||
return doit.out;
|
return doit.out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a file with content specified by the InputStream.
|
||||||
|
* Guaranteed to be created atomically.
|
||||||
|
* @param path The path to the containing directory.
|
||||||
|
* @param name The name to give the file.
|
||||||
|
* @param in An InputStream containing data for file.
|
||||||
|
*/
|
||||||
|
public void createFile(final String path, final String name, InputStream in)
|
||||||
|
{
|
||||||
|
if (path == null || name == null || in == null)
|
||||||
|
{
|
||||||
|
throw new AVMBadArgumentException("Illegal null argument.");
|
||||||
|
}
|
||||||
|
// Save the contents to temp space.
|
||||||
|
File dir = new File(fStorage);
|
||||||
|
final File temp;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
temp = File.createTempFile("alf", "tmp", dir);
|
||||||
|
OutputStream out = new FileOutputStream(temp);
|
||||||
|
byte [] buff = new byte[8192];
|
||||||
|
int read;
|
||||||
|
while ((read = in.read(buff)) != -1)
|
||||||
|
{
|
||||||
|
out.write(buff, 0, read);
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException ie)
|
||||||
|
{
|
||||||
|
throw new AVMException("I/O Error.");
|
||||||
|
}
|
||||||
|
class HTxnCallback implements HibernateTxnCallback
|
||||||
|
{
|
||||||
|
public void perform(Session session)
|
||||||
|
{
|
||||||
|
fSuperRepository.setSession(session);
|
||||||
|
fSuperRepository.createFile(path, name, temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HTxnCallback doit = new HTxnCallback();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fTransaction.perform(doit, true);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
temp.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.avm.AVMService#createFolder(java.lang.String, java.lang.String)
|
* @see org.alfresco.repo.avm.AVMService#createFolder(java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
package org.alfresco.repo.avm;
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
@@ -47,8 +48,8 @@ public class AVMServiceTest extends AVMServiceTestBase
|
|||||||
fService.createDirectory("main:/", "a");
|
fService.createDirectory("main:/", "a");
|
||||||
fService.createDirectory("main:/a", "b");
|
fService.createDirectory("main:/a", "b");
|
||||||
fService.createDirectory("main:/a", "c");
|
fService.createDirectory("main:/a", "c");
|
||||||
fService.createFile("main:/a/b", "foo").close();
|
fService.createFile("main:/a/b", "foo", new ByteArrayInputStream("I am foo.".getBytes()));
|
||||||
fService.createFile("main:/a/c", "bar").close();
|
fService.createFile("main:/a/c", "bar", new ByteArrayInputStream("I am bar.".getBytes()));
|
||||||
fService.createSnapshot("main");
|
fService.createSnapshot("main");
|
||||||
// History is unchanged.
|
// History is unchanged.
|
||||||
checkHistory(history, "main");
|
checkHistory(history, "main");
|
||||||
|
@@ -92,6 +92,36 @@ class FileContentImpl implements FileContent, Serializable
|
|||||||
SuperRepository.GetInstance().getSession().save(this);
|
SuperRepository.GetInstance().getSession().save(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize with the given content.
|
||||||
|
* @param id
|
||||||
|
* @param content
|
||||||
|
*/
|
||||||
|
public FileContentImpl(long id, File content)
|
||||||
|
{
|
||||||
|
fID = id;
|
||||||
|
fRefCount = 1;
|
||||||
|
// Initialize the contents.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OutputStream out = getOutputStream();
|
||||||
|
InputStream in = new FileInputStream(content);
|
||||||
|
byte [] buff = new byte[8192];
|
||||||
|
int count;
|
||||||
|
while ((count = in.read(buff)) != -1)
|
||||||
|
{
|
||||||
|
out.write(buff, 0, count);
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException ie)
|
||||||
|
{
|
||||||
|
throw new AVMException("I/O Error.", ie);
|
||||||
|
}
|
||||||
|
SuperRepository.GetInstance().getSession().save(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy constructor, sort of.
|
* Copy constructor, sort of.
|
||||||
* @param other The content to copy from.
|
* @param other The content to copy from.
|
||||||
|
@@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
package org.alfresco.repo.avm;
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A plain old file. Contains a Content object.
|
* A plain old file. Contains a Content object.
|
||||||
@@ -50,6 +52,18 @@ class PlainFileNodeImpl extends FileNodeImpl implements PlainFileNode
|
|||||||
repos.getSuperRepository().getSession().save(this);
|
repos.getSuperRepository().getSession().save(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new plain file with given content.
|
||||||
|
* @param repos The repository.
|
||||||
|
* @param content The content to set.
|
||||||
|
*/
|
||||||
|
public PlainFileNodeImpl(Repository repos, File content)
|
||||||
|
{
|
||||||
|
super(repos.getSuperRepository().issueID(), repos);
|
||||||
|
fContent = new FileContentImpl(SuperRepository.GetInstance().issueContentID(), content);
|
||||||
|
repos.getSuperRepository().getSession().save(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy on write constructor.
|
* Copy on write constructor.
|
||||||
* @param other The node we are being copied from.
|
* @param other The node we are being copied from.
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.avm;
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
@@ -73,6 +74,14 @@ interface Repository
|
|||||||
* @return An OutputStream.
|
* @return An OutputStream.
|
||||||
*/
|
*/
|
||||||
public OutputStream createFile(String path, String name);
|
public OutputStream createFile(String path, String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a file with the given contents.
|
||||||
|
* @param path The path to the containing directory.
|
||||||
|
* @param name The name to give the file.
|
||||||
|
* @param data The contents of the file.
|
||||||
|
*/
|
||||||
|
public void createFile(String path, String name, File data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new layered file.
|
* Create a new layered file.
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package org.alfresco.repo.avm;
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
@@ -241,10 +242,30 @@ class RepositoryImpl implements Repository, Serializable
|
|||||||
PlainFileNodeImpl file = new PlainFileNodeImpl(this);
|
PlainFileNodeImpl file = new PlainFileNodeImpl(this);
|
||||||
file.setVersionID(getNextVersionID());
|
file.setVersionID(getNextVersionID());
|
||||||
dir.putChild(name, file);
|
dir.putChild(name, file);
|
||||||
file.updateModTime();
|
dir.updateModTime();
|
||||||
return file.getContentForWrite().getOutputStream();
|
return file.getContentForWrite().getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a file with the given contents.
|
||||||
|
* @param path The path to the containing directory.
|
||||||
|
* @param name The name to give the new file.
|
||||||
|
* @param data The contents.
|
||||||
|
*/
|
||||||
|
public void createFile(String path, String name, File data)
|
||||||
|
{
|
||||||
|
Lookup lPath = lookupDirectory(-1, path, true);
|
||||||
|
DirectoryNode dir = (DirectoryNode)lPath.getCurrentNode();
|
||||||
|
if (dir.lookupChild(lPath, name, -1, true) != null)
|
||||||
|
{
|
||||||
|
throw new AVMExistsException("Child exists: " + name);
|
||||||
|
}
|
||||||
|
PlainFileNodeImpl file = new PlainFileNodeImpl(this, data);
|
||||||
|
file.setVersionID(getNextVersionID());
|
||||||
|
dir.putChild(name, file);
|
||||||
|
dir.updateModTime();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new layered file.
|
* Create a new layered file.
|
||||||
* @param srcPath The target indirection for the layered file.
|
* @param srcPath The target indirection for the layered file.
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package org.alfresco.repo.avm;
|
package org.alfresco.repo.avm;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.RandomAccessFile;
|
import java.io.RandomAccessFile;
|
||||||
@@ -117,6 +118,20 @@ class SuperRepository
|
|||||||
return rep.createFile(pathParts[1], name);
|
return rep.createFile(pathParts[1], name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a file with the given File as content.
|
||||||
|
* @param path The path to the containing directory.
|
||||||
|
* @param name The name to give the file.
|
||||||
|
* @param data The file contents.
|
||||||
|
*/
|
||||||
|
public void createFile(String path, String name, File data)
|
||||||
|
{
|
||||||
|
fLookupCount.set(1);
|
||||||
|
String[] pathParts = SplitPath(path);
|
||||||
|
Repository rep = getRepositoryByName(pathParts[0], true);
|
||||||
|
rep.createFile(pathParts[1], name, data);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new directory.
|
* Create a new directory.
|
||||||
* @param path The path to the containing directory.
|
* @param path The path to the containing directory.
|
||||||
|
Reference in New Issue
Block a user