Author: ozeigermann
Date: Tue Aug 14 15:37:07 2007
New Revision: 565953
URL: http://svn.apache.org/viewvc?view=rev&rev=565953
Log:
First working version of tx file resource manager driven by test.
Added:
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/DefaultTransactionTest.java
- copied, changed from r565874,
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/TransactionImplTest.java
Removed:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/deadlock1.png
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/deadlock2.png
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/deadlock3.png
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/TransactionImplTest.java
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/ComboInputStreamMulticasterTest.java
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/TransactionException.java
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/HierarchicalRWLockManager.java
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/TransactionException.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/TransactionException.java?view=diff&rev=565953&r1=565952&r2=565953
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/TransactionException.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/TransactionException.java
Tue Aug 14 15:37:07 2007
@@ -38,6 +38,10 @@
this.code = code;
}
+ public TransactionException(Throwable cause) {
+ super(cause);
+ }
+
public TransactionException(Code code) {
this.code = code;
}
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java?view=diff&rev=565953&r1=565952&r2=565953
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java
Tue Aug 14 15:37:07 2007
@@ -27,6 +27,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.commons.transaction.TransactionException;
import org.apache.commons.transaction.resource.ResourceException;
import org.apache.commons.transaction.resource.ResourceManager;
import org.apache.commons.transaction.resource.StreamableResource;
@@ -39,7 +40,13 @@
protected String rootPath;
public FileResourceManager(String rootPath) {
- this.rootPath = rootPath;
+ try {
+ File file = new File(rootPath);
+ file.mkdirs();
+ this.rootPath = file.getCanonicalPath();
+ } catch (IOException e) {
+ throw new TransactionException(e);
+ }
}
public FileResourceManager.FileResource getResource(String path) throws
ResourceException {
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java?view=diff&rev=565953&r1=565952&r2=565953
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
Tue Aug 14 15:37:07 2007
@@ -14,10 +14,9 @@
public class MemoryUndoManager implements FileResourceUndoManager {
private Log logger = LogFactory.getLog(getClass());
-
+
protected ThreadLocal<List<UndoRecord>> localRecords = new
ThreadLocal<List<UndoRecord>>();
-
private final File logDirectory;
public MemoryUndoManager(String logDir) throws IOException {
@@ -38,6 +37,10 @@
}
public void forgetRecord() {
+ List<UndoRecord> records = new
ArrayList<UndoRecord>(localRecords.get());
+ for (UndoRecord record : records) {
+ record.cleanUp();
+ }
localRecords.set(null);
}
@@ -91,6 +94,12 @@
}
protected void save() {
+ storeRecord(this);
+ }
+
+ public void cleanUp() {
+ if (updatedFile != null)
+ updatedFile.delete();
}
public void undo() {
@@ -103,11 +112,11 @@
break;
case UPDATED_CONTENT:
try {
- FileHelper.move(updatedFile, file);
- } catch (IOException e) {
- // FIXME: This really is fatal: How to signal?
- logger.fatal("Can not undo content update", e);
- }
+ FileHelper.move(updatedFile, file);
+ } catch (IOException e) {
+ // FIXME: This really is fatal: How to signal?
+ logger.fatal("Can not undo content update", e);
+ }
break;
}
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java?view=diff&rev=565953&r1=565952&r2=565953
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java
Tue Aug 14 15:37:07 2007
@@ -24,6 +24,7 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -45,8 +46,6 @@
private Log logger = LogFactory.getLog(getClass());
- protected String rootPath;
-
protected FileResourceManager wrapped;
protected FileResourceUndoManager undoManager;
@@ -55,7 +54,6 @@
public TxFileResourceManager(String name, String rootPath) {
super(name);
- this.rootPath = rootPath;
wrapped = new FileResourceManager(rootPath);
}
@@ -71,7 +69,7 @@
@Override
public void setLm(LockManager<Object, Object> lm) {
super.setLm(lm);
- hlm = new HierarchicalRWLockManager(rootPath, lm);
+ hlm = new HierarchicalRWLockManager(getRootPath(), lm);
}
public class FileTxContext extends AbstractTxContext implements
@@ -100,6 +98,12 @@
}
@Override
+ public void start(long timeout, TimeUnit unit) {
+ getUndoManager().startRecord();
+ super.start(timeout, unit);
+ }
+
+ @Override
public String getRootPath() {
return TxFileResourceManager.this.getRootPath();
}
@@ -329,12 +333,12 @@
}
public void readLock() {
- getHLM().lockInHierarchy(getName(), getPath(), false);
+ getHLM().lockInHierarchy(TxFileResourceManager.this.getName(),
getPath(), false);
super.readLock();
}
public void writeLock() {
- getHLM().lockInHierarchy(getName(), getPath(), true);
+ getHLM().lockInHierarchy(TxFileResourceManager.this.getName(),
getPath(), true);
super.writeLock();
}
}
@@ -356,7 +360,7 @@
}
public String getRootPath() {
- return rootPath;
+ return wrapped.getRootPath();
}
protected FileResourceUndoManager getUndoManager() {
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/HierarchicalRWLockManager.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/HierarchicalRWLockManager.java?view=diff&rev=565953&r1=565952&r2=565953
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/HierarchicalRWLockManager.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/HierarchicalRWLockManager.java
Tue Aug 14 15:37:07 2007
@@ -33,7 +33,11 @@
throws LockException {
// strip off root path
// TODO misses sane checks
- String relativePath = path.substring(path.indexOf(rootPath));
+ if (!path.startsWith(rootPath)) {
+ throw new LockException("Could not lock a path (" + path
+ + ") that is not under the rootPath (" + rootPath + ")");
+ }
+ String relativePath = path.substring(rootPath.length());
// this is the root path we want to lock
if (relativePath.length() == 0) {
@@ -44,12 +48,13 @@
// always read lock root
lock(managedResource, "/", false);
- String[] segments = relativePath.split("/");
+ String[] segments = relativePath.split("\\\\");
StringBuffer currentPath = new StringBuffer(relativePath.length());
// for root path
currentPath.append('/');
- for (int i = 0; i < segments.length; i++) {
+ // skip first segment which is just empty
+ for (int i = 1; i < segments.length; i++) {
String segment = segments[i];
currentPath.append(segment).append('/');
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java?view=diff&rev=565953&r1=565952&r2=565953
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/locking/LockException.java
Tue Aug 14 15:37:07 2007
@@ -34,23 +34,23 @@
* Thread has been interrupted while waiting for lock.
*/
INTERRUPTED,
-
+
/**
* Maximum wait time for a lock has been exceeded.
*/
TIMED_OUT,
-
+
/**
* Locking request canceled because of deadlock.
*/
WOULD_DEADLOCK,
-
+
/**
- * A conflict between two optimistic transactions occured.
+ * A conflict between two optimistic transactions occurred.
*
*/
CONFLICT,
-
+
/**
* A commit was tried, but did not succeed.
*
@@ -61,6 +61,15 @@
protected Object resourceId;
protected Code code;
+
+ public LockException(String message, Object resourceId) {
+ super(message);
+ this.resourceId = resourceId;
+ }
+
+ public LockException(String message) {
+ super(message);
+ }
public LockException(String message, Code code, Object resourceId) {
super(message);
Copied:
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/DefaultTransactionTest.java
(from r565874,
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/TransactionImplTest.java)
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/DefaultTransactionTest.java?view=diff&rev=565953&p1=commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/TransactionImplTest.java&r1=565874&p2=commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/DefaultTransactionTest.java&r2=565953
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/TransactionImplTest.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/DefaultTransactionTest.java
Tue Aug 14 15:37:07 2007
@@ -26,14 +26,14 @@
import org.apache.commons.transaction.memory.TxMap;
import org.junit.Test;
-public class TransactionImplTest {
+public class DefaultTransactionTest {
public static junit.framework.Test suite() {
- return new JUnit4TestAdapter(TransactionImplTest.class);
+ return new JUnit4TestAdapter(DefaultTransactionTest.class);
}
@Test
public void basic() {
- LockManager lm = new RWLockManager<String, String>();
+ LockManager<Object, Object> lm = new RWLockManager<Object, Object>();
Transaction t = new DefaultTransaction(lm);
TxMap<String, Object> txMap1 = new PessimisticTxMap<String,
Object>("TxMap1");
t.enlistResourceManager(txMap1);
@@ -52,6 +52,6 @@
}
public static void main(String[] args) {
- new TransactionImplTest().basic();
+ new DefaultTransactionTest().basic();
}
}
Modified:
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java?view=diff&rev=565953&r1=565952&r2=565953
==============================================================================
---
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java
(original)
+++
commons/proper/transaction/branches/TRANSACTION_2/src/test/org/apache/commons/transaction/file/TxFileResourceManagerTest.java
Tue Aug 14 15:37:07 2007
@@ -16,11 +16,16 @@
*/
package org.apache.commons.transaction.file;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.concurrent.TimeUnit;
import junit.framework.JUnit4TestAdapter;
+import static junit.framework.Assert.fail;
import org.apache.commons.transaction.file.FileResourceManager.FileResource;
import org.apache.commons.transaction.locking.LockManager;
@@ -28,10 +33,143 @@
import org.junit.Test;
public class TxFileResourceManagerTest {
+
+ private static final String ENCODING = "ISO-8859-15";
+
public static junit.framework.Test suite() {
return new JUnit4TestAdapter(TxFileResourceManagerTest.class);
}
+ private static final void createFiles(String[] filePaths) {
+ createFiles(filePaths, null, null);
+ }
+
+ private static final void createFiles(String[] filePaths, String dirPath) {
+ createFiles(filePaths, null, dirPath);
+ }
+
+ private static final void createFiles(String[] filePaths, String[]
contents) {
+ createFiles(filePaths, contents, null);
+ }
+
+ private static final void createFiles(String[] filePaths, String[]
contents, String dirPath) {
+ for (int i = 0; i < filePaths.length; i++) {
+ String filePath = filePaths[i];
+ File file;
+ if (dirPath != null) {
+ file = new File(new File(dirPath), filePath);
+ } else {
+ file = new File(filePath);
+ }
+ file.getParentFile().mkdirs();
+ try {
+ file.delete();
+ file.createNewFile();
+ String content = null;
+ if (contents != null && contents.length > i) {
+ content = contents[i];
+ }
+ if (content != null) {
+ FileOutputStream stream = new FileOutputStream(file);
+ stream.write(contents[i].getBytes(ENCODING));
+ stream.close();
+ }
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ private static final void checkIsEmpty(String dirPath) {
+ checkExactlyContains(dirPath, null);
+ }
+ private static final void checkExactlyContains(String dirPath, String[]
fileNames) {
+ checkExactlyContains(dirPath, fileNames, null);
+ }
+
+ private static final void checkExactlyContains(String dirPath, String[]
fileNames,
+ String[] contents) {
+ File dir = new File(dirPath);
+
+ if (dir.isDirectory()) {
+ File[] files = dir.listFiles();
+ if (fileNames == null) {
+ if (files.length != 0) {
+ fail(dirPath + " must be empty");
+ } else {
+ return;
+ }
+ }
+
+ if (files.length != fileNames.length) {
+ fail(dirPath + " contains " + files.length + " instead of " +
fileNames.length
+ + " files");
+ }
+
+ for (int i = 0; i < fileNames.length; i++) {
+ String fileName = fileNames[i];
+ boolean match = false;
+ File file = null;
+ for (int j = 0; j < files.length; j++) {
+ file = files[j];
+ if (file.getName().equals(fileName)) {
+ match = true;
+ break;
+ }
+ }
+ if (!match) {
+ fail(dirPath + " does not contain required " + fileName);
+ }
+
+ String content = null;
+ if (contents != null && i < contents.length) {
+ content = contents[i];
+ }
+ if (content != null && !compare(file, content)) {
+ fail("Contents of " + fileName + " in " + dirPath
+ + " does not contain required content '" + content
+ "'");
+ }
+ }
+
+ } else {
+ fail(dirPath + " is not directoy");
+ }
+ }
+
+ private static boolean compare(FileInputStream stream, byte[] bytes) {
+ int read;
+ int count = 0;
+ try {
+ while ((read = stream.read()) != -1) {
+ if (bytes[count++] != read) {
+ return false;
+ }
+ }
+ } catch (IOException e) {
+ return false;
+ }
+ return true;
+ }
+
+ private static boolean compare(File file, String content) {
+ FileInputStream stream = null;
+ try {
+ byte[] bytes = content.getBytes(ENCODING);
+ stream = new FileInputStream(file);
+ return compare(stream, bytes);
+ } catch (Throwable t) {
+ return false;
+ } finally {
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+
+
@Test
public void basic() {
TxFileResourceManager manager = new
TxFileResourceManager("TxFileManager", "d:/tmp/content");
@@ -43,12 +181,15 @@
manager.setUndoManager(um);
manager.startTransaction(60, TimeUnit.SECONDS);
FileResource file = manager.getResource("d:/tmp/content/aha");
- file.createAsFile();
- OutputStream os = file.writeStream(false);
+ if (!file.exists()) {
+ file.createAsFile();
+ }
+ OutputStream os = file.writeStream(true);
PrintStream ps = new PrintStream(os);
- ps.print("Huhu");
+ ps.println("Huhu");
manager.commitTransaction();
} catch (Throwable throwable) {
+ System.err.println(throwable);
manager.rollbackTransaction();
}