diff --git a/source/java/org/alfresco/repo/avm/AVMRemoteInputStream.java b/source/java/org/alfresco/repo/avm/AVMRemoteInputStream.java index a1bec72069..991d36ab84 100644 --- a/source/java/org/alfresco/repo/avm/AVMRemoteInputStream.java +++ b/source/java/org/alfresco/repo/avm/AVMRemoteInputStream.java @@ -86,10 +86,7 @@ public class AVMRemoteInputStream extends InputStream { return -1; } - for (int i = 0; i < buff.length; i++) - { - b[off + i] = buff[i]; - } + System.arraycopy(buff, 0, b, off, buff.length); return buff.length; } catch (Exception e) diff --git a/source/java/org/alfresco/repo/avm/AVMRemoteOutputStream.java b/source/java/org/alfresco/repo/avm/AVMRemoteOutputStream.java index e39debd580..4744fd8b1a 100644 --- a/source/java/org/alfresco/repo/avm/AVMRemoteOutputStream.java +++ b/source/java/org/alfresco/repo/avm/AVMRemoteOutputStream.java @@ -85,10 +85,7 @@ public class AVMRemoteOutputStream extends OutputStream else { byte [] buff = new byte[len]; - for (int i = 0; i < len; i++) - { - buff[i] = b[i + off]; - } + System.arraycopy(b, off, buff, 0, len); fAVMRemote.writeOutput(fHandle, buff, len); } } diff --git a/source/java/org/alfresco/repo/avm/AVMRepository.java b/source/java/org/alfresco/repo/avm/AVMRepository.java index b9a508d570..99be8f6d46 100644 --- a/source/java/org/alfresco/repo/avm/AVMRepository.java +++ b/source/java/org/alfresco/repo/avm/AVMRepository.java @@ -2185,7 +2185,7 @@ public class AVMRepository { throw new AVMNotFoundException("Store not found."); } - fLookupCache.onWrite(pathParts[0]); + fLookupCache.onDelete(pathParts[0]); Lookup lPath = store.lookup(-1, pathParts[1], true, false); AVMNode node = lPath.getCurrentNode(); if (node == null) diff --git a/source/java/org/alfresco/repo/avm/LookupCache.java b/source/java/org/alfresco/repo/avm/LookupCache.java index 6358d1c112..a24d541f87 100644 --- a/source/java/org/alfresco/repo/avm/LookupCache.java +++ b/source/java/org/alfresco/repo/avm/LookupCache.java @@ -268,7 +268,8 @@ public class LookupCache for (Map.Entry entry : fCache.entrySet()) { if ((entry.getKey().getStoreName().equals(storeName) && - !entry.getKey().isWrite()) || entry.getValue().isLayered()) + !entry.getKey().isWrite()) || + (!entry.getKey().isWrite() && entry.getValue().isLayered())) { toDelete.add(entry.getKey()); } diff --git a/source/java/org/alfresco/repo/avm/clt/AVMCltBase.java b/source/java/org/alfresco/repo/avm/clt/AVMCltBase.java new file mode 100644 index 0000000000..f9254bbd24 --- /dev/null +++ b/source/java/org/alfresco/repo/avm/clt/AVMCltBase.java @@ -0,0 +1,133 @@ +/** + * + */ +package org.alfresco.repo.avm.clt; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.alfresco.repo.avm.AVMRemote; +import org.alfresco.service.cmr.avmsync.AVMSyncService; +import org.alfresco.util.Pair; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +/** + * This is the base class for AVM clts. + * @author britt + */ +public abstract class AVMCltBase +{ + /** + * The instance of the remote interface. + */ + protected AVMRemote fAVMRemote; + + /** + * The instance of the remote sync service interface. + */ + protected AVMSyncService fAVMSyncService; + + /** + * The ApplicationContext. + */ + protected ConfigurableApplicationContext fContext; + + /** + * Construct a new one. This takes care of instantiating + * the application context and grabs references to the + * services. + * @param args The program arguments. + */ + protected AVMCltBase() + { + fContext = new ClassPathXmlApplicationContext("avm-clt-context.xml"); + fAVMRemote = (AVMRemote)fContext.getBean("avmRemote"); + fAVMSyncService = (AVMSyncService)fContext.getBean("avmSyncService"); + } + + /** + * All clts go through this call. This parses the arguments, exits if + * there are any errors and then passes the broken flags and arguments + * to the run method of the derived clt. + * @param args The raw command line arguments. + * @param flagDefs The definition of what flags to accept and their + * arities. + * @param minArgs The minimum number of actual arguments expected. + * @param usageMessage The message that should be printed if there is a + * syntax error. + */ + public void exec(String [] args, + Object [] flagDefs, + int minArgs, + String usageMessage) + { + Map flagArgs = new HashMap(); + Map> flagValues = new HashMap>(); + List actualArgs = new ArrayList(); + // Convert the flag definitions into a convenient form. + for (int i = 0; i < flagDefs.length / 2; i++) + { + flagArgs.put((String)flagDefs[i * 2], (Integer)flagDefs[i * 2 + 1]); + } + // Walk through the raw command line arguments. + int pos = 0; + while (pos < args.length) + { + // If the argument begins with "-" then this could be a + // flag. + if (args[pos].startsWith("-")) + { + // If the argument is one of the accepted flags then it's + // a flag. + if (flagArgs.containsKey(args[pos])) + { + String flag = args[pos]; + pos++; + int count = flagArgs.get(flag); + // Check for too few arguments + if (args.length - pos < count) + { + usage(usageMessage); + } + // Stuff the parsed flag away. + List flArgs = new ArrayList(); + for (int i = 0; i < count; i++) + { + flArgs.add(args[pos + i]); + } + flagValues.put(flag, flArgs); + pos += count; + continue; + } + } + // Otherwise its just a plain old arg. + actualArgs.add(args[pos]); + pos++; + } + // Check for too few arguments. + if (actualArgs.size() < minArgs) + { + usage(usageMessage); + } + // Do the work. + run(flagValues, actualArgs); + // Cleanup. + fContext.close(); + } + + /** + * Handle syntax error by exiting. + * @param usageMessage The message to print. + */ + protected void usage(String usageMessage) + { + System.err.println(usageMessage); + fContext.close(); + System.exit(1); + } + + protected abstract void run(Map> flags, List args); +}