/*
* 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 .
*/
package org.alfresco.repo.remote;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.util.List;
import org.alfresco.repo.content.encoding.ContentCharsetFinder;
import org.alfresco.repo.model.filefolder.FileFolderServiceImpl;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileFolderService;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.remote.FileFolderRemote;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.MimetypeService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
/**
* Server side implementation of the FileFolderService transport
* layer. This is the class that gets exported remotely as it contains the
* explicit ticket arguments.
*
* @author Derek Hulley
* @since 2.2
*/
public class FileFolderRemoteServer implements FileFolderRemote
{
private RetryingTransactionHelper retryingTransactionHelper;
private AuthenticationService authenticationService;
private FileFolderService fileFolderService;
private MimetypeService mimetypeService;
/**
* @param transactionService provides transactional support and retrying
*/
public void setTransactionService(TransactionService transactionService)
{
this.retryingTransactionHelper = transactionService.getRetryingTransactionHelper();
}
/**
* @param authenticationService the service that will validate the tickets
*/
public void setAuthenticationService(AuthenticationService authenticationService)
{
this.authenticationService = authenticationService;
}
/**
* @param filefolderService the service that will do the work
*/
public void setFileFolderService(FileFolderService filefolderService)
{
this.fileFolderService = filefolderService;
}
/**
* @param mimetypeService used to determine the character encoding
*/
public void setMimetypeService(MimetypeService mimetypeService)
{
this.mimetypeService = mimetypeService;
}
/**
* {@inheritDoc}
*/
public List list(String ticket, final NodeRef contextNodeRef)
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback> callback = new RetryingTransactionCallback>()
{
public List execute() throws Throwable
{
return fileFolderService.list(contextNodeRef);
}
};
return retryingTransactionHelper.doInTransaction(callback, true, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public List listFiles(String ticket, final NodeRef folderNodeRef)
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback> callback = new RetryingTransactionCallback>()
{
public List execute() throws Throwable
{
return fileFolderService.listFiles(folderNodeRef);
}
};
return retryingTransactionHelper.doInTransaction(callback, true, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public List listFolders(String ticket, final NodeRef contextNodeRef)
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback> callback = new RetryingTransactionCallback>()
{
public List execute() throws Throwable
{
return fileFolderService.listFolders(contextNodeRef);
}
};
return retryingTransactionHelper.doInTransaction(callback, true, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public NodeRef searchSimple(String ticket, final NodeRef contextNodeRef, final String name)
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback callback = new RetryingTransactionCallback()
{
public NodeRef execute() throws Throwable
{
return fileFolderService.searchSimple(contextNodeRef, name);
}
};
return retryingTransactionHelper.doInTransaction(callback, true, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public List search(
String ticket,
final NodeRef contextNodeRef,
final String namePattern,
final boolean includeSubFolders)
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback> callback = new RetryingTransactionCallback>()
{
public List execute() throws Throwable
{
return fileFolderService.search(contextNodeRef, namePattern, includeSubFolders);
}
};
return retryingTransactionHelper.doInTransaction(callback, true, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public List search(
String ticket,
final NodeRef contextNodeRef,
final String namePattern,
final boolean fileSearch,
final boolean folderSearch,
final boolean includeSubFolders)
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback> callback = new RetryingTransactionCallback>()
{
public List execute() throws Throwable
{
return fileFolderService.search(contextNodeRef, namePattern, fileSearch, folderSearch, includeSubFolders);
}
};
return retryingTransactionHelper.doInTransaction(callback, true, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public FileInfo rename(String ticket, final NodeRef fileFolderRef, final String newName) throws FileExistsException, FileNotFoundException
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback callback = new RetryingTransactionCallback()
{
public FileInfo execute() throws Throwable
{
return fileFolderService.rename(fileFolderRef, newName);
}
};
return retryingTransactionHelper.doInTransaction(callback, false, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public FileInfo move(String ticket, final NodeRef sourceNodeRef, final NodeRef targetParentRef, final String newName)
throws FileExistsException, FileNotFoundException
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback callback = new RetryingTransactionCallback()
{
public FileInfo execute() throws Throwable
{
return fileFolderService.move(sourceNodeRef, targetParentRef, newName);
}
};
return retryingTransactionHelper.doInTransaction(callback, false, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public FileInfo copy(String ticket, final NodeRef sourceNodeRef, final NodeRef targetParentRef, final String newName)
throws FileExistsException, FileNotFoundException
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback callback = new RetryingTransactionCallback()
{
public FileInfo execute() throws Throwable
{
return fileFolderService.copy(sourceNodeRef, targetParentRef, newName);
}
};
return retryingTransactionHelper.doInTransaction(callback, false, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public FileInfo create(String ticket, final NodeRef parentNodeRef, final String name, final QName typeQName) throws FileExistsException
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback callback = new RetryingTransactionCallback()
{
public FileInfo execute() throws Throwable
{
return fileFolderService.create(parentNodeRef, name, typeQName);
}
};
return retryingTransactionHelper.doInTransaction(callback, false, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public FileInfo[] create(String ticket, final NodeRef[] parentNodeRefs, final String[] names, final QName[] typesQName) throws FileExistsException
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback callback = new RetryingTransactionCallback()
{
public FileInfo[] execute() throws Throwable
{
FileInfo[] result = new FileInfo[parentNodeRefs.length];
for (int i = 0; i< result.length; i++)
{
result[i] = fileFolderService.create(parentNodeRefs[i], names[i], typesQName[i]);
}
return result;
}
};
return retryingTransactionHelper.doInTransaction(callback, false, true);
}
finally
{
AuthenticationUtil.popAuthentication();
}
}
/**
* {@inheritDoc}
*/
public void delete(String ticket, final NodeRef nodeRef)
{
AuthenticationUtil.pushAuthentication();
try
{
authenticationService.validate(ticket, null);
// Make the call
RetryingTransactionCallback