Updated Windows application to support new desktop action framework. Updated project to build with Visual Studio 2005.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3513 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gary Spencer
2006-08-15 13:54:51 +00:00
parent bafb261228
commit 40c9d6cce3
3 changed files with 352 additions and 420 deletions

View File

@@ -0,0 +1,179 @@
/*
* Copyright (C) 2005-2006 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.
*/
#ifndef _Desktop_H
#define _Desktop_H
// Includes
#include <windows.h>
#include <vector>
#include <algorithm>
#include "util\Exception.h"
#include "util\String.h"
#include "util\DataBuffer.h"
// Classes defined in this header file
namespace Alfresco {
class DesktopTarget;
class DesktopParams;
class DesktopResponse;
typedef std::auto_ptr<DesktopTarget> PTR_DesktopTarget;
typedef std::auto_ptr<DesktopParams> PTR_DesktopParams;
typedef std::auto_ptr<DesktopResponse> PTR_DesktopResponse;
}
// Constants
namespace Alfresco {
// Desktop target types
#define TargetFile 0
#define TargetFolder 1
#define TargetCopiedFile 2
#define TargetCopiedFolder 3
#define TargetNodeRef 4
}
// Define desktop action exceptions
DEFINE_EXCEPTION(Alfresco, DesktopActionException);
/**
* Desktop Target Class
*
* Contains the details of a target for a desktop action.
*/
class Alfresco::DesktopTarget {
public:
// Class constructors
DesktopTarget(int typ, String& path);
// Class destructor
~DesktopTarget();
// Return the target type, target path/id
inline unsigned int isType(void) const { return m_type; }
inline const String& getTarget(void) const { return m_target; }
// Return the target type as a string
const String getTypeAsString( void) const;
// Return the target details as a string
const String toString( void) const;
// Operators
bool operator==( const DesktopTarget& target);
bool operator<( const DesktopTarget& target);
private:
// Hide the copy constructor
DesktopTarget(const DesktopTarget& target) {};
private:
// Instance variables
//
// Target type and path/id
unsigned int m_type;
String m_target;
};
/**
* Desktop Params Class
*
* Contains the parameters for a desktop action request.
*/
class Alfresco::DesktopParams {
public:
// Class constructors
DesktopParams(void) {}
// Return the number of targets
inline size_t numberOfTargets(void) const { return m_list.size(); }
// Return a target from the list
const DesktopTarget* getTarget(const unsigned int idx) const;
// Add a desktop target
inline void addTarget(DesktopTarget* pTarget) { m_list.push_back(pTarget); }
// Clear the target list
inline void clearTargets( void) { m_list.clear(); }
// Return the desktop parameters as a string
const String toString(void) const;
private:
// Instance variables
//
// List of file/folder/node targets for the action
std::vector<DesktopTarget*> m_list;
};
/**
* Desktop Response Class
*
* Contains the result of calling a server side desktop action.
*/
class Alfresco::DesktopResponse {
public:
// class constructors
DesktopResponse( const unsigned int sts, const wchar_t* msg = NULL);
// Return the status code
inline unsigned int getStatus( void) const { return m_status; }
// Check if there is a status message, return the status message
inline bool hasStatusMessage(void) const { return m_statusMsg.length() > 0; }
inline const String& getStatusMessage(void) const { return m_statusMsg; }
// Assignment operator
DesktopResponse& operator=( const DesktopResponse& response);
private:
// Instance variables
//
// Status code and message
unsigned int m_status;
String m_statusMsg;
};
#endif

View File

@@ -1,420 +0,0 @@
#include <iostream>
#include "alfresco\Alfresco.hpp"
#include "util\String.h"
#include "util\DataBuffer.h"
#include "util\FileName.h"
#include <shellapi.h>
using namespace std;
using namespace JLAN;
// Function prototypes
bool doFolderStatus( Alfresco& alfresco, const wchar_t* fileSpec = L"*.*");
bool doCheckInOut( Alfresco& alfresco, StringList& files);
bool doCheckIn( Alfresco& alfresco, PTR_AlfrescoFileInfo& fileInfo);
bool doCheckOut( Alfresco& alfresco, PTR_AlfrescoFileInfo& fileInfo);
/**
* Alfresco Windows Drag And Drop Application
*
* @author GKSpencer
*/
int wmain( int argc, wchar_t* argv[], wchar_t* envp[]) {
// Output a startup banner
wcout << L"Alfresco Drag And Drop Application" << endl;
wcout << L"----------------------------------" << endl;
// Check if the app is running from a network drive
String appPath(argv[0]);
// String appPath("\\\\StarlaA\\Alfresco\\Garys Space\\AlfrescoApp.exe");
// String appPath("Z:\\Garys Space\\AlfrescoApp.exe");
// argc = 2;
// Looks like a UNC path, trim off the application name
int pos = appPath.lastIndexOf(PathSeperator);
if ( pos < 0) {
wcout << L"%% Invalid application path, " << appPath << endl;
return 1;
}
// Get the path to the folder containing the application
String folderPath = appPath.substring(0, pos);
// Create the Alfresco interface
Alfresco alfresco(folderPath);
if ( alfresco.isAlfrescoFolder()) {
// If there are no file paths on the command line then display a status page for the files
// in the Alfresco folder
if ( argc == 1) {
// Display status for the files in the Alfresco folder
doFolderStatus( alfresco);
}
else {
// Build a list of the file names
StringList fileList;
for ( int i = 1; i < argc; i++)
fileList.addString( String(argv[i]));
// fileList.addString(L"N:\\testArea\\msword\\CIFSLOG.doc");
// fileList.addString(L"\\\\StarlaA\\Alfresco\\Garys Space\\CIFSLOG.doc");
// Process the file list and check in or out each file
doCheckInOut( alfresco, fileList);
}
}
else {
wcout << L"%% Not a valid Alfresco CIFS folder, " << folderPath << endl;
return 1;
}
// Wait for user input
wcout << L"Press <Enter> to continue ..." << flush;
getchar();
}
/**
* Display file status of the files in the target Alfresco folder
*
* @param Alfresco& alfresco
* @param const wchar_t* fileSpec
* @return bool
*/
bool doFolderStatus( Alfresco& alfresco, const wchar_t* fileSpec) {
// Get the base UNC path
String uncPath = alfresco.getUNCPath();
uncPath.append(PathSeperator);
// Search the Alfresco folder
WIN32_FIND_DATA findData;
String searchPath = uncPath;
searchPath.append( fileSpec);
bool sts = false;
HANDLE fHandle = FindFirstFile( searchPath, &findData);
if ( fHandle != INVALID_HANDLE_VALUE) {
// Loop until all files have been returned
PTR_AlfrescoFileInfo pFileInfo;
sts = true;
while ( fHandle != INVALID_HANDLE_VALUE) {
// Get the file name, ignore the '.' and '..' files
String fName = findData.cFileName;
if ( fName.equals(L".") || fName.equals(L"..")) {
// Get the next file/folder name in the search
if ( FindNextFile( fHandle, &findData) == 0)
fHandle = INVALID_HANDLE_VALUE;
continue;
}
// Get the file information for the current file folder
pFileInfo = alfresco.getFileInformation( findData.cFileName);
if ( pFileInfo.get() != NULL) {
// Output the file details
wcout << pFileInfo->getName() << endl;
if ( pFileInfo->isType() == TypeFolder)
wcout << L" [Folder]" << endl;
if ( pFileInfo->isWorkingCopy())
wcout << L" [Work: " << pFileInfo->getCopyOwner() << L", " << pFileInfo->getCopiedFrom() << L"]" << endl;
if ( pFileInfo->getLockType() != LockNone)
wcout << L" [Lock: " << (pFileInfo->getLockType() == LockRead ? L"READ" : L"WRITE") << L", " <<
pFileInfo->getLockOwner() << L"]" << endl;
if ( pFileInfo->hasContent())
wcout << L" [Content: " << pFileInfo->getContentLength() << L", " << pFileInfo->getContentType() << L"]" << endl;;
// Get the next file/folder name in the search
if ( FindNextFile( fHandle, &findData) == 0)
fHandle = INVALID_HANDLE_VALUE;
}
else {
sts = false;
fHandle = INVALID_HANDLE_VALUE;
}
}
}
// Return status
return sts;
}
/**
* Process the list of files and check in or out each file
*
* @param alfresco Alfresco&
* @param files StringList&
*/
bool doCheckInOut( Alfresco& alfresco, StringList& files) {
// Process the list of files and either check in the file if it is a working copy or check out
// the file
for ( unsigned int i = 0; i < files.numberOfStrings(); i++) {
// Get the current file name
String curFile = files.getStringAt( i);
// Check if the path is on an Alfresco mapped drive
if ( alfresco.isMappedDrive() && curFile.startsWithIgnoreCase( alfresco.getDrivePath())) {
// Convert the path to a UNC path
String uncPath = alfresco.getRootPath();
uncPath.append( curFile.substring(2));
curFile = uncPath;
}
// Check that the path is to a file
bool copyFile = false;
DWORD attr = GetFileAttributes( curFile);
if ( attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
// Get the file name from the path
StringList nameParts = FileName::splitPath( curFile);
String curName = nameParts.getStringAt( 1);
// Get the Alfresco file status information
PTR_AlfrescoFileInfo pFileInfo = alfresco.getFileInformation( curName);
// If the path is to a file that is not on the Alfresco share the file will need to be copied,
// after checking the status of a matching file in the Alfresco folder
if ( curFile.length() >= 3 && curFile.substring(1,3).equals( L":\\")) {
// Check if there is an existing file with the same name
if ( pFileInfo.get() != NULL) {
// Check if the file is a working copy
if ( pFileInfo->isWorkingCopy()) {
// Local file matches a working copy file in the Alfresco folder
wcout << L"Found matching working copy for local file " << curName << endl;
}
else if ( pFileInfo->getLockType() != LockNone) {
// File is locked, may be the original document
wcout << L"%% Destination file " << curName << L" is locked" << endl;
return false;
}
else {
// Indicate that we have copied a new file to the Alfresco share, do not check in/out
copyFile = true;
}
}
else {
// Indicate that we have copied a new file to the Alfresco share, do not check in/out
copyFile = true;
}
// Build the from/to paths, must be double null terminated
wchar_t fromPath[MAX_PATH + 1];
wchar_t toPath[MAX_PATH + 1];
memset( fromPath, 0, sizeof( fromPath));
memset( toPath, 0, sizeof( toPath));
wcscpy( fromPath, curFile.data());
wcscpy( toPath, alfresco.getUNCPath());
// Copy the local file to the Alfresco folder
SHFILEOPSTRUCT fileOpStruct;
memset( &fileOpStruct, 0, sizeof(SHFILEOPSTRUCT));
fileOpStruct.hwnd = HWND_DESKTOP;
fileOpStruct.wFunc = FO_COPY;
fileOpStruct.pFrom = fromPath;
fileOpStruct.pTo = toPath;
fileOpStruct.fFlags= 0;
fileOpStruct.fAnyOperationsAborted =false;
// Copy the file to the Alfresco folder
if ( SHFileOperation( &fileOpStruct) != 0) {
// File copy failed
wcout << L"%% Failed to copy file " << curFile << endl;
return false;
}
else if ( fileOpStruct.fAnyOperationsAborted) {
// User aborted the file copy
wcout << L"%% Copy aborted for " << curFile << endl;
return false;
}
// Get the file information for the copied file
pFileInfo = alfresco.getFileInformation( curName);
}
// Check in or check out the file
if ( pFileInfo.get() != NULL) {
// Check if the file should be checked in/out
if ( copyFile == false) {
// Check if the file is a working copy, if so then check it in
if ( pFileInfo->isWorkingCopy()) {
// Check in the file
doCheckIn( alfresco, pFileInfo);
}
else if ( pFileInfo->getLockType() == LockNone) {
// Check out the file
doCheckOut( alfresco, pFileInfo);
}
else {
// File is locked, may already be checked out
wcout << L"%% File " << curFile << L" is locked" << endl;
}
}
else {
// No existing file to link the copied file to
wcout << L"Copied file " << curFile << L" to Alfresco share" << endl;
}
}
else
wcout << L"%% Failed to get file status for " << curFile << endl;
}
else
wcout << L"%% Path " << curFile << L" is a folder, ignored" << endl;
}
// Return status
return true;
}
/**
* Check in the specified file
*
* @param alfresco Alfresco&
* @param pFileInfo PTR_AlfrescoFileInfo&
* @return bool
*/
bool doCheckIn( Alfresco& alfresco, PTR_AlfrescoFileInfo& pFileInfo) {
bool checkedIn = false;
try {
// Check in the specified file
alfresco.checkIn( pFileInfo->getName());
wcout << L"Checked in file " << pFileInfo->getName() << endl;
// Indicate that the check in was successful
checkedIn = true;
}
catch (Exception ex) {
wcerr << L"%% Error checking in file " << pFileInfo->getName() << endl;
wcerr << L" " << ex.getMessage() << endl;
}
// Return the check in status
return checkedIn;
}
/**
* Check out the specified file
*
* @param alfresco Alfresco&
* @param pFileInfo PTR_AlfrescoFileInfo&
* @return bool
*/
bool doCheckOut( Alfresco& alfresco, PTR_AlfrescoFileInfo& pFileInfo) {
bool checkedOut = false;
try {
// Check out the specified file
String workingCopy;
alfresco.checkOut( pFileInfo->getName(), workingCopy);
wcout << L"Checked out file " << pFileInfo->getName() << " to " << workingCopy << endl;
// Indicate that the check out was successful
checkedOut = true;
}
catch (Exception ex) {
wcerr << L"%% Error checking out file " << pFileInfo->getName() << endl;
wcerr << L" " << ex.getMessage() << endl;
}
// Return the check out status
return checkedOut;
}

View File

@@ -0,0 +1,173 @@
/*
* Copyright (C) 2005-2006 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.
*/
#include "alfresco\Desktop.hpp"
#include "util\Exception.h"
#include "util\Integer.h"
using namespace Alfresco;
using namespace std;
// Define exceptions
EXCEPTION_CLASS(Alfresco, DesktopActionException);
/**
* Class constructor
*
* @param typ Target type
* @param path Target path/id
*/
DesktopTarget::DesktopTarget(int typ, String& path) {
// Set the target type and path
m_type = typ;
m_target = path;
}
/**
* Return the target type as a string
*
* @return const String
*/
const String DesktopTarget::getTypeAsString() const {
String typStr;
switch ( isType()) {
case TargetFile:
typStr = L"File";
break;
case TargetFolder:
typStr = L"Folder";
break;
case TargetCopiedFile:
typStr = L"File Copy";
break;
case TargetCopiedFolder:
typStr = L"Folder Copy";
break;
case TargetNodeRef:
typStr = L"NodeRef";
break;
}
return typStr;
}
/**
* Return the target details as a string
*
* @return const String
*/
const String DesktopTarget::toString( void) const {
String str = L"[";
str.append(getTypeAsString());
str.append(L":");
str.append(getTarget());
str.append(L"]");
return str;
}
/**
* Equality operator
*
* @param target const DekstopTarget&
* @return bool
*/
bool DesktopTarget::operator==( const DesktopTarget& target) {
if ( isType() == target.isType() &&
getTarget().equals(target.getTarget()))
return true;
return false;
}
/**
* Less than operator
*
* @param target const DesktopTarget&
* @return bool
*/
bool DesktopTarget::operator<( const DesktopTarget& target) {
if ( isType() == target.isType())
return getTarget() < target.getTarget();
else
return isType() < target.isType();
}
/**
* Return the required desktop target
*
* @param idx const unsigned int
* @return const DesktopTarget*
*/
const DesktopTarget* DesktopParams::getTarget(const unsigned int idx) const {
// Range check the index
if ( idx > m_list.size())
return NULL;
// Return the required target
return m_list[idx];
}
/**
* Return the desktop parameters as a string
*
* @return const String
*/
const String DesktopParams::toString(void) const {
String str = L"[";
str.append(L"Targets=");
str.append((unsigned int)numberOfTargets());
str.append(L"]");
return str;
}
/**
* Class constructor
*
* @param sts const unsigned int
* @param msg const wchar_t*
*/
DesktopResponse::DesktopResponse(const unsigned int sts, const wchar_t* msg) {
m_status = sts;
if ( msg != NULL)
m_statusMsg = msg;
}
/**
* Assignment operator
*
* @param response const DesktopResponse&
* @return DesktopResponse&
*/
DesktopResponse& DesktopResponse::operator=( const DesktopResponse& response) {
m_status = response.getStatus();
m_statusMsg = response.getStatusMessage();
return *this;
}