Author: ozeigermann
Date: Mon Jul 23 13:54:15 2007
New Revision: 558857

URL: http://svn.apache.org/viewvc?view=rev&rev=558857
Log:
First step to (yet non-working) pessimistic tx file manager having undo log

Added:
    
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java
    
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceUndoManager.java
    
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
Removed:
    
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/DefaultPathManager.java
    
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/PathManager.java
Modified:
    
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java

Added: 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java?view=auto&rev=558857
==============================================================================
--- 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java
 (added)
+++ 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceManager.java
 Mon Jul 23 13:54:15 2007
@@ -0,0 +1,204 @@
+/*
+ * 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.commons.transaction.file;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.transaction.resource.ResourceException;
+import org.apache.commons.transaction.resource.ResourceManager;
+import org.apache.commons.transaction.resource.StreamableResource;
+import org.apache.commons.transaction.util.FileHelper;
+
+public class FileResourceManager implements 
ResourceManager<StreamableResource> {
+
+    private Log logger = LogFactory.getLog(getClass());
+
+    protected String rootPath;
+
+    public FileResourceManager(String rootPath) {
+        this.rootPath = rootPath;
+    }
+
+    public StreamableResource getResource(String path) throws 
ResourceException {
+        return new FileResource(path);
+    }
+
+    public String getRootPath() {
+        return rootPath;
+    }
+
+    protected static class FileResource implements StreamableResource {
+
+        protected File file;
+
+        public FileResource(String path) {
+            this.file = new File(path);
+        }
+
+        public FileResource(File file) {
+            this.file = file;
+        }
+
+        public void createAsDirectory() throws ResourceException {
+            if (!file.mkdirs()) {
+                throw new ResourceException("Could not create directory");
+            }
+
+        }
+
+        public void createAsFile() throws ResourceException {
+            try {
+                if (!file.createNewFile()) {
+                    throw new ResourceException("Could not create file");
+                }
+            } catch (IOException e) {
+                throw new ResourceException(e);
+            }
+        }
+
+        public void delete() throws ResourceException {
+            if (!file.delete())
+                throw new ResourceException("Could not create file");
+
+        }
+
+        public boolean exists() {
+            return file.exists();
+        }
+
+        public List<StreamableResource> getChildren() throws ResourceException 
{
+            List<StreamableResource> result = new 
ArrayList<StreamableResource>();
+            File[] files = file.listFiles();
+            for (File file : files) {
+                result.add(new FileResource(file));
+            }
+            return result;
+        }
+
+        public StreamableResource getParent() throws ResourceException {
+            // FIXME: Is reasonable, but would require refernce to enclosing 
class
+            /*
+            if (getPath().equals(getRootPath()))
+                return null;
+                */
+            File parent = file.getParentFile();
+            return new FileResource(parent);
+        }
+
+        public String getPath() throws ResourceException {
+            try {
+                return file.getCanonicalPath();
+            } catch (IOException e) {
+                throw new ResourceException(e);
+            }
+        }
+
+        public boolean isDirectory() {
+            return file.isDirectory();
+        }
+
+        public boolean isFile() {
+            return file.isFile();
+        }
+
+        public void move(String destinationpath) throws ResourceException {
+            File destination = new File(destinationpath);
+            try {
+                FileHelper.moveUsingNIO(file, destination);
+            } catch (IOException e) {
+                throw new ResourceException(e);
+            }
+        }
+
+        public void copy(String destinationpath) throws ResourceException {
+            File destination = new File(destinationpath);
+            try {
+                FileHelper.copyUsingNIO(file, destination);
+            } catch (IOException e) {
+                throw new ResourceException(e);
+            }
+        }
+
+        public InputStream readStream() throws ResourceException {
+            try {
+                FileInputStream is = new FileInputStream(file);
+                return is;
+            } catch (IOException e) {
+                throw new ResourceException(e);
+            }
+        }
+
+        public OutputStream writeStream(boolean append) throws 
ResourceException {
+            try {
+                FileOutputStream os = new FileOutputStream(file);
+                return os;
+            } catch (IOException e) {
+                throw new ResourceException(e);
+            }
+        }
+
+        public void removeProperty(String name) {
+            throw new UnsupportedOperationException("You can not remove 
properties from files!");
+        }
+
+        public void setProperty(String name, Object newValue) {
+            throw new UnsupportedOperationException("You can not set 
properties on files!");
+        }
+
+        public Object getProperty(String name) {
+            if (name.equals("lastModified")) {
+                return file.lastModified();
+            }
+            if (name.equals("length")) {
+                return file.length();
+            }
+            return null;
+        }
+
+        // XXX no op, only way to lock is using FileChannel#lock() and
+        // FileChannel#tryLock()
+        public boolean tryReadLock() {
+            return true;
+        }
+
+        // XXX no op, only way to lock is using FileChannel#lock() and
+        // FileChannel#tryLock()
+        public boolean tryWriteLock() {
+            return true;
+        }
+
+        // XXX no op, only way to lock is using FileChannel#lock() and
+        // FileChannel#tryLock()
+        public void readLock() {
+        }
+
+        // XXX no op, only way to lock is using FileChannel#lock() and
+        // FileChannel#tryLock()
+        public void writeLock() {
+        }
+
+    }
+}

Added: 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceUndoManager.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceUndoManager.java?view=auto&rev=558857
==============================================================================
--- 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceUndoManager.java
 (added)
+++ 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/FileResourceUndoManager.java
 Mon Jul 23 13:54:15 2007
@@ -0,0 +1,31 @@
+package org.apache.commons.transaction.file;
+
+import java.io.File;
+
+public interface FileResourceUndoManager {
+
+    public enum Code {
+        CREATED_DIRECTORY, CREATED_FILE, DELETED_DIRECTORY, MOVED, COPIED, 
CONTENT_CHANGED, PROPERTY_CHANGED
+    }
+    
+    public void startRecord();
+
+    public void undoRecord();
+
+    public void forgetRecord();
+
+    public void recordCopy(File from, File to);
+
+    public void recordCreateAsDirectory(File directory);
+
+    public void recordCreateAsFile(File file);
+
+    public void recordDelete(File file);
+
+    public void recordMove(File from, File to);
+
+    public void recordChangeProperty(File file, String name, Object oldValue);
+
+    public void recordChangeContent(File file);
+
+}

Added: 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java?view=auto&rev=558857
==============================================================================
--- 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
 (added)
+++ 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/MemoryUndoManager.java
 Mon Jul 23 13:54:15 2007
@@ -0,0 +1,136 @@
+package org.apache.commons.transaction.file;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.transaction.util.FileHelper;
+
+// TODO: memory version to be serialized to XML using JAXB
+public class MemoryUndoManager implements FileResourceUndoManager {
+
+    private Log logger = LogFactory.getLog(getClass());
+    protected ThreadLocal<List<UndoRecord>> localRecords = new 
ThreadLocal<List<UndoRecord>>();
+
+    
+    public void recordChangeContent(File file) {
+        UndoRecord record = new UndoRecord();
+        record.code = Code.CONTENT_CHANGED;
+        record.file = file;
+        try {
+            record.oldConent = new 
ByteArrayInputStream(FileHelper.readInto(file));
+        } catch (IOException e) {
+            logger.fatal("Could not store changed content for "+file);
+            // FIXME: This really should cause an error
+        }
+        storeRecord(record);
+    }
+
+    public void recordCopy(File from, File to) {
+        if (to.exists()) {
+            recordChangeContent(to);
+        }
+        UndoRecord record = new UndoRecord();
+        record.code = Code.COPIED;
+        record.file = from;
+        record.to = to;
+        storeRecord(record);
+    }
+
+    public void recordCreateAsDirectory(File directory) {
+        UndoRecord record = new UndoRecord();
+        record.code = Code.CREATED_DIRECTORY;
+        record.file = directory;
+        storeRecord(record);
+    }
+
+    public void recordCreateAsFile(File file) {
+        UndoRecord record = new UndoRecord();
+        record.code = Code.CREATED_FILE;
+        record.file = file;
+        storeRecord(record);
+    }
+
+    public void recordDelete(File file) {
+        if (file.isFile()) {
+            recordChangeContent(file);
+        } else {
+            UndoRecord record = new UndoRecord();
+            record.code = Code.DELETED_DIRECTORY;
+            record.file = file;
+            storeRecord(record);
+        }
+    }
+
+    public void recordMove(File from, File to) {
+        if (to.exists()) {
+            recordChangeContent(to);
+        }
+        UndoRecord record = new UndoRecord();
+        record.code = Code.MOVED;
+        record.file = from;
+        record.to = to;
+        storeRecord(record);
+    }
+
+    public void recordChangeProperty(File file, String name, Object oldValue) {
+        UndoRecord record = new UndoRecord();
+        record.code = Code.PROPERTY_CHANGED;
+        record.file = file;
+        record.propertyName = name;
+        record.oldValue = oldValue;
+        storeRecord(record);
+    }
+
+    public void startRecord() {
+        localRecords.set(new ArrayList<UndoRecord>());
+    }
+
+    public void undoRecord() {
+        List<UndoRecord> records = new 
ArrayList<UndoRecord>(localRecords.get());
+        Collections.reverse(records);
+        for (UndoRecord record : records) {
+            record.undo();
+        }
+    }
+
+    public void forgetRecord() {
+        localRecords.set(null);
+    }
+
+    protected void storeRecord(UndoRecord record) {
+        List<UndoRecord> records = localRecords.get();
+        records.add(record);
+    }
+
+    protected static class UndoRecord {
+        Code code;
+
+        File file;
+
+        File to;
+
+        String propertyName;
+
+        Object oldValue;
+
+        InputStream oldConent;
+
+        // FIXME: Needs implementation (not that hard)
+        // ugly c-style - who cares?
+        public void undo() {
+            // TODO
+            switch (code) {
+            
+            }
+            
+        }
+    }
+
+}

Modified: 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java?view=diff&rev=558857&r1=558856&r2=558857
==============================================================================
--- 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java
 (original)
+++ 
jakarta/commons/proper/transaction/branches/TRANSACTION_2/src/java/org/apache/commons/transaction/file/TxFileResourceManager.java
 Mon Jul 23 13:54:15 2007
@@ -18,82 +18,46 @@
 
 import java.io.Closeable;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.commons.transaction.AbstractTransactionalResourceManager;
-import org.apache.commons.transaction.TransactionalResourceManager;
+import org.apache.commons.transaction.ManageableResourceManager;
 import 
org.apache.commons.transaction.AbstractTransactionalResourceManager.AbstractTxContext;
+import org.apache.commons.transaction.file.FileResourceManager.FileResource;
 import org.apache.commons.transaction.locking.LockException;
+import org.apache.commons.transaction.resource.ResourceException;
 import org.apache.commons.transaction.resource.ResourceManager;
 import org.apache.commons.transaction.resource.StreamableResource;
-import org.apache.commons.transaction.util.FileHelper;
 
 public class TxFileResourceManager extends
         
AbstractTransactionalResourceManager<TxFileResourceManager.FileTxContext> 
implements
-        ResourceManager<StreamableResource> {
+        ManageableResourceManager, ResourceManager<StreamableResource> {
 
     private Log logger = LogFactory.getLog(getClass());
 
     protected String contextFileName = "transaction.log";
 
-    protected PathManager idMapper;
+    protected String rootPath;
 
-    protected TransactionalResourceManager tm;
+    protected FileResourceManager wrapped;
 
-    public static void applyDeletes(File removeDir, File targetDir, File 
rootDir)
-            throws IOException {
-        if (removeDir.isDirectory() && targetDir.isDirectory()) {
-            File[] files = removeDir.listFiles();
-            for (int i = 0; i < files.length; i++) {
-                File removeFile = files[i];
-                File targetFile = new File(targetDir, removeFile.getName());
-                if (!removeFile.isDirectory()) {
-                    if (targetFile.exists()) {
-                        if (!targetFile.delete()) {
-                            throw new IOException("Could not delete file " + 
removeFile.getName()
-                                    + " in directory targetDir");
-                        }
-                    } else if (!targetFile.isFile()) {
-                        // this is likely a dangling link
-                        targetFile.delete();
-                    }
-                    // indicate, this has been done
-                    removeFile.delete();
-                } else {
-                    applyDeletes(removeFile, targetFile, rootDir);
-                }
-                // delete empty target directories, except root dir
-                if (!targetDir.equals(rootDir) && targetDir.list().length == 
0) {
-                    targetDir.delete();
-                }
-            }
-        }
-    }
+    protected FileResourceUndoManager undoManager;
 
-    public String getContextFileName() {
-        return contextFileName;
+    public TxFileResourceManager(String rootPath) {
+        this.rootPath = rootPath;
+        wrapped = new FileResourceManager(rootPath);
     }
 
     public void setContextFileName(String contextFile) {
         this.contextFileName = contextFile;
     }
 
-    public PathManager getIdMapper() {
-        return idMapper;
-    }
-
-    public void setIdMapper(PathManager idMapper) {
-        this.idMapper = idMapper;
-    }
-
     @Override
     protected FileTxContext createContext() {
         return new FileTxContext();
@@ -101,91 +65,175 @@
 
     // TODO resource manager needs to forward requests to this context, locking
     // will happen here
-    public class FileTxContext extends AbstractTxContext implements 
FileResourceManager {
+    // FIXME
+    // needs
+    // - custom commit / rollback
+    // - proper resource tracking
+    public class FileTxContext extends AbstractTxContext implements
+            ResourceManager<StreamableResource> {
 
         // list of streams participating in this tx
         private Collection<Closeable> openStreams = new ArrayList<Closeable>();
 
         public FileTxContext() {
-            super();
-            String changeDir = getIdMapper().getChangeBaseDir();
-            String deleteDir = getIdMapper().getDeleteBaseDir();
-
-            new File(changeDir).mkdirs();
-            new File(deleteDir).mkdirs();
         }
 
-        public void commit() {
-            super.commit();
-            String changeDir = getIdMapper().getChangeBaseDir();
-            String deleteDir = getIdMapper().getDeleteBaseDir();
-            String storeDir = getIdMapper().getStoreDir();
-
-            try {
-                applyDeletes(new File(deleteDir), new File(storeDir), new 
File(storeDir));
-                FileHelper.moveRec(new File(changeDir), new File(storeDir));
-            } catch (IOException e) {
-                throw new LockException(LockException.Code.COMMIT_FAILED, e);
-            }
+        protected void registerStream(Closeable stream) {
+            openStreams.add(stream);
         }
 
-        public void cleanUp() {
-            String baseDir = getIdMapper().getTransactionBaseDir();
-            FileHelper.removeRec(new File(baseDir));
+        public StreamableResource getResource(String path) throws 
ResourceException {
+            return new TxFileResource(path);
         }
 
-        public boolean copy(String sourceId, String destinationId) throws 
IOException,
-                LockException {
-            // TODO Auto-generated method stub
-            return false;
+        public String getRootPath() {
+            return TxFileResourceManager.this.getRootPath();
         }
 
-        public boolean createDir(String id) throws IOException, LockException {
-            // TODO Auto-generated method stub
-            return false;
-        }
+        // FIXME needs custom implementations
+        // Details:
+        // - Hierarchical locking
+        // - Calls to configured undo manager
+        protected class TxFileResource extends FileResource {
 
-        public boolean move(String sourceId, String destinationId) throws 
IOException,
-                LockException {
-            // TODO Auto-generated method stub
-            return false;
-        }
+            public TxFileResource(File file) {
+                super(file);
+            }
 
-        public InputStream read(String id) throws IOException, LockException {
-            readLock(id);
-            String path = getIdMapper().getPathForRead(id);
-            InputStream is = new FileInputStream(new File(path));
-            registerStream(is);
-            return is;
-        }
+            public TxFileResource(String path) {
+                super(path);
+            }
 
-        public OutputStream write(String id) throws IOException {
-            writeLock(id);
-            String path = getIdMapper().getPathForRead(id);
-            return new FileOutputStream(new File(path));
-        }
+            public void copy(String destinationpath) throws ResourceException {
+                super.copy(destinationpath);
+            }
 
-        public boolean remove(String id) throws IOException {
-            writeLock(id);
-            String path = getIdMapper().getPathForDelete(id);
-            return new File(path).delete();
-        }
+            public void createAsDirectory() throws ResourceException {
+                super.createAsDirectory();
+            }
 
-        public boolean create(String id) throws IOException {
-            writeLock(id);
-            String path = getIdMapper().getPathForDelete(id);
-            return new File(path).createNewFile();
-        }
+            public void createAsFile() throws ResourceException {
+                super.createAsFile();
+            }
+
+            public void delete() throws ResourceException {
+                super.delete();
+            }
+
+            public boolean exists() {
+                return super.exists();
+            }
+
+            public List<StreamableResource> getChildren() throws 
ResourceException {
+                return super.getChildren();
+            }
+
+            public StreamableResource getParent() throws ResourceException {
+                return super.getParent();
+            }
+
+            public String getPath() throws ResourceException {
+                return super.getPath();
+            }
+
+            public Object getProperty(String name) {
+                return super.getProperty(name);
+            }
+
+            public boolean isDirectory() {
+                return super.isDirectory();
+            }
+
+            public boolean isFile() {
+                return super.isFile();
+            }
+
+            public void move(String destinationpath) throws ResourceException {
+                super.move(destinationpath);
+            }
+
+            public InputStream readStream() throws ResourceException {
+                return super.readStream();
+            }
+
+            public void removeProperty(String name) {
+                super.removeProperty(name);
+            }
+
+            public void setProperty(String name, Object newValue) {
+                super.setProperty(name, newValue);
+            }
+
+            public boolean tryReadLock() {
+                try {
+                    return getLm().tryLock(getName(), getPath(), false);
+                } catch (ResourceException e) {
+                    // FIXME: ouch!
+                    throw new LockException(e);
+                }
+            }
+
+            public boolean tryWriteLock() {
+                try {
+                    return getLm().tryLock(getName(), getPath(), true);
+                } catch (ResourceException e) {
+                    // FIXME: ouch!
+                    throw new LockException(e);
+                }
+            }
+
+            public void readLock() {
+                try {
+                    getLm().lock(getName(), getPath(), false);
+                } catch (ResourceException e) {
+                    // FIXME: ouch!
+                    throw new LockException(e);
+                }
+                super.readLock();
+            }
+
+            public void writeLock() {
+                try {
+                    getLm().lock(getName(), getPath(), true);
+                } catch (ResourceException e) {
+                    // FIXME: ouch!
+                    throw new LockException(e);
+                }
+                super.writeLock();
+            }
+
+            public OutputStream writeStream(boolean append) throws 
ResourceException {
+                return super.writeStream(append);
+            }
 
-        public boolean removeDir(String id) throws IOException, LockException {
-            // TODO Auto-generated method stub
-            return false;
         }
+    }
 
-        protected void registerStream(Closeable stream) {
-            openStreams.add(stream);
+    @Override
+    public boolean commitCanFail() {
+        return false;
+    }
+
+    public StreamableResource getResource(String path) throws 
ResourceException {
+        FileTxContext context = getActiveTx();
+        if (context != null) {
+            return context.getResource(path);
+        } else {
+            return wrapped.getResource(path);
         }
 
+    }
+
+    public String getRootPath() {
+        return rootPath;
+    }
+
+    public FileResourceUndoManager getUndoManager() {
+        return undoManager;
+    }
+
+    public void setUndoManager(FileResourceUndoManager undoManager) {
+        this.undoManager = undoManager;
     }
 
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to