use of org.alfresco.filesys.repo.rules.operations.MoveFileOperation in project alfresco-repository by Alfresco.
the class ScenarioDoubleRenameShuffleInstance method evaluate.
/**
* Evaluate the next operation
* @param operation
*/
public Command evaluate(Operation operation) {
/**
* Anti-pattern : timeout
*/
Date now = new Date();
if (now.getTime() > startTime.getTime() + getTimeout()) {
if (logger.isDebugEnabled()) {
logger.debug("Instance timed out");
}
isComplete = true;
return null;
}
switch(internalState) {
case NONE:
/**
* Looking for first rename Y(middle) to Z(end)
*/
if (operation instanceof RenameFileOperation) {
if (logger.isDebugEnabled()) {
logger.debug("Got first rename - tracking rename: " + operation);
}
RenameFileOperation r = (RenameFileOperation) operation;
fileMiddle = r.getFrom();
fileEnd = r.getTo();
String[] paths = FileName.splitPath(r.getFromPath());
folderMiddle = paths[0];
String[] paths2 = FileName.splitPath(r.getToPath());
folderEnd = paths2[0];
internalState = InternalState.RENAME1;
return new RenameFileCommand(r.getFrom(), r.getTo(), r.getRootNodeRef(), r.getFromPath(), r.getToPath());
} else {
// anything else bomb out
if (logger.isDebugEnabled()) {
logger.debug("State error, expected a RENAME");
}
isComplete = true;
}
case RENAME1:
/**
* Looking for the second of two renames X(createName) to Y(middle) to Z(end)
*/
if (operation instanceof RenameFileOperation) {
if (logger.isDebugEnabled()) {
logger.debug("Tracking rename: " + operation);
}
RenameFileOperation r = (RenameFileOperation) operation;
// Now see if this rename makes a pair
if (fileMiddle.equalsIgnoreCase(r.getTo())) {
if (logger.isDebugEnabled()) {
logger.debug("Got second rename");
}
fileFrom = r.getFrom();
/**
* This shuffle reverses the rename out of the way and then copies the
* content only. Finally it moves the temp file into place for the subsequent
* delete.
* a) Rename Z to Y (Reverse previous move)
* b) Copy Content from X to Y
* c) Rename X to Z (move temp file out to old location)
*/
if (logger.isDebugEnabled()) {
logger.debug("Go and shuffle! fromName:" + fileFrom + " middle: " + fileMiddle + " end: " + fileEnd);
}
String[] paths = FileName.splitPath(r.getFromPath());
String oldFolder = paths[0];
ArrayList<Command> commands = new ArrayList<Command>();
RenameFileCommand r1 = new RenameFileCommand(fileEnd, fileMiddle, r.getRootNodeRef(), oldFolder + "\\" + fileEnd, oldFolder + "\\" + fileMiddle);
commands.add(r1);
CopyContentCommand copyContent = new CopyContentCommand(fileFrom, fileMiddle, r.getRootNodeRef(), oldFolder + "\\" + fileFrom, oldFolder + "\\" + fileMiddle);
commands.add(copyContent);
if (deleteBackup) {
logger.debug("deleteBackup option turned on");
DeleteFileCommand d1 = new DeleteFileCommand(oldFolder, r.getRootNodeRef(), oldFolder + "\\" + fileFrom);
commands.add(d1);
} else {
RenameFileCommand r2 = new RenameFileCommand(fileFrom, fileEnd, r.getRootNodeRef(), oldFolder + "\\" + fileFrom, oldFolder + "\\" + fileEnd);
commands.add(r2);
}
/**
* TODO - we may need to copy a new node for the backup and delete the temp node.
* It depends if we care about the contents of the Backup file.
*/
isComplete = true;
return new CompoundCommand(commands);
}
}
if (operation instanceof MoveFileOperation) {
if (logger.isDebugEnabled()) {
logger.info("Tracking rename: " + operation);
}
MoveFileOperation r = (MoveFileOperation) operation;
// Now see if this rename makes a pair
if (fileMiddle.equalsIgnoreCase(r.getTo())) {
if (logger.isDebugEnabled()) {
logger.debug("Got second rename");
}
fileFrom = r.getFrom();
/**
* This shuffle reverses the rename out of the way and then copies the
* content only. Finally it moves the temp file into place for the subsequent
* delete.
* a) Rename Z to Y (Reverse previous move)
* b) Copy Content from X to Y
* c) Rename X to Z (move temp file out to old location)
*/
if (logger.isDebugEnabled()) {
logger.debug("Go and shuffle! fromName:" + fileFrom + " middle: " + fileMiddle + " end: " + fileEnd);
}
String[] paths = FileName.splitPath(r.getFromPath());
String oldFolder = paths[0];
ArrayList<Command> commands = new ArrayList<Command>();
RenameFileCommand r1 = new RenameFileCommand(fileEnd, fileMiddle, r.getRootNodeRef(), folderEnd + "\\" + fileEnd, folderMiddle + "\\" + fileMiddle);
commands.add(r1);
CopyContentCommand copyContent = new CopyContentCommand(fileFrom, fileMiddle, r.getRootNodeRef(), oldFolder + "\\" + fileFrom, folderMiddle + "\\" + fileMiddle);
commands.add(copyContent);
if (deleteBackup) {
logger.debug("deleteBackup option turned on");
DeleteFileCommand d1 = new DeleteFileCommand(oldFolder, r.getRootNodeRef(), oldFolder + "\\" + fileFrom);
commands.add(d1);
} else {
MoveFileCommand m1 = new MoveFileCommand(fileFrom, fileEnd, r.getRootNodeRef(), oldFolder + "\\" + fileFrom, folderEnd + "\\" + fileEnd, isMoveAsSystem());
commands.add(m1);
}
/**
* TODO - we may need to copy a new node for the backup and delete the temp node.
* It depends if we care about the contents of the Backup file.
*/
isComplete = true;
return new CompoundCommand(commands);
} else {
if ((interimPattern != null)) {
// ALF-16257: temporary Word file moved from .TemporaryItems
Matcher m = interimPattern.matcher(r.getFromPath());
if (m.matches() && r.getFrom().equals(r.getTo())) {
if (logger.isDebugEnabled()) {
logger.debug("Got system move from temporary folder: " + r.getFrom() + " to " + r.getToPath());
}
return new MoveFileCommand(r.getFrom(), r.getTo(), r.getRootNodeRef(), r.getFromPath(), r.getToPath(), true);
}
}
}
}
break;
}
return null;
}
use of org.alfresco.filesys.repo.rules.operations.MoveFileOperation in project alfresco-repository by Alfresco.
the class ScenarioLockedDeleteShuffleInstance method evaluate.
/**
* Evaluate the next operation
* @param operation
*/
public Command evaluate(Operation operation) {
/**
* Anti-pattern for all states - delete the lock file
*/
if (lockName != null) {
if (operation instanceof DeleteFileOperation) {
DeleteFileOperation d = (DeleteFileOperation) operation;
if (d.getName().equals(lockName)) {
logger.debug("Anti-pattern : Lock file deleted");
isComplete = true;
return null;
}
}
}
/**
* Anti-pattern : timeout
*/
Date now = new Date();
if (now.getTime() > startTime.getTime() + getTimeout()) {
if (logger.isDebugEnabled()) {
logger.debug("Instance timed out lockName:" + lockName);
isComplete = true;
return null;
}
}
switch(internalState) {
case NONE:
// Looking for a create transition
if (operation instanceof CreateFileOperation) {
CreateFileOperation c = (CreateFileOperation) operation;
this.lockName = c.getName();
if (logger.isDebugEnabled()) {
logger.debug("entering LOCKED state: " + lockName);
}
internalState = InternalState.LOCKED;
return null;
} else {
// anything else bomb out
if (logger.isDebugEnabled()) {
logger.debug("State error, expected a CREATE");
}
isComplete = true;
}
break;
case LOCKED:
/**
* Looking for target file being deleted
*
* Need to intervene and replace delete with a rename to temp file.
*/
if (operation instanceof DeleteFileOperation) {
DeleteFileOperation d = (DeleteFileOperation) operation;
if (logger.isDebugEnabled()) {
logger.debug("entering DELETE_SUBSTITUTED state: " + lockName);
}
String tempName = ".shuffle" + d.getName();
deletes.put(d.getName(), tempName);
String[] paths = FileName.splitPath(d.getPath());
String currentFolder = paths[0];
RenameFileCommand r1 = new RenameFileCommand(d.getName(), tempName, d.getRootNodeRef(), d.getPath(), currentFolder + "\\" + tempName);
internalState = InternalState.DELETE_SUBSTITUTED;
return r1;
}
case DELETE_SUBSTITUTED:
/**
* Looking for a move operation of the deleted file
*/
if (operation instanceof MoveFileOperation) {
MoveFileOperation m = (MoveFileOperation) operation;
String targetFile = m.getTo();
if (deletes.containsKey(targetFile)) {
String tempName = deletes.get(targetFile);
String[] paths = FileName.splitPath(m.getToPath());
String currentFolder = paths[0];
/**
* This is where the scenario fires.
* a) Rename the temp file back to the targetFile
* b) Copy content from moved file
* c) Delete rather than move file
*/
logger.debug("scenario fires");
ArrayList<Command> commands = new ArrayList<Command>();
RenameFileCommand r1 = new RenameFileCommand(tempName, targetFile, m.getRootNodeRef(), currentFolder + "\\" + tempName, m.getToPath());
CopyContentCommand copyContent = new CopyContentCommand(m.getFrom(), targetFile, m.getRootNodeRef(), m.getFromPath(), m.getToPath());
DeleteFileCommand d1 = new DeleteFileCommand(m.getFrom(), m.getRootNodeRef(), m.getFromPath());
commands.add(r1);
commands.add(copyContent);
commands.add(d1);
logger.debug("Scenario complete");
isComplete = true;
return new CompoundCommand(commands);
}
}
case MOVED:
}
return null;
}
use of org.alfresco.filesys.repo.rules.operations.MoveFileOperation in project alfresco-repository by Alfresco.
the class ScenarioTempDeleteShuffle method createInstance.
@Override
public ScenarioInstance createInstance(final EvaluatorContext ctx, Operation operation) {
/**
* This scenario is triggered by a delete of a file matching
* the pattern
*/
if (operation instanceof CreateFileOperation) {
CreateFileOperation c = (CreateFileOperation) operation;
// check whether file is below .TemporaryItems
String path = c.getPath();
// if path contains .TemporaryItems
Matcher d = tempDirPattern.matcher(path);
if (d.matches()) {
logger.debug("pattern matches temp dir folder so this is a new create in a temp dir");
Matcher m = pattern.matcher(c.getName());
if (m.matches()) {
// and how to lock - since we are already have one lock on the scenarios/folder here
// this is a potential deadlock and synchronization bottleneck
Map<String, String> createdTempFiles = (Map<String, String>) ctx.getSessionState().get(SCENARIO_KEY);
if (createdTempFiles == null) {
synchronized (ctx.getSessionState()) {
logger.debug("created new temp file map and added it to the session state");
createdTempFiles = (Map<String, String>) ctx.getSessionState().get(SCENARIO_KEY);
if (createdTempFiles == null) {
createdTempFiles = Collections.synchronizedMap(new MaxSizeMap<String, String>(5, false));
ctx.getSessionState().put(SCENARIO_KEY, createdTempFiles);
}
}
}
createdTempFiles.put(c.getName(), c.getName());
// TODO - Return a different scenario instance here ???
// So it can time out and have anti-patterns etc?
}
}
}
if (operation instanceof MoveFileOperation) {
MoveFileOperation mf = (MoveFileOperation) operation;
// check whether file is below .TemporaryItems
String path = mf.getFromPath();
// if path contains .TemporaryItems
Matcher d = tempDirPattern.matcher(path);
if (d.matches()) {
logger.debug("pattern matches temp dir folder so this is a new create in a temp dir");
Matcher m = pattern.matcher(mf.getFrom());
if (m.matches()) {
// and how to lock - since we are already have one lock on the scenarios/folder here
// this is a potential deadlock and synchronization bottleneck
Map<String, String> createdTempFiles = (Map<String, String>) ctx.getSessionState().get(SCENARIO_KEY);
if (createdTempFiles == null) {
synchronized (ctx.getSessionState()) {
logger.debug("created new temp file map and added it to the session state");
createdTempFiles = (Map<String, String>) ctx.getSessionState().get(SCENARIO_KEY);
if (createdTempFiles == null) {
createdTempFiles = Collections.synchronizedMap(new MaxSizeMap<String, String>(5, false));
ctx.getSessionState().put(SCENARIO_KEY, createdTempFiles);
}
}
}
createdTempFiles.remove(mf.getFrom());
// TODO - Return a different scenario instance here ???
// So it can time out and have anti-patterns etc?
}
}
}
if (operation instanceof DeleteFileOperation) {
DeleteFileOperation c = (DeleteFileOperation) operation;
Matcher m = pattern.matcher(c.getName());
if (m.matches()) {
Map<String, String> createdTempFiles = (Map<String, String>) ctx.getSessionState().get(SCENARIO_KEY);
if (createdTempFiles != null) {
if (createdTempFiles.containsKey(c.getName())) {
if (logger.isDebugEnabled()) {
logger.debug("New Scenario Temp Delete Shuffle Instance:" + c.getName());
}
ScenarioTempDeleteShuffleInstance instance = new ScenarioTempDeleteShuffleInstance();
instance.setTimeout(timeout);
instance.setRanking(ranking);
return instance;
}
}
}
}
// No not interested.
return null;
}
use of org.alfresco.filesys.repo.rules.operations.MoveFileOperation in project alfresco-repository by Alfresco.
the class ScenarioTempDeleteShuffleInstance method evaluate.
/**
* Evaluate the next operation
* @param operation
*/
public Command evaluate(Operation operation) {
/**
* Anti-pattern : timeout
*/
Date now = new Date();
if (now.getTime() > startTime.getTime() + getTimeout()) {
if (logger.isDebugEnabled()) {
logger.debug("Instance timed out lockName:" + lockName);
isComplete = true;
return null;
}
}
switch(internalState) {
case NONE:
/**
* Looking for target file being deleted
*
* Need to intervene and replace delete with a rename to temp file.
*/
if (operation instanceof DeleteFileOperation) {
DeleteFileOperation d = (DeleteFileOperation) operation;
if (logger.isDebugEnabled()) {
logger.debug("entering DELETE_SUBSTITUTED state: " + lockName);
}
String tempName = ".shuffle" + d.getName();
deletes.put(d.getName(), tempName);
String[] paths = FileName.splitPath(d.getPath());
String currentFolder = paths[0];
RenameFileCommand r1 = new RenameFileCommand(d.getName(), tempName, d.getRootNodeRef(), d.getPath(), currentFolder + "\\" + tempName);
internalState = InternalState.DELETE_SUBSTITUTED;
return r1;
} else {
// anything else bomb out
if (logger.isDebugEnabled()) {
logger.debug("State error, expected a DELETE");
}
isComplete = true;
}
break;
case DELETE_SUBSTITUTED:
/**
* Looking for a move operation of the deleted file
*/
if (operation instanceof MoveFileOperation) {
MoveFileOperation m = (MoveFileOperation) operation;
String targetFile = m.getTo();
if (deletes.containsKey(targetFile)) {
String tempName = deletes.get(targetFile);
String[] paths = FileName.splitPath(m.getToPath());
String currentFolder = paths[0];
/**
* This is where the scenario fires.
* a) Rename the temp file back to the targetFile
* b) Copy content from moved file
* c) Delete rather than move file
*/
logger.debug("scenario fires");
ArrayList<Command> commands = new ArrayList<Command>();
RenameFileCommand r1 = new RenameFileCommand(tempName, targetFile, m.getRootNodeRef(), currentFolder + "\\" + tempName, m.getToPath());
CopyContentCommand copyContent = new CopyContentCommand(m.getFrom(), targetFile, m.getRootNodeRef(), m.getFromPath(), m.getToPath());
DeleteFileCommand d1 = new DeleteFileCommand(m.getFrom(), m.getRootNodeRef(), m.getFromPath());
commands.add(r1);
commands.add(copyContent);
commands.add(d1);
logger.debug("Scenario complete");
isComplete = true;
return new CompoundCommand(commands);
}
}
}
return null;
}
use of org.alfresco.filesys.repo.rules.operations.MoveFileOperation in project alfresco-repository by Alfresco.
the class NonTransactionalRuleContentDiskDriver method renameFile.
@Override
public void renameFile(SrvSession sess, TreeConnection tree, String oldPath, String newPath) throws IOException {
ContentContext tctx = (ContentContext) tree.getContext();
NodeRef rootNode = tctx.getRootNode();
if (logger.isDebugEnabled()) {
logger.debug("renameFile oldPath:" + oldPath + ", newPath:" + newPath);
}
DriverState driverState = getDriverState(sess);
// Is this a rename within the same folder or a move between folders?
String[] paths = FileName.splitPath(oldPath);
String oldFolder = paths[0];
String oldFile = paths[1];
paths = FileName.splitPath(newPath);
String newFolder = paths[0];
String newFile = paths[1];
try {
if (oldFolder.equalsIgnoreCase(newFolder)) {
logger.debug("renameFileCommand - is a rename within the same folder");
EvaluatorContext ctx = getEvaluatorContext(driverState, oldFolder);
Operation o = new RenameFileOperation(oldFile, newFile, oldPath, newPath, rootNode);
Command c = ruleEvaluator.evaluate(ctx, o);
commandExecutor.execute(sess, tree, c);
ruleEvaluator.notifyRename(ctx, o, c);
releaseEvaluatorContextIfEmpty(driverState, ctx, oldFolder);
} else {
logger.debug("moveFileCommand - move between folders");
Operation o = new MoveFileOperation(oldFile, newFile, oldPath, newPath, rootNode);
/*
* Note: At the moment we only have move scenarios for the destination folder - so
* we only need to evaluate against a single (destination) context/folder.
* This will require re-design as and when we need to have scenarios for the source/folder
*/
// EvaluatorContext ctx1 = getEvaluatorContext(driverState, oldFolder);
EvaluatorContext ctx2 = getEvaluatorContext(driverState, newFolder);
Command c = ruleEvaluator.evaluate(ctx2, o);
commandExecutor.execute(sess, tree, c);
releaseEvaluatorContextIfEmpty(driverState, ctx2, newFolder);
// diskInterface.renameFile(sess, tree, oldPath, newPath);
}
} catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
throw new AccessDeniedException("Unable to rename file file " + oldPath, ade);
}
}
Aggregations