2006-05-04 12:37:20 +00:00

507 lines
12 KiB
C++

/*
* 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 "stdafx.h"
#include "CAlfrescoApp.h"
#include "CAlfrescoAppDlg.h"
#include "FileStatusDialog.h"
#include <stdlib.h>
#include "util\String.h"
#include "util\DataBuffer.h"
#include "util\FileName.h"
#include <shellapi.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
using namespace Alfresco;
// CCAlfrescoAppApp
BEGIN_MESSAGE_MAP(CCAlfrescoAppApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
// CCAlfrescoAppApp construction
CCAlfrescoAppApp::CCAlfrescoAppApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
// The one and only CCAlfrescoAppApp object
CCAlfrescoAppApp theApp;
// CCAlfrescoAppApp initialization
BOOL CCAlfrescoAppApp::InitInstance()
{
// InitCommonControls() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
InitCommonControls();
CWinApp::InitInstance();
AfxEnableControlContainer();
// Get the application path
String appPath = __wargv[0];
int pos = appPath.lastIndexOf(PathSeperator);
if ( pos < 0) {
AfxMessageBox( L"Invalid application path", MB_OK | MB_ICONSTOP);
return 1;
}
// Get the path to the folder containing the application
String folderPath = appPath.substring(0, pos);
// Create the Alfresco interface
AlfrescoInterface alfresco(folderPath);
if ( alfresco.isAlfrescoFolder()) {
try {
// 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(__wargv[i]));
// Process the file list and check in or out each file
doCheckInOut( alfresco, fileList);
}
}
catch (Exception ex) {
CString msg;
msg.FormatMessage( L"Exception occurred\n\n%1", ex.getMessage().data());
AfxMessageBox( msg, MB_OK | MB_ICONSTOP);
}
}
else {
AfxMessageBox( L"Not a valid Alfresco CIFS folder", MB_OK | MB_ICONSTOP);
return 1;
}
// Run the main dialog
/**
CCAlfrescoAppDlg dlg;
m_pMainWnd = &dlg;
INT_PTR nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
**/
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
/**
* Display file status of the files in the target Alfresco folder
*
* @param AlfrescoInterface& alfresco
* @param const wchar_t* fileSpec
* @return bool
*/
bool CCAlfrescoAppApp::doFolderStatus( AlfrescoInterface& 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);
AlfrescoFileInfoList fileList;
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) {
// Add the file to the list
fileList.addInfo( pFileInfo);
}
// Get the next file/folder name in the search
if ( FindNextFile( fHandle, &findData) == 0)
fHandle = INVALID_HANDLE_VALUE;
}
}
// Display the file status dialog if there are files to display
if ( fileList.size() > 0) {
// Display the file status dialog
CFileStatusDialog dlg( fileList);
dlg.DoModal();
}
else {
CString msg;
msg.FormatMessage( L"No files found in %1", uncPath.data());
AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION);
}
// Return status
return sts;
}
/**
* Process the list of files and check in or out each file
*
* @param alfresco AlfrescoInterface&
* @param files StringList&
*/
bool CCAlfrescoAppApp::doCheckInOut( AlfrescoInterface& 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
CString msg;
msg.FormatMessage( L"Found matching working copy for local file %1", curName.data());
AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION);
}
else if ( pFileInfo->getLockType() != LockNone) {
// File is locked, may be the original document
CString msg;
msg.FormatMessage( L"Destination file %1 is locked", curName.data());
AfxMessageBox( msg, MB_OK | MB_ICONSTOP);
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
CString msg;
msg.FormatMessage( L"Failed to copy file %1", curFile.data());
AfxMessageBox( msg, MB_OK | MB_ICONSTOP);
return false;
}
else if ( fileOpStruct.fAnyOperationsAborted) {
// User aborted the file copy
CString msg;
msg.FormatMessage( L"Copy aborted for %1", curFile.data());
AfxMessageBox( msg, MB_OK | MB_ICONSTOP);
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
CString msg;
msg.FormatMessage( L"File %1 is locked", curFile.data());
AfxMessageBox( msg, MB_OK | MB_ICONSTOP);
}
}
else {
// No existing file to link the copied file to
CString msg;
msg.FormatMessage( L"Copied file %1 to Alfresco folder", curFile.data());
AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION);
}
}
else {
CString msg;
msg.FormatMessage( L"Failed to get file status for %1", curFile.data());
AfxMessageBox( msg, MB_OK | MB_ICONSTOP);
}
}
else {
// Check the error status
CString msg;
if ( attr != INVALID_FILE_ATTRIBUTES)
msg.FormatMessage( L"Path %1 is a folder, ignored", curFile.data());
else
msg.FormatMessage( L"File %1 does not exist", curFile.data());
AfxMessageBox( msg, MB_OK | MB_ICONSTOP);
}
}
// Return status
return true;
}
/**
* Check in the specified file
*
* @param alfresco AlfrescoInterface&
* @param pFileInfo PTR_AlfrescoFileInfo&
* @return bool
*/
bool CCAlfrescoAppApp::doCheckIn( AlfrescoInterface& alfresco, PTR_AlfrescoFileInfo& pFileInfo) {
bool checkedIn = false;
try {
// Check in the specified file
alfresco.checkIn( pFileInfo->getName());
CString msg;
msg.FormatMessage( L"Checked in file %1", pFileInfo->getName().data());
AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION);
// Indicate that the check in was successful
checkedIn = true;
}
catch (Exception ex) {
CString msg;
msg.FormatMessage( L"Error checking in file %1\n\n%2", pFileInfo->getName().data(), ex.getMessage().data());
AfxMessageBox( msg, MB_OK | MB_ICONSTOP);
}
// Return the check in status
return checkedIn;
}
/**
* Check out the specified file
*
* @param alfresco AlfrescoInterface&
* @param pFileInfo PTR_AlfrescoFileInfo&
* @return bool
*/
bool CCAlfrescoAppApp::doCheckOut( AlfrescoInterface& alfresco, PTR_AlfrescoFileInfo& pFileInfo) {
bool checkedOut = false;
try {
// Check out the specified file
String workingCopy;
alfresco.checkOut( pFileInfo->getName(), workingCopy);
CString msg;
msg.FormatMessage( L"Checked out file %1 to %2", pFileInfo->getName().data(), workingCopy.data());
AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION);
// Indicate that the check out was successful
checkedOut = true;
}
catch (Exception ex) {
CString msg;
msg.FormatMessage( L"Error checking out file %1\n\n%2", pFileInfo->getName().data(), ex.getMessage().data());
AfxMessageBox( msg, MB_OK | MB_ICONSTOP);
}
// Return the check out status
return checkedOut;
}