package fr.itldev.koya.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.repo.policy.BehaviourFilter;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
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.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentIOException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.site.SiteInfo;
import org.alfresco.service.cmr.site.SiteService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.TempFileProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.google.common.base.Stopwatch;
import fr.itldev.koya.action.importXml.model.ContentXml;
import fr.itldev.koya.action.importXml.model.ContentsXmlWrapper;
import fr.itldev.koya.action.importXml.model.DossierXml;
import fr.itldev.koya.action.importXml.model.DossiersXmlWrapper;
import fr.itldev.koya.alfservice.DossierService;
import fr.itldev.koya.alfservice.KoyaContentService;
import fr.itldev.koya.alfservice.KoyaNodeService;
import fr.itldev.koya.alfservice.UserService;
import fr.itldev.koya.alfservice.security.SpaceAclService;
import fr.itldev.koya.exception.KoyaServiceException;
import fr.itldev.koya.model.KoyaModel;
import fr.itldev.koya.model.exceptions.KoyaErrorCodes;
import fr.itldev.koya.model.impl.Company;
import fr.itldev.koya.model.impl.Dossier;
import fr.itldev.koya.model.impl.User;
import fr.itldev.koya.model.permissions.KoyaPermissionCollaborator;
import fr.itldev.koya.model.permissions.SitePermission;
import fr.itldev.koya.utils.Zips;
public class DossierImportActionExecuter extends ActionExecuterAbstractBase {
private Log logger = LogFactory.getLog(DossierImportActionExecuter.class);
public static final String NAME = "koyaDossierImport";
private SiteService siteService;
private NodeService nodeService;
private ContentService contentService;
private DossierService dossierService;
private UserService userService;
private SpaceAclService spaceAclService;
private KoyaNodeService koyaNodeService;
private KoyaContentService koyaContentService;
private AuthenticationService authenticationService;
private BehaviourFilter policyBehaviourFilter;
private FileFolderService fileFolderService;
private TransactionService transactionService;
private String defaultZipCharset;
private String failoverZipCharset;
// <editor-fold defaultstate="collapsed" desc="getters/setters">
public void setSiteService(SiteService siteService) {
this.siteService = siteService;
}
public void setNodeService(NodeService nodeService) {
this.nodeService = nodeService;
}
public void setContentService(ContentService contentService) {
this.contentService = contentService;
}
public void setDossierService(DossierService dossierService) {
this.dossierService = dossierService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
public void setSpaceAclService(SpaceAclService spaceAclService) {
this.spaceAclService = spaceAclService;
}
public void setKoyaNodeService(KoyaNodeService koyaNodeService) {
this.koyaNodeService = koyaNodeService;
}
public void setKoyaContentService(KoyaContentService koyaContentService) {
this.koyaContentService = koyaContentService;
}
public void setAuthenticationService(
AuthenticationService authenticationService) {
this.authenticationService = authenticationService;
}
public void setPolicyBehaviourFilter(BehaviourFilter policyBehaviourFilter) {
this.policyBehaviourFilter = policyBehaviourFilter;
}
public void setFileFolderService(FileFolderService fileFolderService) {
this.fileFolderService = fileFolderService;
}
public void setDefaultZipCharset(String defaultZipCharset) {
this.defaultZipCharset = defaultZipCharset;
}
public void setFailoverZipCharset(String failoverZipCharset) {
this.failoverZipCharset = failoverZipCharset;
}
public void setTransactionService(TransactionService transactionService) {
this.transactionService = transactionService;
}
// </editor-fold>
private static final String TEMP_FILE_PREFIX = "koya";
private static final String TEMP_FILE_SUFFIX_ZIP = ".zip";
private static final String FILE_DOSSIERS_XML = "dossiers_import.xml";
private static final String FILE_CONTENT_ZIP = "Documents.zip";
private static final String FILE_CONTENT_XML = "documents_import.xml";
private static final String FOLDER_CONTENTS = "contents";
private static final String PROCESSED_ARCHIVE_DIRECTORY = "processed";
private static final List<SitePermission> societePermissions = new ArrayList<SitePermission>() {
{
add(SitePermission.MANAGER);
add(SitePermission.COLLABORATOR);
}
};
@Override
protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
String username = authenticationService.getCurrentUserName();
File tempFile = null;
File tempDir = null;
if (!this.nodeService.exists(actionedUponNodeRef)) {
return;
}
policyBehaviourFilter.disableBehaviour(ContentModel.ASPECT_AUDITABLE);
String zipName = (String) nodeService.getProperty(actionedUponNodeRef,
ContentModel.PROP_NAME);
ContentData contentRef = (ContentData) nodeService.getProperty(
actionedUponNodeRef, ContentModel.PROP_CONTENT);
long zipSizeBytes = 0;
try {
zipSizeBytes = contentRef.getSize();
} catch (Exception e) {
}
if (!zipName.toLowerCase().endsWith(".zip")) {
return; // Not a zip file.
}
StringBuffer sbLog = new StringBuffer();
ImportDossierStat dossierStat = new ImportDossierStat();
ImportContentStat contentStat = new ImportContentStat();
SiteInfo siteInfo = siteService.getSite(actionedUponNodeRef);
NodeRef documentLibrary = siteService.getContainer(
siteInfo.getShortName(), SiteService.DOCUMENT_LIBRARY);
Map<String, Dossier> mapCacheDossier = new HashMap<String, Dossier>();
Set<Dossier> modifiedDossiers = new HashSet<>();
Stopwatch timer = new Stopwatch().start();
try {
Company company = koyaNodeService.getKoyaNode(
siteInfo.getNodeRef(), Company.class);
String companyName = company.getName();
logger.trace(getLogPrefix(companyName, username)
+ "Import Xml Started");
sbLog.append("Import start at " + new Date() + "\n");
// The node being passed in should be an Alfresco content
// package
ContentReader reader = this.contentService.getReader(
actionedUponNodeRef, ContentModel.PROP_CONTENT);
if (reader != null) {
// perform an dossiers import of a standard ZIP file
// unfortunately a ZIP file can not be read directly from an
// input stream so we have to create a temporary file first
tempFile = TempFileProvider.createTempFile(TEMP_FILE_PREFIX,
TEMP_FILE_SUFFIX_ZIP);
reader.getContent(tempFile);
// build a temp dir name based on the ID of the noderef we are
// importing also use the long life temp folder as large ZIP
// files can take a while
File alfTempDir = TempFileProvider.getLongLifeTempDir("import");
tempDir = new File(alfTempDir.getPath() + File.separatorChar
+ actionedUponNodeRef.getId());
// TODO: improve this code to directly pipe the zip stream
// output into the repo objects -
// to remove the need to expand to the filesystem first?
logger.trace(getLogPrefix(companyName, username)
+ "Extracting " + zipName + " ("
+ tempFile.getAbsolutePath() + ")" + " to "
+ tempDir.getAbsolutePath());
Zips.unzip(tempFile.getAbsolutePath(),
tempDir.getAbsolutePath(), defaultZipCharset,
failoverZipCharset, sbLog);
dossierStat = importDossier(tempDir, company, documentLibrary,
mapCacheDossier, modifiedDossiers, sbLog);
// Importing new content into the dossiers
File fileContentZip = new File(tempDir, FILE_CONTENT_ZIP);
if (fileContentZip.exists()) {
// Extract content zip file
File contentsDir = new File(tempDir, FOLDER_CONTENTS);
logger.trace(getLogPrefix(companyName, username)
+ "Extracting " + fileContentZip.getName() + " to "
+ contentsDir.getAbsolutePath());
Zips.unzip(fileContentZip.getAbsolutePath(),
contentsDir.getAbsolutePath(), defaultZipCharset,
failoverZipCharset, sbLog);
contentStat = importContent(contentsDir, company,
mapCacheDossier, modifiedDossiers, sbLog);
}
}
} catch (InvalidNodeRefException | InvalidTypeException
| ContentIOException ex) {
throw new AlfrescoRuntimeException(getLogPrefix(null, username)
+ " " + ex.getMessage(), ex);
} finally {
NodeRef importDirNodeRef = nodeService.getPrimaryParent(
actionedUponNodeRef).getParentRef();
// moving imported zip archive
NodeRef processedNodeRef = fileFolderService.searchSimple(
importDirNodeRef, PROCESSED_ARCHIVE_DIRECTORY);
if (processedNodeRef == null) {
processedNodeRef = fileFolderService.create(importDirNodeRef,
PROCESSED_ARCHIVE_DIRECTORY, ContentModel.TYPE_FOLDER)
.getNodeRef();
}
try {
fileFolderService.move(actionedUponNodeRef, processedNodeRef,
null);
} catch (FileExistsException ex) {
int i = 0;
String zipFileName = zipName.substring(0,
zipName.indexOf(".zip"));
while (fileFolderService.searchSimple(processedNodeRef,
zipFileName + "-" + (++i) + ".zip") != null) {
}
try {
fileFolderService.move(actionedUponNodeRef,
processedNodeRef, zipFileName + "-" + i + ".zip");
} catch (FileExistsException
| org.alfresco.service.cmr.model.FileNotFoundException ex1) {
sbLog.append("\nCan't move zip archive to "
+ PROCESSED_ARCHIVE_DIRECTORY);
sbLog.append(ex.getMessage());
logger.error(ex.getMessage(), ex);
}
} catch (org.alfresco.service.cmr.model.FileNotFoundException ex) {
sbLog.append("\nCan't move zip archive to "
+ PROCESSED_ARCHIVE_DIRECTORY);
sbLog.append(ex.getMessage());
logger.error(ex.getMessage(), ex);
}
// Writing down the log file
String logFilename = zipName + ".log";
NodeRef logNodeRef = fileFolderService.searchSimple(
importDirNodeRef, logFilename);
ContentWriter logWriter;
if (logNodeRef != null) {
logWriter = fileFolderService.getWriter(logNodeRef);
} else {
FileInfo logInfo = fileFolderService.create(importDirNodeRef,
logFilename, ContentModel.TYPE_CONTENT);
logWriter = fileFolderService.getWriter(logInfo.getNodeRef());
}
// logWriter.putContent(sbLog.toString());
FileChannel fileChannel = logWriter.getFileChannel(false);
ByteBuffer bf = ByteBuffer
.wrap(("=======================\n\n\n" + sbLog.toString())
.getBytes());
try {
fileChannel.position(logWriter.getSize());
fileChannel.write(bf);
fileChannel.force(false);
fileChannel.close();
} catch (IOException ex) {
logger.error(ex.getMessage(), ex);
}
deleteDir(tempDir);
// now the import is done, delete the temporary file
if (tempFile != null) {
tempFile.delete();
}
timer.stop();
logger.info("[Import report] {\"zip\":\"" + zipName + "\","
+ "\"zipSizeBytes\":\"" + zipSizeBytes + "\","
+ "\"execSeconds\":\""
+ timer.elapsedTime(TimeUnit.SECONDS) + "\"," + dossierStat
+ "," + contentStat + "}");
}
for (Dossier d : modifiedDossiers) {
dossierService.updateLastModificationDate(d);
}
}
private ImportDossierStat importDossier(File tempDir, Company company,
NodeRef documentLibrary, Map<String, Dossier> mapCacheDossier,
Set<Dossier> modifiedDossiers, final StringBuffer sbLog) {
String userName = authenticationService.getCurrentUserName();
String companyName = company.getName();
ImportDossierStat dossierStat = new ImportDossierStat();
// Reading the new dossiers to create
File fileDossiersXml = new File(tempDir, FILE_DOSSIERS_XML);
if (fileDossiersXml.exists()) {
// Create new dossiers
List<DossierXml> dossierXmls = null;
try {
logger.trace(getLogPrefix(companyName, userName)
+ "Unmarshalling " + fileDossiersXml.getName());
sbLog.append("\n\nUnmarshalling " + fileDossiersXml.getName());
JAXBContext context = JAXBContext.newInstance(
DossiersXmlWrapper.class, DossierXml.class);
DossiersXmlWrapper dossiersXmlWrapper = (DossiersXmlWrapper) context
.createUnmarshaller().unmarshal(fileDossiersXml);
if (dossiersXmlWrapper != null) {
dossierXmls = dossiersXmlWrapper.getDossiers();
}
} catch (JAXBException ex) {
sbLog.append("Error unmarshalling dossiers metadata. "
+ ex.getMessage());
throw new AlfrescoRuntimeException(getLogPrefix(companyName,
userName) + "Error unmarshalling dossiers metadata.",
ex);
}
if (dossierXmls != null) {
dossierStat.countDossier = dossierXmls.size();
logger.trace(getLogPrefix(companyName, userName)
+ dossierXmls.size() + " dossiers found");
sbLog.append("\n" + dossierStat.countDossier
+ " dossiers found");
for (final DossierXml dossierXml : dossierXmls) {
if (dossierXml.getReference() == null) {
continue;
}
String space = dossierXml.getSpace();
if (space == null || space.isEmpty()) {
space = "defaultSpace";
}
String dossierTitle = dossierXml.getReference() + " - "
+ dossierXml.getName();
NodeRef spaceNodeRef = nodeService
.getChildByName(documentLibrary,
ContentModel.ASSOC_CONTAINS, space);
boolean newDossier = false;
Dossier d = null;
try {
// Try to get dossier by reference (if exists)
d = dossierService.getDossier(company,
dossierXml.getReference());
if (d != null) {
// Dossier already exists
if (!d.getTitle().equals(dossierTitle)) {
sbLog.append("\nUpdating dossier "
+ d.getTitle() + " to " + dossierTitle);
koyaNodeService.rename(d.getNodeRef(),
dossierXml.getReference() + " - "
+ dossierXml.getName());
d = koyaNodeService.getKoyaNode(d.getNodeRef(),
Dossier.class);
} else {
sbLog.append("\nFound dossier " + d.getTitle());
}
dossierStat.countDossiersDuplicate++;
} else {
logger.trace(getLogPrefix(companyName, userName)
+ "Creating dossier " + dossierTitle
+ " into " + spaceNodeRef);
// New dossier have to created
sbLog.append("\nCreating dossier "
+ dossierXml.getReference() + " - "
+ dossierXml.getName());
/**
* Create dossier in a separated transaction.
* Permissions groups are created when trying to add
* collaborators permissions
*/
UserTransaction transaction = transactionService
.getNonPropagatingUserTransaction();
try {
transaction.begin();
Map<QName, String> props = new HashMap<QName, String>();
props.put(KoyaModel.PROP_REFERENCE,
dossierXml.getReference());
d = dossierService.create(
dossierXml.getReference() + " - "
+ dossierXml.getName(),
spaceNodeRef, props);
transaction.commit();
} catch (Exception e) {
try {
transaction.rollback();
} catch (IllegalStateException
| SecurityException | SystemException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
newDossier = true;
modifiedDossiers.add(d);
dossierStat.countDossiersCreated++;
}
} catch (Exception e) {
logger.error(
getLogPrefix(companyName, userName)
+ "Cannot create dossier "
+ dossierXml.getReference(), e);
sbLog.append("\nCannot create dossier "
+ dossierXml.getReference() + " : "
+ e.getMessage());
dossierStat.countDossiersError++;
continue;
}
mapCacheDossier.put(dossierXml.getReference(), d);
logger.trace(getLogPrefix(companyName, userName)
+ "Get dossier responsibles");
addKoyaPermissionCollaborator(company, d,
dossierXml.getResponsibles(),
KoyaPermissionCollaborator.RESPONSIBLE, newDossier,
sbLog);
logger.trace(getLogPrefix(companyName, userName)
+ "get dossier members");
addKoyaPermissionCollaborator(company, d,
dossierXml.getMembers(),
KoyaPermissionCollaborator.MEMBER, newDossier,
sbLog);
}
logger.trace(getLogPrefix(companyName, userName)
+ dossierStat.countDossiersCreated
+ " dossiers created");
sbLog.append("\n\n" + dossierStat.countDossiersCreated
+ " dossiers created");
logger.trace(getLogPrefix(companyName, userName)
+ dossierStat.countDossiersDuplicate
+ " dossiers already existing");
sbLog.append("\n" + dossierStat.countDossiersDuplicate
+ " dossiers already existing");
logger.trace(getLogPrefix(companyName, userName)
+ dossierStat.countDossiersError
+ " dossiers not created (error)");
sbLog.append("\n" + dossierStat.countDossiersError
+ " dossiers not created (error)");
}
}
return dossierStat;
}
private class ImportDossierStat {
int countDossier = 0;
int countDossiersCreated = 0;
int countDossiersDuplicate = 0;
int countDossiersError = 0;
@Override
public String toString() {
return "\"ImportDossierStat\":{\"countDossier\":\"" + countDossier
+ "\",\"countDossiersCreated\":\"" + countDossiersCreated
+ "\",\"countDossiersDuplicate\":\""
+ countDossiersDuplicate + "\",\"countDossiersError\":\""
+ countDossiersError + "\"}";
}
}
private ImportContentStat importContent(File contentsDir, Company company,
Map<String, Dossier> mapCacheDossier,
Set<Dossier> modifiedDossiers, final StringBuffer sbLog) {
ImportContentStat contentStat = new ImportContentStat();
String userName = authenticationService.getCurrentUserName();
String companyName = company.getName();
// Reading contents files descriptor
File fileContentXml = new File(contentsDir.getPath(), FILE_CONTENT_XML);
if (!fileContentXml.exists()) {
sbLog.append("\nNo files content metadata file found.");
throw new AlfrescoRuntimeException(getLogPrefix(companyName,
userName) + "No files content metadata file found.");
}
// Create new content
List<ContentXml> contentXmls = null;
try {
logger.trace(getLogPrefix(companyName, userName) + "Unmarshalling "
+ fileContentXml.getName());
sbLog.append("\n\nUnmarshalling " + fileContentXml.getName());
JAXBContext context = JAXBContext.newInstance(
ContentsXmlWrapper.class, ContentXml.class);
ContentsXmlWrapper contentsXmlWrapper = (ContentsXmlWrapper) context
.createUnmarshaller().unmarshal(fileContentXml);
if (contentsXmlWrapper != null) {
contentXmls = contentsXmlWrapper.getContentXmls();
}
} catch (JAXBException ex) {
sbLog.append("\nError unmarshalling dossiers metadata."
+ ex.getMessage());
throw new AlfrescoRuntimeException(getLogPrefix(companyName,
userName) + "Error unmarshalling dossiers metadata.", ex);
}
if (contentXmls == null) {
return contentStat;
}
contentStat.countContent = contentXmls.size();
logger.trace(getLogPrefix(companyName, userName) + contentXmls.size()
+ " contents found");
sbLog.append("\n\n" + contentStat.countContent + " contents found");
for (ContentXml contentXml : contentXmls) {
String filename = null;
String title = null;
try {
Dossier dossier = mapCacheDossier.get(contentXml
.getDossierReference());
if (dossier == null) {
dossier = dossierService.getDossier(company,
contentXml.getDossierReference());
if (dossier == null) {
sbLog.append("\nDossier "
+ contentXml.getDossierReference()
+ " not found");
contentStat.countContentDossierNotFound++;
continue;
}
mapCacheDossier.put(contentXml.getDossierReference(),
dossier);
}
String path = contentXml.getPath();
boolean pathCreated = false;
NodeRef dirNodeRef;
if (path == null || path.isEmpty()) {
dirNodeRef = dossier.getNodeRef();
} else {
dirNodeRef = koyaContentService.makeFolders(
dossier.getNodeRef(),
Arrays.asList(path.split(File.separator)))
.getNodeRef();
pathCreated = true;
}
filename = contentXml.getFilename();
if (filename != null && !filename.trim().isEmpty()) {
int extIdx = filename.lastIndexOf(".");
title = contentXml.getName()
+ (extIdx != -1 ? filename.substring(extIdx) : "");
logger.trace(getLogPrefix(companyName, userName)
+ "Adding " + filename + " to /" + path + " as "
+ title);
sbLog.append("\nAdding " + filename + " to /"
+ dossier.getTitle() + "/" + path);
if (nodeService.getChildByName(dirNodeRef,
ContentModel.ASSOC_CONTAINS, filename) == null) {
koyaContentService.createContentNode(dirNodeRef, title,
filename, new FileInputStream(new File(
contentsDir, filename)));
modifiedDossiers.add(dossier);
contentStat.countContentAdded++;
} else {
logger.error(getLogPrefix(companyName, userName)
+ "File " + filename + " - " + title
+ " already exist in /" + dossier.getTitle()
+ "/" + path);
sbLog.append("\nFile " + filename + " - " + title
+ " already exist in /" + dossier.getTitle()
+ "/" + path);
contentStat.countContentError++;
}
} else if (pathCreated) {
contentStat.countPathCreation++;
}
} catch (FileNotFoundException ex) {
logger.error(ex.getMessage(), ex);
sbLog.append("\n" + filename + " not found");
contentStat.countContentFileNotFound++;
} catch (KoyaServiceException ex) {
// TODO Dossier not found or
// multiple dossiers found
Integer errorCode = ex.getErrorCode();
if (errorCode.equals(KoyaErrorCodes.FILE_UPLOAD_NAME_EXISTS)) {
logger.error(getLogPrefix(companyName, userName) + "File "
+ filename + " - " + title + " already exist");
sbLog.append("\nFile " + filename + " - " + title
+ " already exist in dossier");
contentStat.countContentDuplicate++;
} else {
}
}
}
logger.trace(getLogPrefix(companyName, userName)
+ contentStat.countContentAdded + " contents added");
sbLog.append("\n" + contentStat.countContentAdded + " contents added");
logger.trace(getLogPrefix(companyName, userName)
+ contentStat.countContentDuplicate
+ " contents duplicates name");
sbLog.append("\n" + contentStat.countContentDuplicate
+ " contents duplicates name");
logger.trace(getLogPrefix(companyName, userName)
+ contentStat.countContentFileNotFound + " files not found");
sbLog.append("\n" + contentStat.countContentFileNotFound
+ " files not found");
logger.trace(getLogPrefix(companyName, userName)
+ contentStat.countContentDossierNotFound
+ " contents' dossiers not found");
sbLog.append("\n" + contentStat.countContentDossierNotFound
+ " contents' dossiers not found");
logger.trace(getLogPrefix(companyName, userName)
+ contentStat.countContentError + " contents not added (error)");
sbLog.append("\n" + contentStat.countContentError
+ " contents not added (error)");
logger.trace(getLogPrefix(companyName, userName)
+ contentStat.countPathCreation + " empty path");
sbLog.append("\n" + contentStat.countPathCreation + " empty path");
return contentStat;
}
private class ImportContentStat {
int countContent = 0;
int countContentAdded = 0;
int countContentDuplicate = 0;
int countContentError = 0;
int countContentFileNotFound = 0;
int countContentDossierNotFound = 0;
int countPathCreation = 0;
@Override
public String toString() {
return "\"ImportContentStat\":{\"countContent\":\"" + countContent
+ "\",\"countContentAdded\":\"" + countContentAdded
+ "\",\"countContentDuplicate\":\"" + countContentDuplicate
+ "\",\"countContentError\":\"" + countContentError
+ "\",\"countContentFileNotFound\":\""
+ countContentFileNotFound
+ "\",\"countContentDossierNotFound\":\""
+ countContentDossierNotFound
+ "\",\"countPathCreation\":\"" + countPathCreation + "\"}";
}
}
private void addKoyaPermissionCollaborator(Company c, Dossier d,
List<String> usersMail,
final KoyaPermissionCollaborator permissionCollaborator,
boolean newDossier, final StringBuffer sbLog) {
if (!newDossier) {
// Removing not responsible anymore
List<User> currentUsers = spaceAclService.listMembership(d,
permissionCollaborator);
for (User u : currentUsers) {
if (!usersMail.contains(u.getEmail())) {
spaceAclService.removeKoyaAuthority(d,
permissionCollaborator, u);
}
}
}
for (String userMail : usersMail) {
User u = null;
try {
u = userService.getUserByEmail(userMail);
} catch (KoyaServiceException kse) {
// silently catch exception
}
if (u != null) {
try {
spaceAclService.collaboratorShare(d, u,
permissionCollaborator);
logger.trace(getLogPrefix(c.getName(), null) + "Adding "
+ userMail + " as " + permissionCollaborator);
sbLog.append("\nAdding " + userMail + " as "
+ permissionCollaborator);
} catch (KoyaServiceException ex) {
logger.error(
getLogPrefix(c.getName(), null) + "Error adding "
+ userMail + " AS "
+ permissionCollaborator + " to dossier "
+ d.getTitle(), ex);
sbLog.append("\nError adding " + userMail + " AS "
+ permissionCollaborator + " to dossier "
+ d.getTitle());
}
}
}
}
@Override
protected void addParameterDefinitions(List<ParameterDefinition> paramList) {
}
/**
* Recursively delete a dir of files and directories
*
* @param dir
* directory to delete
*/
private void deleteDir(File dir) {
if (dir == null) {
return;
}
File elenco = new File(dir.getPath());
// listFiles can return null if the path is invalid i.e. already
// been deleted,
// therefore check for null before using in loop
File[] files = elenco.listFiles();
if (files != null) {
for (File file : files) {
if (file.isFile()) {
file.delete();
} else {
deleteDir(file);
}
}
}
// delete provided directory
dir.delete();
}
private String getLogPrefix(String companyName, String username) {
return "[" + username + "]"
+ ((companyName != null) ? "[" + companyName + "]" : "");
}
}