mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Heinous merge from HEAD. Seems to basically work. Be on guard however.
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@4137 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -57,6 +57,7 @@ import org.alfresco.filesys.util.DataBuffer;
|
||||
import org.alfresco.filesys.util.WildCard;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.lock.NodeLockedException;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
@@ -99,10 +100,13 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
||||
private SearchService searchService;
|
||||
private ContentService contentService;
|
||||
private PermissionService permissionService;
|
||||
private CheckOutCheckInService checkOutInService;
|
||||
|
||||
private AuthenticationComponent authComponent;
|
||||
|
||||
// Service registry for desktop actions
|
||||
|
||||
private ServiceRegistry serviceRegistry;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*
|
||||
@@ -173,13 +177,13 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the check in/out service
|
||||
* Return the service registry
|
||||
*
|
||||
* @return CheckOutInService
|
||||
* @return ServiceRegistry
|
||||
*/
|
||||
public final CheckOutCheckInService getCheckInOutService()
|
||||
public final ServiceRegistry getServiceRegistry()
|
||||
{
|
||||
return this.checkOutInService;
|
||||
return this.serviceRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,13 +237,13 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the check in/out service
|
||||
* Set the service registry
|
||||
*
|
||||
* @param checkInService CheckOutInService
|
||||
* @param serviceRegistry
|
||||
*/
|
||||
public void setCheckInOutService(CheckOutCheckInService checkInService)
|
||||
public void setServiceRegistry(ServiceRegistry serviceRegistry)
|
||||
{
|
||||
this.checkOutInService = checkInService;
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -831,20 +835,108 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create the transaction
|
||||
|
||||
sess.beginTransaction(transactionService, true);
|
||||
|
||||
// Get the file information to check if the file/folder exists
|
||||
|
||||
FileInfo info = getFileInformation(sess, tree, name);
|
||||
if (info.isDirectory())
|
||||
// Check if pseudo files are enabled
|
||||
|
||||
if ( hasPseudoFileInterface(ctx))
|
||||
{
|
||||
status = FileStatus.DirectoryExists;
|
||||
// Check if the file name is a pseudo file name
|
||||
|
||||
if ( getPseudoFileInterface( ctx).isPseudoFile(sess, tree, name)) {
|
||||
// Make sure the parent folder has a file state, and the path exists
|
||||
|
||||
String[] paths = FileName.splitPath( name);
|
||||
fstate = ctx.getStateTable().findFileState( paths[0]);
|
||||
|
||||
if ( fstate == null) {
|
||||
|
||||
// Check if the path exists
|
||||
|
||||
if ( fileExists( sess, tree, paths[0]) == FileStatus.DirectoryExists)
|
||||
{
|
||||
// Create the file state
|
||||
|
||||
fstate = ctx.getStateTable().findFileState( paths[0], true, true);
|
||||
|
||||
fstate.setFileStatus( FileStatus.DirectoryExists);
|
||||
|
||||
// Get the node for the folder path
|
||||
|
||||
sess.beginTransaction(transactionService, true);
|
||||
fstate.setNodeRef( getNodeForPath( tree, paths[0]));
|
||||
|
||||
// Add pseudo files to the folder
|
||||
|
||||
getPseudoFileInterface( ctx).addPseudoFilesToFolder( sess, tree, paths[0]);
|
||||
|
||||
// Debug
|
||||
|
||||
if ( logger.isInfoEnabled())
|
||||
logger.info( "Added file state for pseudo files folder (exists) - " + paths[0]);
|
||||
}
|
||||
}
|
||||
else if ( fstate.hasPseudoFiles() == false)
|
||||
{
|
||||
// Make sure the file state has the node ref
|
||||
|
||||
if ( fstate.hasNodeRef() == false)
|
||||
{
|
||||
// Create the transaction
|
||||
|
||||
sess.beginTransaction(transactionService, true);
|
||||
|
||||
// Get the node for the folder path
|
||||
|
||||
fstate.setNodeRef( getNodeForPath( tree, paths[0]));
|
||||
}
|
||||
|
||||
// Add pseudo files for the parent folder
|
||||
|
||||
getPseudoFileInterface( ctx).addPseudoFilesToFolder( sess, tree, paths[0]);
|
||||
|
||||
// Debug
|
||||
|
||||
if ( logger.isInfoEnabled())
|
||||
logger.info( "Added pseudo files for folder (exists) - " + paths[0]);
|
||||
}
|
||||
|
||||
// Check if the path is to a pseudo file
|
||||
|
||||
PseudoFile pfile = getPseudoFileInterface(ctx).getPseudoFile( sess, tree, name);
|
||||
if ( pfile != null)
|
||||
{
|
||||
// Indicate that the file exists
|
||||
|
||||
status = FileStatus.FileExists;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to find pseudo file
|
||||
|
||||
if ( logger.isInfoEnabled())
|
||||
logger.info( "Failed to find pseudo file (exists) - " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
// If the file is not a pseudo file then search for the file
|
||||
|
||||
if ( status == FileStatus.Unknown)
|
||||
{
|
||||
status = FileStatus.FileExists;
|
||||
// Create the transaction
|
||||
|
||||
sess.beginTransaction(transactionService, true);
|
||||
|
||||
// Get the file information to check if the file/folder exists
|
||||
|
||||
FileInfo info = getFileInformation(sess, tree, name);
|
||||
if (info.isDirectory())
|
||||
{
|
||||
status = FileStatus.DirectoryExists;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = FileStatus.FileExists;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -861,13 +953,17 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
||||
status = FileStatus.NotExist;
|
||||
}
|
||||
|
||||
// done
|
||||
// Debug
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("File status determined: \n" +
|
||||
" name: " + name + "\n" +
|
||||
" status: " + status);
|
||||
}
|
||||
|
||||
// Return the file/folder status
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -896,15 +992,65 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
||||
|
||||
if ( hasPseudoFileInterface(ctx))
|
||||
{
|
||||
// Check if the path is to a pseudo file
|
||||
|
||||
PseudoFile pfile = getPseudoFileInterface(ctx).getPseudoFile( sess, tree, params.getPath());
|
||||
if ( pfile != null)
|
||||
{
|
||||
// Create a network file to access the pseudo file data
|
||||
|
||||
return pfile.getFile( params.getPath());
|
||||
}
|
||||
// Check if the file name is a pseudo file name
|
||||
|
||||
String path = params.getPath();
|
||||
|
||||
if ( getPseudoFileInterface( ctx).isPseudoFile(sess, tree, path)) {
|
||||
|
||||
// Make sure the parent folder has a file state, and the path exists
|
||||
|
||||
String[] paths = FileName.splitPath( path);
|
||||
FileState fstate = ctx.getStateTable().findFileState( paths[0]);
|
||||
|
||||
if ( fstate == null) {
|
||||
|
||||
// Check if the path exists
|
||||
|
||||
if ( fileExists( sess, tree, paths[0]) == FileStatus.DirectoryExists)
|
||||
{
|
||||
// Create the file state and add any pseudo files
|
||||
|
||||
fstate = ctx.getStateTable().findFileState( paths[0], true, true);
|
||||
|
||||
fstate.setFileStatus( FileStatus.DirectoryExists);
|
||||
getPseudoFileInterface( ctx).addPseudoFilesToFolder( sess, tree, paths[0]);
|
||||
|
||||
// Debug
|
||||
|
||||
if ( logger.isInfoEnabled())
|
||||
logger.info( "Added file state for pseudo files folder (open) - " + paths[0]);
|
||||
}
|
||||
}
|
||||
else if ( fstate.hasPseudoFiles() == false)
|
||||
{
|
||||
// Add pseudo files for the parent folder
|
||||
|
||||
getPseudoFileInterface( ctx).addPseudoFilesToFolder( sess, tree, paths[0]);
|
||||
|
||||
// Debug
|
||||
|
||||
if ( logger.isInfoEnabled())
|
||||
logger.info( "Added pseudo files for folder (open) - " + paths[0]);
|
||||
}
|
||||
|
||||
// Check if the path is to a pseudo file
|
||||
|
||||
PseudoFile pfile = getPseudoFileInterface(ctx).getPseudoFile( sess, tree, params.getPath());
|
||||
if ( pfile != null)
|
||||
{
|
||||
// Create a network file to access the pseudo file data
|
||||
|
||||
return pfile.getFile( params.getPath());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Failed to find pseudo file
|
||||
|
||||
if ( logger.isInfoEnabled())
|
||||
logger.info( "Failed to find pseudo file (open) - " + params.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not a pseudo file, try and open a normal file/folder node
|
||||
@@ -1045,7 +1191,7 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
||||
|
||||
try
|
||||
{
|
||||
// get the device root
|
||||
// Get the device root
|
||||
|
||||
ContentContext ctx = (ContentContext) tree.getContext();
|
||||
NodeRef deviceRootNodeRef = ctx.getRootNode();
|
||||
@@ -1888,7 +2034,8 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface
|
||||
FileState fstate = ctx.getStateTable().findFileState(path);
|
||||
if ( fstate != null && fstate.hasNodeRef() && fstate.exists() )
|
||||
{
|
||||
// check that the node exists
|
||||
// Check that the node exists
|
||||
|
||||
if (nodeService.exists(fstate.getNodeRef()))
|
||||
{
|
||||
// Bump the file states expiry time
|
||||
|
@@ -27,7 +27,6 @@ import org.alfresco.filesys.server.filesys.DiskSharedDevice;
|
||||
import org.alfresco.filesys.smb.server.repo.pseudo.LocalPseudoFile;
|
||||
import org.alfresco.filesys.smb.server.repo.pseudo.PseudoFile;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
@@ -35,8 +34,6 @@ import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
|
||||
/**
|
||||
* Desktop Action Class
|
||||
@@ -455,13 +452,13 @@ public abstract class DesktopAction {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the check in/out service
|
||||
* Return the service registry
|
||||
*
|
||||
* @return CheckOutInService
|
||||
* @return ServiceRegistry
|
||||
*/
|
||||
public final CheckOutCheckInService getCheckInOutService()
|
||||
public final ServiceRegistry getServiceRegistry()
|
||||
{
|
||||
return m_contentDriver.getCheckInOutService();
|
||||
return m_contentDriver.getServiceRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -19,6 +19,8 @@ package org.alfresco.filesys.smb.server.repo;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.mozilla.javascript.ScriptableObject;
|
||||
|
||||
/**
|
||||
* Desktop Response Class
|
||||
*
|
||||
@@ -26,8 +28,12 @@ import java.util.List;
|
||||
*
|
||||
* @author gkspencer
|
||||
*/
|
||||
public class DesktopResponse {
|
||||
public class DesktopResponse extends ScriptableObject {
|
||||
|
||||
// Version id
|
||||
|
||||
private static final long serialVersionUID = 6421278986221629296L;
|
||||
|
||||
// Desktop action status and optional status message
|
||||
|
||||
private int m_status;
|
||||
@@ -58,7 +64,29 @@ public class DesktopResponse {
|
||||
m_status = sts;
|
||||
m_statusMsg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Javascript constructor
|
||||
*
|
||||
* @param sts int
|
||||
* @param msg String
|
||||
*/
|
||||
public void jsConstructor(int sts, String msg)
|
||||
{
|
||||
m_status = sts;
|
||||
m_statusMsg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class name
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "DesktopResponse";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the status code
|
||||
*
|
||||
@@ -69,6 +97,16 @@ public class DesktopResponse {
|
||||
return m_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the status property
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public int jsGet_status()
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if there is an optional status message
|
||||
*
|
||||
@@ -89,6 +127,16 @@ public class DesktopResponse {
|
||||
return m_statusMsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the status message property
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public String jsGet_message()
|
||||
{
|
||||
return m_statusMsg != null ? m_statusMsg : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if there are optional response values
|
||||
*
|
||||
@@ -144,6 +192,26 @@ public class DesktopResponse {
|
||||
m_statusMsg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the status property
|
||||
*
|
||||
* @param sts int
|
||||
*/
|
||||
public void jsSet_status(int sts)
|
||||
{
|
||||
m_status = sts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the status message property
|
||||
*
|
||||
* @param msg String
|
||||
*/
|
||||
public void jsSet_message(String msg)
|
||||
{
|
||||
m_statusMsg = msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the desktop response as a string
|
||||
*
|
||||
|
@@ -16,6 +16,10 @@
|
||||
*/
|
||||
package org.alfresco.filesys.smb.server.repo.desk;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.filesys.server.filesys.FileName;
|
||||
import org.alfresco.filesys.server.filesys.NotifyChange;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopAction;
|
||||
@@ -23,6 +27,7 @@ import org.alfresco.filesys.smb.server.repo.DesktopParams;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopResponse;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopTarget;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.coci.CheckOutCheckInService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
|
||||
/**
|
||||
@@ -34,6 +39,10 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
*/
|
||||
public class CheckInOutDesktopAction extends DesktopAction {
|
||||
|
||||
// Check in/out service
|
||||
|
||||
private CheckOutCheckInService m_checkInOutService;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
@@ -42,6 +51,11 @@ public class CheckInOutDesktopAction extends DesktopAction {
|
||||
super( DesktopAction.AttrAnyFiles, DesktopAction.PreConfirmAction + DesktopAction.PreCopyToTarget + DesktopAction.PreLocalToWorkingCopy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the confirmation string to be displayed by the client
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getConfirmationString() {
|
||||
return "Run check in/out action";
|
||||
@@ -56,7 +70,7 @@ public class CheckInOutDesktopAction extends DesktopAction {
|
||||
@Override
|
||||
public DesktopResponse runAction(DesktopParams params) {
|
||||
|
||||
// check if there are any files/folders to process
|
||||
// Check if there are any files/folders to process
|
||||
|
||||
if ( params.numberOfTargetNodes() == 0)
|
||||
return new DesktopResponse(StsSuccess);
|
||||
@@ -81,9 +95,10 @@ public class CheckInOutDesktopAction extends DesktopAction {
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check in the file
|
||||
// Check in the file, pass an empty version properties so that veriosnable nodes create a new version
|
||||
|
||||
getCheckInOutService().checkin( target.getNode(), null, null, false);
|
||||
Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
|
||||
getCheckInOutService().checkin( target.getNode(), versionProperties, null, false);
|
||||
|
||||
// Check if there are any file/directory change notify requests active
|
||||
|
||||
@@ -183,4 +198,23 @@ public class CheckInOutDesktopAction extends DesktopAction {
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the check in/out service
|
||||
*
|
||||
* @return CheckOutCheckInService
|
||||
*/
|
||||
protected final CheckOutCheckInService getCheckInOutService()
|
||||
{
|
||||
// Check if the service has been cached
|
||||
|
||||
if ( m_checkInOutService == null)
|
||||
{
|
||||
m_checkInOutService = getServiceRegistry().getCheckOutCheckInService();
|
||||
}
|
||||
|
||||
// Return the check in/out service
|
||||
|
||||
return m_checkInOutService;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,448 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* 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.alfresco.filesys.smb.server.repo.desk;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.alfresco.config.ConfigElement;
|
||||
import org.alfresco.filesys.server.filesys.DiskSharedDevice;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopAction;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopActionException;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopParams;
|
||||
import org.alfresco.filesys.smb.server.repo.DesktopResponse;
|
||||
import org.alfresco.service.cmr.repository.ScriptException;
|
||||
import org.alfresco.service.cmr.repository.ScriptService;
|
||||
|
||||
/**
|
||||
* Javascript Desktop Action Class
|
||||
*
|
||||
* <p>Run a server-side script against the target node(s).
|
||||
*
|
||||
* @author gkspencer
|
||||
*/
|
||||
public class JavaScriptDesktopAction extends DesktopAction {
|
||||
|
||||
// Script service
|
||||
|
||||
private ScriptService m_scriptService;
|
||||
|
||||
// Script name
|
||||
|
||||
private String m_scriptName;
|
||||
|
||||
// Script file details
|
||||
|
||||
private String m_scriptPath;
|
||||
private long m_lastModified;
|
||||
|
||||
// Script string
|
||||
|
||||
private String m_script;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
*/
|
||||
public JavaScriptDesktopAction()
|
||||
{
|
||||
super( DesktopAction.AttrAnyFiles, DesktopAction.PreConfirmAction + DesktopAction.PreCopyToTarget);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the confirmation string to be displayed by the client
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String getConfirmationString()
|
||||
{
|
||||
return "Run Javascript action";
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the action
|
||||
*
|
||||
* @param global ConfigElement
|
||||
* @param config ConfigElement
|
||||
* @param fileSys DiskSharedDevice
|
||||
* @exception DesktopActionException
|
||||
*/
|
||||
@Override
|
||||
public void initializeAction(ConfigElement global, ConfigElement config, DiskSharedDevice fileSys)
|
||||
throws DesktopActionException
|
||||
{
|
||||
|
||||
// Perform standard initialization
|
||||
|
||||
super.initializeAction(global, config, fileSys);
|
||||
|
||||
// Get the script file name and check that it exists
|
||||
|
||||
ConfigElement elem = config.getChild("script");
|
||||
if ( elem != null && elem.getValue().length() > 0)
|
||||
{
|
||||
// Set the script name
|
||||
|
||||
setScriptName(elem.getValue());
|
||||
|
||||
// Check if the script exists on the classpath
|
||||
|
||||
URL scriptURL = this.getClass().getClassLoader().getResource(getScriptName());
|
||||
if ( scriptURL == null)
|
||||
throw new DesktopActionException("Failed to find script on classpath, " + getScriptName());
|
||||
|
||||
// Decode the URL path, it might contain escaped characters
|
||||
|
||||
String scriptURLPath = null;
|
||||
try
|
||||
{
|
||||
scriptURLPath = URLDecoder.decode( scriptURL.getFile(), "UTF-8");
|
||||
}
|
||||
catch ( UnsupportedEncodingException ex)
|
||||
{
|
||||
throw new DesktopActionException("Failed to decode script path, " + ex.getMessage());
|
||||
}
|
||||
|
||||
// Check that the script file exists
|
||||
|
||||
File scriptFile = new File(scriptURLPath);
|
||||
if ( scriptFile.exists() == false)
|
||||
throw new DesktopActionException("Script file not found, " + elem.getValue());
|
||||
|
||||
m_scriptPath = scriptFile.getAbsolutePath();
|
||||
m_lastModified =scriptFile.lastModified();
|
||||
|
||||
// Load the script
|
||||
|
||||
try
|
||||
{
|
||||
loadScript( scriptFile);
|
||||
}
|
||||
catch ( IOException ex)
|
||||
{
|
||||
throw new DesktopActionException( "Failed to load script, " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new DesktopActionException("Script name not specified");
|
||||
|
||||
// check if the desktop action attributes have been specified
|
||||
|
||||
elem = config.getChild("attributes");
|
||||
if ( elem != null)
|
||||
{
|
||||
// Check if the attribute string is empty
|
||||
|
||||
if ( elem.getValue().length() == 0)
|
||||
throw new DesktopActionException("Empty desktop action attributes");
|
||||
|
||||
// Parse the attribute string
|
||||
|
||||
int attr = 0;
|
||||
StringTokenizer tokens = new StringTokenizer( elem.getValue(), ",");
|
||||
|
||||
while ( tokens.hasMoreTokens())
|
||||
{
|
||||
// Get the current attribute token and validate
|
||||
|
||||
String token = tokens.nextToken().trim();
|
||||
|
||||
if ( token.equalsIgnoreCase( "targetFiles"))
|
||||
attr |= AttrTargetFiles;
|
||||
else if ( token.equalsIgnoreCase( "targetFolders"))
|
||||
attr |= AttrTargetFolders;
|
||||
else if ( token.equalsIgnoreCase( "clientFiles"))
|
||||
attr |= AttrClientFiles;
|
||||
else if ( token.equalsIgnoreCase( "clientFolders"))
|
||||
attr |= AttrClientFolders;
|
||||
else if ( token.equalsIgnoreCase( "alfrescoFiles"))
|
||||
attr |= AttrAlfrescoFiles;
|
||||
else if ( token.equalsIgnoreCase( "alfrescoFolders"))
|
||||
attr |= AttrAlfrescoFolders;
|
||||
else if ( token.equalsIgnoreCase( "multiplePaths"))
|
||||
attr |= AttrMultiplePaths;
|
||||
else if ( token.equalsIgnoreCase( "allowNoParams"))
|
||||
attr |= AttrAllowNoParams;
|
||||
else if ( token.equalsIgnoreCase( "anyFiles"))
|
||||
attr |= AttrAnyFiles;
|
||||
else if ( token.equalsIgnoreCase( "anyFolders"))
|
||||
attr |= AttrAnyFolders;
|
||||
else if ( token.equalsIgnoreCase( "anyFilesFolders"))
|
||||
attr |= AttrAnyFilesFolders;
|
||||
else
|
||||
throw new DesktopActionException("Unknown attribute, " + token);
|
||||
}
|
||||
|
||||
// Set the action attributes
|
||||
|
||||
setAttributes( attr);
|
||||
}
|
||||
|
||||
// Check if the desktop action pre-processing options have been specified
|
||||
|
||||
elem = config.getChild("preprocess");
|
||||
if ( elem != null)
|
||||
{
|
||||
// Check if the pre-process string is empty
|
||||
|
||||
if ( elem.getValue().length() == 0)
|
||||
throw new DesktopActionException("Empty desktop action pre-processing flags");
|
||||
|
||||
// Parse the pre-process string
|
||||
|
||||
int pre = 0;
|
||||
StringTokenizer tokens = new StringTokenizer( elem.getValue(), ",");
|
||||
|
||||
while ( tokens.hasMoreTokens())
|
||||
{
|
||||
// Get the current pre-process token and validate
|
||||
|
||||
String token = tokens.nextToken().trim();
|
||||
|
||||
if ( token.equalsIgnoreCase( "copyToTarget"))
|
||||
pre |= PreCopyToTarget;
|
||||
else if ( token.equalsIgnoreCase( "confirm"))
|
||||
pre |= PreConfirmAction;
|
||||
else if ( token.equalsIgnoreCase( "localToWorkingCopy"))
|
||||
pre |= PreLocalToWorkingCopy;
|
||||
else
|
||||
throw new DesktopActionException("Unknown pre-processing flag, " + token);
|
||||
}
|
||||
|
||||
// Set the action pre-processing flags
|
||||
|
||||
setPreProcessActions( pre);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the desktop action
|
||||
*
|
||||
* @param params DesktopParams
|
||||
* @return DesktopResponse
|
||||
*/
|
||||
@Override
|
||||
public DesktopResponse runAction(DesktopParams params)
|
||||
throws DesktopActionException
|
||||
{
|
||||
// Check if the script file has been changed
|
||||
|
||||
DesktopResponse response = new DesktopResponse(StsSuccess);
|
||||
|
||||
File scriptFile = new File(m_scriptPath);
|
||||
if ( scriptFile.lastModified() != m_lastModified)
|
||||
{
|
||||
// Reload the script
|
||||
|
||||
m_lastModified = scriptFile.lastModified();
|
||||
|
||||
try
|
||||
{
|
||||
loadScript( scriptFile);
|
||||
}
|
||||
catch ( IOException ex)
|
||||
{
|
||||
response.setStatus(StsError, "Failed to reload script file, " + getScriptName());
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
// Start a transaction
|
||||
|
||||
params.getSession().beginTransaction(getTransactionService(), false);
|
||||
|
||||
// Access the script service
|
||||
|
||||
if ( getScriptService() != null)
|
||||
{
|
||||
// Create the objects to be passed to the script
|
||||
|
||||
Map<String, Object> model = new HashMap<String, Object>();
|
||||
model.put("deskParams", params);
|
||||
model.put("out", System.out);
|
||||
|
||||
// Start a transaction
|
||||
|
||||
params.getSession().beginTransaction(getTransactionService(), false);
|
||||
|
||||
// Run the script
|
||||
|
||||
Object result = null;
|
||||
|
||||
try
|
||||
{
|
||||
// Run the script
|
||||
|
||||
result = getScriptService().executeScriptString( getScript(), model);
|
||||
|
||||
// Check the result
|
||||
|
||||
if ( result != null)
|
||||
{
|
||||
// Check for a full response object
|
||||
|
||||
if ( result instanceof DesktopResponse)
|
||||
{
|
||||
response = (DesktopResponse) result;
|
||||
}
|
||||
|
||||
// Status code only response
|
||||
|
||||
else if ( result instanceof Double)
|
||||
{
|
||||
Double jsSts = (Double) result;
|
||||
response.setStatus( jsSts.intValue(), "");
|
||||
}
|
||||
|
||||
// Encoded response in the format '<stsCode>,<stsMessage>'
|
||||
|
||||
else if ( result instanceof String)
|
||||
{
|
||||
String responseMsg = (String) result;
|
||||
|
||||
// Parse the status message
|
||||
|
||||
StringTokenizer token = new StringTokenizer( responseMsg, ",");
|
||||
String stsToken = token.nextToken();
|
||||
String msgToken = token.nextToken();
|
||||
|
||||
int sts = -1;
|
||||
try
|
||||
{
|
||||
sts = Integer.parseInt( stsToken);
|
||||
}
|
||||
catch ( NumberFormatException ex)
|
||||
{
|
||||
response.setStatus( StsError, "Bad response from script");
|
||||
}
|
||||
|
||||
// Set the response
|
||||
|
||||
response.setStatus( sts, msgToken != null ? msgToken : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ScriptException ex)
|
||||
{
|
||||
// Set the error response for the client
|
||||
|
||||
response.setStatus( StsError, ex.getMessage());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return an error response, script service not available
|
||||
|
||||
response.setStatus( StsError, "Script service not available");
|
||||
}
|
||||
|
||||
// Return the response
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the script service
|
||||
*
|
||||
* @return ScriptService
|
||||
*/
|
||||
protected final ScriptService getScriptService()
|
||||
{
|
||||
// Check if the script service has been initialized
|
||||
|
||||
if ( m_scriptService == null)
|
||||
{
|
||||
// Get the script service
|
||||
|
||||
m_scriptService = getServiceRegistry().getScriptService();
|
||||
}
|
||||
|
||||
// Return the script service
|
||||
|
||||
return m_scriptService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the script name
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getScriptName()
|
||||
{
|
||||
return m_scriptName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the script data
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public final String getScript()
|
||||
{
|
||||
return m_script;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the script name
|
||||
*
|
||||
* @param name String
|
||||
*/
|
||||
protected final void setScriptName(String name)
|
||||
{
|
||||
m_scriptName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load, or reload, the script
|
||||
*
|
||||
* @param scriptFile File
|
||||
*/
|
||||
private final void loadScript(File scriptFile)
|
||||
throws IOException
|
||||
{
|
||||
// Open the script file
|
||||
|
||||
BufferedReader scriptIn = new BufferedReader(new FileReader( scriptFile));
|
||||
StringBuilder scriptStr = new StringBuilder((int) scriptFile.length() + 256);
|
||||
|
||||
String inRec = scriptIn.readLine();
|
||||
|
||||
while ( inRec != null)
|
||||
{
|
||||
scriptStr.append( inRec);
|
||||
scriptStr.append( "\n");
|
||||
inRec = scriptIn.readLine();
|
||||
}
|
||||
|
||||
// Close the script file
|
||||
|
||||
scriptIn.close();
|
||||
|
||||
// Update the script string
|
||||
|
||||
m_script = scriptStr.toString();
|
||||
}
|
||||
}
|
@@ -68,6 +68,27 @@ public class ContentPseudoFileImpl implements PseudoFileInterface
|
||||
if ( pfile != null)
|
||||
isPseudo = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check if the file name matches a pseudo-file name in the desktop actions list
|
||||
|
||||
if ( ctx.hasDesktopActions())
|
||||
{
|
||||
DesktopActionTable actions = ctx.getDesktopActions();
|
||||
if ( actions.getActionViaPseudoName( paths[1]) != null)
|
||||
isPseudo = true;
|
||||
}
|
||||
|
||||
// Check if the URL file is enabled
|
||||
|
||||
if ( isPseudo == false && ctx.hasURLFile())
|
||||
{
|
||||
// Check if it is the URL file name
|
||||
|
||||
if ( ctx.getURLFileName().equals( paths[1]))
|
||||
isPseudo = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the pseudo file status
|
||||
|
||||
|
Reference in New Issue
Block a user