Added environment variable expansion to the command line handling of desktop actions, plus the special '%AlfrescoDir%' token for the

current working directory path (from the client side).
Updated sample commandline test action to use '%SystemRoot%\Notepad.exe'.
Added lock check to check out action code to give more meaningful error message.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3689 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gary Spencer
2006-09-05 10:04:44 +00:00
parent c905a09f4b
commit c8ed7691e0
6 changed files with 211 additions and 39 deletions

Binary file not shown.

View File

@@ -37,14 +37,14 @@ using namespace Alfresco;
// CCAlfrescoAppApp // CCAlfrescoAppApp
BEGIN_MESSAGE_MAP(CCAlfrescoAppApp, CWinApp) BEGIN_MESSAGE_MAP(CAlfrescoApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp) ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP() END_MESSAGE_MAP()
// CCAlfrescoAppApp construction // CCAlfrescoApp construction
CCAlfrescoAppApp::CCAlfrescoAppApp() CAlfrescoApp::CAlfrescoApp()
{ {
// TODO: add construction code here, // TODO: add construction code here,
// Place all significant initialization in InitInstance // Place all significant initialization in InitInstance
@@ -53,12 +53,12 @@ CCAlfrescoAppApp::CCAlfrescoAppApp()
// The one and only CCAlfrescoAppApp object // The one and only CCAlfrescoAppApp object
CCAlfrescoAppApp theApp; CAlfrescoApp theApp;
// CCAlfrescoAppApp initialization // CCAlfrescoAppApp initialization
BOOL CCAlfrescoAppApp::InitInstance() BOOL CAlfrescoApp::InitInstance()
{ {
// InitCommonControls() is required on Windows XP if an application // InitCommonControls() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable // manifest specifies use of ComCtl32.dll version 6 or later to enable
@@ -181,7 +181,7 @@ BOOL CCAlfrescoAppApp::InitInstance()
* @param params DesktopParams& * @param params DesktopParams&
* @return bool * @return bool
*/ */
bool CCAlfrescoAppApp::buildDesktopParameters( AlfrescoInterface& alfresco, StringList& paths, AlfrescoActionInfo& actionInfo, bool CAlfrescoApp::buildDesktopParameters( AlfrescoInterface& alfresco, StringList& paths, AlfrescoActionInfo& actionInfo,
DesktopParams& params) { DesktopParams& params) {
// If there are no paths then just return a success // If there are no paths then just return a success
@@ -401,7 +401,7 @@ bool CCAlfrescoAppApp::buildDesktopParameters( AlfrescoInterface& alfresco, Stri
* @param aborted bool& * @param aborted bool&
* @return bool * @return bool
*/ */
bool CCAlfrescoAppApp::copyFilesUsingShell(const String& fromFileFolder, const String& toFolder, bool& aborted) { bool CAlfrescoApp::copyFilesUsingShell(const String& fromFileFolder, const String& toFolder, bool& aborted) {
// Build the from/to paths, must be double null terminated // Build the from/to paths, must be double null terminated
@@ -456,7 +456,7 @@ bool CCAlfrescoAppApp::copyFilesUsingShell(const String& fromFileFolder, const S
* @param actionInfo AlfrescoActionInfo& * @param actionInfo AlfrescoActionInfo&
* @return bool * @return bool
*/ */
bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo) { bool CAlfrescoApp::runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo) {
// Build the desktop action parameter list, perform any file copying of local files // Build the desktop action parameter list, perform any file copying of local files
@@ -484,24 +484,9 @@ bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathL
if ( response.getStatus() == StsCommandLine) { if ( response.getStatus() == StsCommandLine) {
// Initialize the startup information
STARTUPINFO startupInfo;
memset(&startupInfo, 0, sizeof(STARTUPINFO));
// Launch a process using the command line // Launch a process using the command line
PROCESS_INFORMATION processInfo; sts = doCommandLine( alfresco, response.getStatusMessage());
memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
if ( CreateProcess( response.getStatusMessage().data(), NULL, NULL, NULL, true, 0, NULL, NULL,
&startupInfo, &processInfo) == false) {
CString msg;
msg.FormatMessage( L"Failed to launch command line\n\n%1\n\nError %2!d!", response.getStatusMessage().data(), GetLastError());
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
}
else
sts = true;
} }
// Check if a web browser should be launched with a URL // Check if a web browser should be launched with a URL
@@ -510,14 +495,7 @@ bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathL
// Use the Windows shell to open the URL // Use the Windows shell to open the URL
HINSTANCE shellSts = ShellExecute( NULL, NULL, response.getStatusMessage().data(), NULL, NULL, SW_SHOWNORMAL); sts = doURL( alfresco, response.getStatusMessage());
if (( int) shellSts < 32) {
CString msg;
msg.FormatMessage( L"Failed to launch URL\n\n%1", response.getStatusMessage().data());
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
}
else
sts = true;
} }
// Error status // Error status
@@ -572,3 +550,168 @@ bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathL
return sts; return sts;
} }
/**
* Launch a command line
*
* @param alfresco AlfrescoInterface&
* @param cmdStr const String&
* @return bool
*/
bool CAlfrescoApp::doCommandLine( AlfrescoInterface& alfresco, const String& cmdStr) {
// Check if the command line contains any environment variables/tokens
String cmdLine = cmdStr;
int pos = cmdLine.indexOf( L'%');
if ( pos != -1) {
// Command line contains environment variables or other tokens that must be replaced
String newCmdLine = L"";
if (pos > 0)
newCmdLine = cmdLine.substring( 0, pos);
wchar_t envBuf[256];
size_t envLen;
while ( pos != -1) {
// Find the end of the current token
int endPos = cmdLine.indexOf ( L'%', pos + 1);
if ( endPos == -1) {
CString msg;
msg.FormatMessage( L"Bad token in command line\n\n%1", cmdLine.data());
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
return false;
}
// Extract the token
String token = cmdLine.substring( pos + 1, endPos);
// Replace the token with an environment variable value or other values
if ( token.equals( L"AlfrescoDir")) {
// Use the local path to the Alfresco folder that the application is running from
newCmdLine.append( alfresco.getUNCPath());
}
else {
// Find the environment variable value
envLen = sizeof( envBuf)/sizeof(wchar_t);
const wchar_t* pEnvName = token.data();
if ( _wgetenv_s( &envLen, envBuf, envLen, pEnvName) == 0) {
// Append the environment variable value
newCmdLine.append( envBuf);
}
else {
// Error converting the environment variable
CString msg;
msg.FormatMessage( L"Failed to convert environment variable\n\n%1\n\n%2", token.data(), cmdLine.data());
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
return false;
}
}
// Update the token search position
pos = endPos + 1;
if (( unsigned int) pos < cmdStr.length()) {
// Search for the next token
pos = cmdLine.indexOf( L'%', pos);
}
else {
// End of string, finish the token search
pos = -1;
}
// Append the normal string between tokens
if ( pos > (endPos + 1)) {
// Get the between token sting
String filler = cmdLine.substring( endPos + 1, pos);
newCmdLine.append( filler);
}
else if ( pos == -1) {
// Append the remaining string
String filler = cmdLine.substring( endPos + 1);
newCmdLine.append( filler);
}
}
// Update the command line
cmdLine = newCmdLine;
}
// Initialize the startup information
STARTUPINFO startupInfo;
memset(&startupInfo, 0, sizeof(STARTUPINFO));
// Launch a process using the command line
PROCESS_INFORMATION processInfo;
memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
bool sts = false;
if ( CreateProcess( NULL, (LPWSTR) cmdLine.data(), NULL, NULL, true, 0, NULL, NULL,
&startupInfo, &processInfo) == false) {
CString msg;
msg.FormatMessage( L"Failed to launch command line\n\n%1\n\nError %2!d!", cmdLine.data(), GetLastError());
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
}
else
sts = true;
return sts;
}
/**
* Browse to a URL
*
* @param alfresco AlfrescoInterface&
* @param url const String&
* @return bool
*/
bool CAlfrescoApp::doURL( AlfrescoInterface& alfresco, const String& url) {
// Use the Windows shell to open the URL
bool sts = false;
HINSTANCE shellSts = ShellExecute( NULL, NULL, url.data(), NULL, NULL, SW_SHOWNORMAL);
if (( int) shellSts < 32) {
CString msg;
msg.FormatMessage( L"Failed to launch URL\n\n%1", url.data());
AfxMessageBox( msg, MB_OK | MB_ICONERROR);
}
else
sts = true;
return sts;
}

View File

@@ -30,14 +30,14 @@
using namespace Alfresco; using namespace Alfresco;
// CCAlfrescoAppApp: // CAlfrescoApp:
// See CAlfrescoApp.cpp for the implementation of this class // See CAlfrescoApp.cpp for the implementation of this class
// //
class CCAlfrescoAppApp : public CWinApp class CAlfrescoApp : public CWinApp
{ {
public: public:
CCAlfrescoAppApp(); CAlfrescoApp();
// Overrides // Overrides
public: public:
@@ -59,6 +59,11 @@ private:
// Run the action // Run the action
bool runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo); bool runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo);
// Post-process actions, command line launch and browse to URL
bool doCommandLine( AlfrescoInterface& alfresco, const String& cmdLine);
bool doURL( AlfrescoInterface& alfresco, const String& url);
}; };
extern CCAlfrescoAppApp theApp; extern CAlfrescoApp theApp;

View File

@@ -676,7 +676,8 @@ void String::append ( const char* str) {
* @param str const wchar_t* * @param str const wchar_t*
*/ */
void String::append (const wchar_t* str) { void String::append (const wchar_t* str) {
m_string += str; while ( *str != 0)
m_string += *str++;
} }
/** /**

View File

@@ -113,6 +113,11 @@ public class CheckInOutDesktopAction extends DesktopAction {
} }
catch (Exception ex) catch (Exception ex)
{ {
// Dump the error
if ( logger.isErrorEnabled())
logger.error("Desktop action error", ex);
// Return an error status and message // Return an error status and message
response.setStatus(StsError, "Checkin failed for " + target.getTarget() + ", " + ex.getMessage()); response.setStatus(StsError, "Checkin failed for " + target.getTarget() + ", " + ex.getMessage());
@@ -122,6 +127,19 @@ public class CheckInOutDesktopAction extends DesktopAction {
{ {
try try
{ {
// Check if the file is locked
if ( getNodeService().hasAspect( target.getNode(), ContentModel.ASPECT_LOCKABLE)) {
// Get the lock type
String lockTypeStr = (String) getNodeService().getProperty( target.getNode(), ContentModel.PROP_LOCK_TYPE);
if ( lockTypeStr != null) {
response.setStatus(StsError, "Checkout failed, file is locked");
return response;
}
}
// Check out the file // Check out the file
NodeRef workingCopyNode = getCheckInOutService().checkout( target.getNode()); NodeRef workingCopyNode = getCheckInOutService().checkout( target.getNode());
@@ -149,6 +167,11 @@ public class CheckInOutDesktopAction extends DesktopAction {
} }
catch (Exception ex) catch (Exception ex)
{ {
// Dump the error
if ( logger.isErrorEnabled())
logger.error("Desktop action error", ex);
// Return an error status and message // Return an error status and message
response.setStatus(StsError, "Failed to checkout " + target.getTarget() + ", " + ex.getMessage()); response.setStatus(StsError, "Failed to checkout " + target.getTarget() + ", " + ex.getMessage());

View File

@@ -47,6 +47,6 @@ public class CmdLineDesktopAction extends DesktopAction {
// Return a URL in the status message // Return a URL in the status message
return new DesktopResponse(StsCommandLine, "C:\\Windows\\notepad.exe"); return new DesktopResponse(StsCommandLine, "%SystemRoot%\\notepad.exe");
} }
} }