mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-30 18:15:39 +00:00
44765: ALF-17164: Fix failing build in case build is not run in continuous mode 44769: ALF-17097 60k Site Performance: Admin Console | Groups | Browse Groups (include sys groups): Results isn't appeared. - Group page now supports search and browse of large volumes of groups. Tested up to 300,000 sites (60k sites). Previously this would not return. - In order to support large volumes of groups it is not practical to search for all root groups. A functional change has taken place to fix this issue. [Browse] (which initially displayed only root groups) now uses the search value entered by the user and the same query as [Search]. It could be argued that the browse functionality was not very practical anyway if there were a large number of root groups as the user would have to page through all the pages one at a time to get to the required group in order to add a new sub group. As a result of this change it is now possible to get to the required group much faster. As the 'browse' function uses the search value and Include System Groups checkbox (it already used the checkbox value) it made little sense to revert to the Search results when either of these is changed. As this was taking place, this has now been changed too. The [Search] and [Browse] options both now use the authority canned query which has been enhanced to use the sortBy field supplied by the UI. - Uses the authority canned query for [Search] and [Browse] searches on the Groups page. - Canned query may sort on "shortName", "displayName" or "authorityName" - Filter on displayName uses regular expressions to support ? and * wildcards - Canned query returns fewer (unused) columns to speed up fetch time. - Canned query no longer joins to alf_store as none of the values were used. 44772: CIFS Gedit support - rename open files. 44776: ALF-17164: Fix failing build in case build is not run in continuous mode - move generation of version.properties out of continuous mode git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@44790 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
633 lines
21 KiB
Java
633 lines
21 KiB
Java
/*
|
|
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
|
*
|
|
* This file is part of Alfresco
|
|
*
|
|
* Alfresco is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Alfresco is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
package org.alfresco.filesys.repo;
|
|
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.util.Date;
|
|
import java.util.Map;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import org.alfresco.filesys.alfresco.ExtendedDiskInterface;
|
|
import org.alfresco.filesys.alfresco.RepositoryDiskInterface;
|
|
import org.alfresco.filesys.config.ServerConfigurationBean;
|
|
import org.alfresco.filesys.repo.rules.Command;
|
|
import org.alfresco.filesys.repo.rules.EvaluatorContext;
|
|
import org.alfresco.filesys.repo.rules.Operation;
|
|
import org.alfresco.filesys.repo.rules.RuleEvaluator;
|
|
import org.alfresco.filesys.repo.rules.operations.CloseFileOperation;
|
|
import org.alfresco.filesys.repo.rules.operations.CreateFileOperation;
|
|
import org.alfresco.filesys.repo.rules.operations.DeleteFileOperation;
|
|
import org.alfresco.filesys.repo.rules.operations.MoveFileOperation;
|
|
import org.alfresco.filesys.repo.rules.operations.OpenFileOperation;
|
|
import org.alfresco.filesys.repo.rules.operations.RenameFileOperation;
|
|
import org.alfresco.jlan.server.SrvSession;
|
|
import org.alfresco.jlan.server.core.DeviceContext;
|
|
import org.alfresco.jlan.server.core.DeviceContextException;
|
|
import org.alfresco.jlan.server.filesys.FileAction;
|
|
import org.alfresco.jlan.server.filesys.FileAttribute;
|
|
import org.alfresco.jlan.server.filesys.FileInfo;
|
|
import org.alfresco.jlan.server.filesys.FileName;
|
|
import org.alfresco.jlan.server.filesys.FileOpenParams;
|
|
import org.alfresco.jlan.server.filesys.NetworkFile;
|
|
import org.alfresco.jlan.server.filesys.SearchContext;
|
|
import org.alfresco.jlan.server.filesys.TreeConnection;
|
|
import org.alfresco.jlan.smb.SharingMode;
|
|
import org.alfresco.service.cmr.repository.NodeRef;
|
|
import org.alfresco.util.PropertyCheck;
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.springframework.extensions.config.ConfigElement;
|
|
|
|
/**
|
|
* Non Transactional DiskDriver with rules engine.
|
|
* <p>
|
|
* Provides a DiskInterface that deals with "shuffles". Shuffles are implemented by the Rules Engine.
|
|
* <p>
|
|
* Sits on top of the repository and is non-retryable and non-transactional.
|
|
* It is, however thread safe and multiple callers may call in parallel.
|
|
*/
|
|
public class NonTransactionalRuleContentDiskDriver implements ExtendedDiskInterface
|
|
{
|
|
/**
|
|
* The Driver State. Contained within the JLAN SrvSession.
|
|
*/
|
|
private class DriverState
|
|
{
|
|
/**
|
|
* key, value pair storage for the session
|
|
*/
|
|
Map<String, Object> sessionState = new ConcurrentHashMap<String, Object>();
|
|
|
|
/**
|
|
* Map of folderName to Evaluator Context.
|
|
*/
|
|
Map<String, EvaluatorContext> contextMap = new ConcurrentHashMap<String, EvaluatorContext>();
|
|
}
|
|
|
|
private static final Log logger = LogFactory.getLog(NonTransactionalRuleContentDiskDriver.class);
|
|
|
|
private ExtendedDiskInterface diskInterface;
|
|
private RuleEvaluator ruleEvaluator;
|
|
private RepositoryDiskInterface repositoryDiskInterface;
|
|
private CommandExecutor commandExecutor;
|
|
|
|
public void init()
|
|
{
|
|
PropertyCheck.mandatory(this, "diskInterface", diskInterface);
|
|
PropertyCheck.mandatory(this, "ruleEvaluator", getRuleEvaluator());
|
|
PropertyCheck.mandatory(this, "repositoryDiskInterface", getRepositoryDiskInterface());
|
|
PropertyCheck.mandatory(this, "commandExecutor", getCommandExecutor());
|
|
}
|
|
|
|
@Override
|
|
public FileInfo getFileInformation(SrvSession sess, TreeConnection tree,
|
|
String path) throws IOException
|
|
{
|
|
if(logger.isDebugEnabled())
|
|
{
|
|
logger.debug("getFileInformation:" + path);
|
|
}
|
|
FileInfo info = diskInterface.getFileInformation(sess, tree, path);
|
|
|
|
return info;
|
|
}
|
|
|
|
@Override
|
|
public int fileExists(SrvSession sess, TreeConnection tree, String path)
|
|
{
|
|
int fileExists = diskInterface.fileExists(sess, tree, path);
|
|
|
|
return fileExists;
|
|
}
|
|
|
|
@Override
|
|
public DeviceContext createContext(String shareName, ConfigElement args)
|
|
throws DeviceContextException
|
|
{
|
|
return diskInterface.createContext(shareName, args);
|
|
}
|
|
|
|
@Override
|
|
public void treeOpened(SrvSession sess, TreeConnection tree)
|
|
{
|
|
diskInterface.treeOpened(sess, tree);
|
|
}
|
|
|
|
@Override
|
|
public void treeClosed(SrvSession sess, TreeConnection tree)
|
|
{
|
|
diskInterface.treeClosed(sess, tree);
|
|
|
|
}
|
|
|
|
@Override
|
|
public void closeFile(SrvSession sess, TreeConnection tree,
|
|
NetworkFile param) throws IOException
|
|
{
|
|
if(logger.isDebugEnabled())
|
|
{
|
|
logger.debug("closeFile:" + param.getFullName());
|
|
}
|
|
|
|
ContentContext tctx = (ContentContext) tree.getContext();
|
|
NodeRef rootNode = tctx.getRootNode();
|
|
|
|
DriverState driverState = getDriverState(sess);
|
|
|
|
String[] paths = FileName.splitPath(param.getFullName());
|
|
String folder = paths[0];
|
|
String file = paths[1];
|
|
|
|
EvaluatorContext ctx = getEvaluatorContext(driverState, folder);
|
|
|
|
Operation o = new CloseFileOperation(file, param, rootNode, param.getFullName(), param.hasDeleteOnClose(), param.isForce());
|
|
Command c = ruleEvaluator.evaluate(ctx, o);
|
|
|
|
commandExecutor.execute(sess, tree, c);
|
|
|
|
releaseEvaluatorContextIfEmpty(driverState, ctx, folder);
|
|
|
|
}
|
|
|
|
@Override
|
|
public void createDirectory(SrvSession sess, TreeConnection tree,
|
|
FileOpenParams params) throws IOException
|
|
{
|
|
diskInterface.createDirectory(sess, tree, params);
|
|
|
|
}
|
|
|
|
@Override
|
|
public NetworkFile createFile(SrvSession sess, TreeConnection tree,
|
|
FileOpenParams params) throws IOException
|
|
{
|
|
if(logger.isDebugEnabled())
|
|
{
|
|
int sharedAccess = params.getSharedAccess();
|
|
String strSharedAccess = SharingMode.getSharingModeAsString(sharedAccess);
|
|
int attr = params.getAttributes();
|
|
|
|
logger.debug("createFile:" + params.getPath()
|
|
+ ", isDirectory: " + params.isDirectory()
|
|
+ ", isStream: " + params.isStream()
|
|
+ ", readOnlyAccess: " + params.isReadOnlyAccess()
|
|
+ ", readWriteAccess: " + params.isReadWriteAccess()
|
|
+ ", writeOnlyAccess:" +params.isWriteOnlyAccess()
|
|
+ ", attributesOnlyAccess:" +params.isAttributesOnlyAccess()
|
|
+ ", sequentialAccessOnly:" + params.isSequentialAccessOnly()
|
|
+ ", requestBatchOpLock:" +params.requestBatchOpLock()
|
|
+ ", requestExclusiveOpLock:" +params.requestExclusiveOpLock()
|
|
+ ", isDeleteOnClose:" +params.isDeleteOnClose()
|
|
+ ", sharedAccess: " + strSharedAccess
|
|
+ ", allocationSize: " + params.getAllocationSize()
|
|
+ ", isHidden:" + FileAttribute.isHidden(attr)
|
|
+ ", isSystem:" + FileAttribute.isSystem(attr));
|
|
}
|
|
|
|
long creationDateTime = params.getCreationDateTime();
|
|
if(creationDateTime != 0)
|
|
{
|
|
logger.debug("creationDateTime is set:" + new Date(creationDateTime));
|
|
}
|
|
|
|
ContentContext tctx = (ContentContext) tree.getContext();
|
|
NodeRef rootNode = tctx.getRootNode();
|
|
|
|
String[] paths = FileName.splitPath(params.getPath());
|
|
String folder = paths[0];
|
|
String file = paths[1];
|
|
|
|
DriverState driverState = getDriverState(sess);
|
|
EvaluatorContext ctx = getEvaluatorContext(driverState, folder);
|
|
|
|
Operation o = new CreateFileOperation(file, rootNode, params.getPath(), params.getAllocationSize());
|
|
Command c = ruleEvaluator.evaluate(ctx, o);
|
|
|
|
Object ret = commandExecutor.execute(sess, tree, c);
|
|
|
|
if(ret != null && ret instanceof NetworkFile)
|
|
{
|
|
return (NetworkFile)ret;
|
|
}
|
|
else
|
|
{
|
|
// Error - contact broken
|
|
logger.error("contract broken - NetworkFile not returned. " + ret == null ? "Return value is null" : ret);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void deleteDirectory(SrvSession sess, TreeConnection tree, String dir)
|
|
throws IOException
|
|
{
|
|
|
|
diskInterface.deleteDirectory(sess, tree, dir);
|
|
|
|
|
|
}
|
|
|
|
@Override
|
|
public void deleteFile(SrvSession sess, TreeConnection tree, String name)
|
|
throws IOException
|
|
{
|
|
if(logger.isDebugEnabled())
|
|
{
|
|
logger.debug("deleteFile name:" + name);
|
|
}
|
|
|
|
ContentContext tctx = (ContentContext) tree.getContext();
|
|
NodeRef rootNode = tctx.getRootNode();
|
|
|
|
DriverState driverState = getDriverState(sess);
|
|
|
|
String[] paths = FileName.splitPath(name);
|
|
String folder = paths[0];
|
|
String file = paths[1];
|
|
|
|
EvaluatorContext ctx = getEvaluatorContext(driverState, folder);
|
|
|
|
Operation o = new DeleteFileOperation(file, rootNode, name);
|
|
Command c = ruleEvaluator.evaluate(ctx, o);
|
|
commandExecutor.execute(sess, tree, c);
|
|
|
|
releaseEvaluatorContextIfEmpty(driverState, ctx, folder);
|
|
|
|
|
|
} // End of deleteFile
|
|
|
|
@Override
|
|
public void flushFile(SrvSession sess, TreeConnection tree, NetworkFile file)
|
|
throws IOException
|
|
{
|
|
diskInterface.flushFile(sess, tree, file);
|
|
|
|
}
|
|
|
|
@Override
|
|
public boolean isReadOnly(SrvSession sess, DeviceContext ctx)
|
|
throws IOException
|
|
{
|
|
boolean isReadOnly = diskInterface.isReadOnly(sess, ctx);
|
|
|
|
return isReadOnly;
|
|
}
|
|
|
|
@Override
|
|
public NetworkFile openFile(SrvSession sess, TreeConnection tree,
|
|
FileOpenParams param) throws IOException
|
|
{
|
|
String path = param.getPath();
|
|
|
|
boolean truncate = param.isOverwrite();
|
|
|
|
if(logger.isDebugEnabled())
|
|
{
|
|
int sharedAccess = param.getSharedAccess();
|
|
String strSharedAccess = SharingMode.getSharingModeAsString(sharedAccess);
|
|
|
|
logger.debug("openFile:" + path
|
|
+ ", isDirectory: " + param.isDirectory()
|
|
+ ", isStream: " + param.isStream()
|
|
+ ", readOnlyAccess: " + param.isReadOnlyAccess()
|
|
+ ", readWriteAccess: " + param.isReadWriteAccess()
|
|
+ ", writeOnlyAccess:" +param.isWriteOnlyAccess()
|
|
+ ", attributesOnlyAccess:" +param.isAttributesOnlyAccess()
|
|
+ ", sequentialAccessOnly:" + param.isSequentialAccessOnly()
|
|
+ ", writeThrough:" + param.isWriteThrough()
|
|
+ ", truncate:" + truncate
|
|
+ ", requestBatchOpLock:" +param.requestBatchOpLock()
|
|
+ ", requestExclusiveOpLock:" +param.requestExclusiveOpLock()
|
|
+ ", isDeleteOnClose:" +param.isDeleteOnClose()
|
|
+ ", allocationSize:" + param.getAllocationSize()
|
|
+ ", sharedAccess: " + strSharedAccess
|
|
+ ", openAction: " + param.getOpenAction()
|
|
+ param
|
|
);
|
|
}
|
|
|
|
ContentContext tctx = (ContentContext) tree.getContext();
|
|
NodeRef rootNode = tctx.getRootNode();
|
|
|
|
DriverState driverState = getDriverState(sess);
|
|
|
|
String[] paths = FileName.splitPath(path);
|
|
String folder = paths[0];
|
|
String file = paths[1];
|
|
|
|
EvaluatorContext ctx = getEvaluatorContext(driverState, folder);
|
|
|
|
|
|
|
|
OpenFileMode openMode = OpenFileMode.READ_ONLY;
|
|
|
|
if(param.isAttributesOnlyAccess())
|
|
{
|
|
openMode = OpenFileMode.ATTRIBUTES_ONLY;
|
|
}
|
|
else if (param.isReadWriteAccess())
|
|
{
|
|
openMode = OpenFileMode.READ_WRITE;
|
|
}
|
|
else if (param.isWriteOnlyAccess())
|
|
{
|
|
openMode = OpenFileMode.WRITE_ONLY;
|
|
}
|
|
else if (param.isReadOnlyAccess())
|
|
{
|
|
openMode = OpenFileMode.READ_ONLY;
|
|
}
|
|
else if(param.isDeleteOnClose())
|
|
{
|
|
if(logger.isDebugEnabled())
|
|
{
|
|
logger.debug("open file has delete on close");
|
|
}
|
|
openMode = OpenFileMode.DELETE;
|
|
}
|
|
|
|
Operation o = new OpenFileOperation(file, openMode, truncate, rootNode, path);
|
|
Command c = ruleEvaluator.evaluate(ctx, o);
|
|
Object ret = commandExecutor.execute(sess, tree, c);
|
|
|
|
if(ret != null && ret instanceof NetworkFile)
|
|
{
|
|
NetworkFile x = (NetworkFile)ret;
|
|
|
|
if(logger.isDebugEnabled())
|
|
{
|
|
logger.debug("returning open file: for path:" + path +", ret:" + ret);
|
|
}
|
|
return x;
|
|
}
|
|
else
|
|
{
|
|
// Error - contact broken
|
|
logger.error("contract broken - NetworkFile not returned. " + ret == null ? "Return value is null" : ret);
|
|
return null;
|
|
}
|
|
|
|
//return diskInterface.openFile(sess, tree, params);
|
|
} // End of OpenFile
|
|
|
|
@Override
|
|
public int readFile(SrvSession sess, TreeConnection tree, NetworkFile file,
|
|
byte[] buf, int bufPos, int siz, long filePos) throws IOException
|
|
{
|
|
int readSize = diskInterface.readFile(sess, tree, file, buf, bufPos, siz, filePos);
|
|
return readSize;
|
|
}
|
|
|
|
@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];
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
public long seekFile(SrvSession sess, TreeConnection tree,
|
|
NetworkFile file, long pos, int typ) throws IOException
|
|
{
|
|
long ret = diskInterface.seekFile(sess, tree, file, pos, typ);
|
|
|
|
|
|
return ret;
|
|
}
|
|
|
|
@Override
|
|
public void setFileInformation(SrvSession sess, TreeConnection tree,
|
|
String name, FileInfo info) throws IOException
|
|
{
|
|
diskInterface.setFileInformation(sess, tree, name, info);
|
|
|
|
}
|
|
|
|
@Override
|
|
public SearchContext startSearch(SrvSession sess, TreeConnection tree,
|
|
String searchPath, int attrib) throws FileNotFoundException
|
|
{
|
|
SearchContext context = diskInterface.startSearch(sess, tree, searchPath, attrib);
|
|
|
|
return context;
|
|
}
|
|
|
|
@Override
|
|
public void truncateFile(SrvSession sess, TreeConnection tree,
|
|
NetworkFile file, long siz) throws IOException
|
|
{
|
|
diskInterface.truncateFile(sess, tree, file, siz);
|
|
|
|
}
|
|
|
|
@Override
|
|
public int writeFile(SrvSession sess, TreeConnection tree,
|
|
NetworkFile file, byte[] buf, int bufoff, int siz, long fileoff)
|
|
throws IOException
|
|
{
|
|
int writeSize = diskInterface.writeFile(sess, tree, file, buf, bufoff, siz, fileoff);
|
|
|
|
return writeSize;
|
|
}
|
|
|
|
public void setDiskInterface(ExtendedDiskInterface diskInterface)
|
|
{
|
|
this.diskInterface = diskInterface;
|
|
}
|
|
|
|
public ExtendedDiskInterface getDiskInterface()
|
|
{
|
|
return diskInterface;
|
|
}
|
|
|
|
public void setRuleEvaluator(RuleEvaluator ruleEvaluator)
|
|
{
|
|
this.ruleEvaluator = ruleEvaluator;
|
|
}
|
|
|
|
public RuleEvaluator getRuleEvaluator()
|
|
{
|
|
return ruleEvaluator;
|
|
}
|
|
|
|
@Override
|
|
public void registerContext(DeviceContext ctx)
|
|
throws DeviceContextException
|
|
{
|
|
diskInterface.registerContext(ctx);
|
|
}
|
|
|
|
public void setRepositoryDiskInterface(RepositoryDiskInterface repositoryDiskInterface)
|
|
{
|
|
this.repositoryDiskInterface = repositoryDiskInterface;
|
|
}
|
|
|
|
public RepositoryDiskInterface getRepositoryDiskInterface()
|
|
{
|
|
return repositoryDiskInterface;
|
|
}
|
|
|
|
public void setCommandExecutor(CommandExecutor commandExecutor)
|
|
{
|
|
this.commandExecutor = commandExecutor;
|
|
}
|
|
|
|
public CommandExecutor getCommandExecutor()
|
|
{
|
|
return commandExecutor;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the driver state from the session.
|
|
* @param sess
|
|
* @return the driver state.
|
|
*/
|
|
private DriverState getDriverState(SrvSession sess)
|
|
{
|
|
synchronized (sess)
|
|
{
|
|
// Get the driver state
|
|
Object state = sess.getDriverState();
|
|
if(state == null)
|
|
{
|
|
state = new DriverState();
|
|
sess.setDriverState(state);
|
|
if(logger.isDebugEnabled())
|
|
{
|
|
logger.debug("new driver state created");
|
|
}
|
|
|
|
}
|
|
DriverState driverState = (DriverState)state;
|
|
return driverState;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the evaluator context from the state and the folder.
|
|
* @param driverState
|
|
* @param folder
|
|
* @return
|
|
*/
|
|
private EvaluatorContext getEvaluatorContext(DriverState driverState, String folder)
|
|
{
|
|
synchronized(driverState.contextMap)
|
|
{
|
|
EvaluatorContext ctx = driverState.contextMap.get(folder);
|
|
if(ctx == null)
|
|
{
|
|
ctx = ruleEvaluator.createContext(driverState.sessionState);
|
|
driverState.contextMap.put(folder, ctx);
|
|
if(logger.isDebugEnabled())
|
|
{
|
|
logger.debug("new driver context: " + folder);
|
|
}
|
|
}
|
|
return ctx;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Release the evaluator context if there are no active scenarios.
|
|
* @param driverState
|
|
* @param ctx
|
|
* @param folder
|
|
*/
|
|
private void releaseEvaluatorContextIfEmpty(DriverState driverState, EvaluatorContext ctx, String folder)
|
|
{
|
|
synchronized(driverState.contextMap)
|
|
{
|
|
if(ctx != null)
|
|
{
|
|
if(ctx.getScenarioInstances().size() > 0)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
driverState.contextMap.remove(folder);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|