/* This file is part of Cyclos (www.cyclos.org). A project of the Social Trade Organisation (www.socialtrade.org). Cyclos is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Cyclos 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 General Public License for more details. You should have received a copy of the GNU General Public License along with Cyclos; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package nl.strohalm.cyclos.services.customization; import java.io.InputStream; import java.sql.Blob; import java.util.Calendar; import java.util.Collection; import java.util.List; import nl.strohalm.cyclos.access.AdminMemberPermission; import nl.strohalm.cyclos.access.BrokerPermission; import nl.strohalm.cyclos.dao.customizations.BinaryFileDAO; import nl.strohalm.cyclos.dao.customizations.DocumentDAO; import nl.strohalm.cyclos.dao.customizations.DocumentPageDAO; import nl.strohalm.cyclos.entities.Relationship; import nl.strohalm.cyclos.entities.customization.binaryfiles.BinaryFile; import nl.strohalm.cyclos.entities.customization.documents.Document; import nl.strohalm.cyclos.entities.customization.documents.DocumentPage; import nl.strohalm.cyclos.entities.customization.documents.DocumentQuery; import nl.strohalm.cyclos.entities.customization.documents.DynamicDocument; import nl.strohalm.cyclos.entities.customization.documents.MemberDocument; import nl.strohalm.cyclos.entities.customization.documents.StaticDocument; import nl.strohalm.cyclos.entities.groups.AdminGroup; import nl.strohalm.cyclos.entities.groups.BrokerGroup; import nl.strohalm.cyclos.entities.groups.SystemGroup; import nl.strohalm.cyclos.services.groups.GroupServiceLocal; import nl.strohalm.cyclos.utils.access.LoggedUser; import nl.strohalm.cyclos.utils.validation.PropertyValidation; import nl.strohalm.cyclos.utils.validation.RequiredError; import nl.strohalm.cyclos.utils.validation.ValidationError; import nl.strohalm.cyclos.utils.validation.Validator; /** * Implementation for document service * @author luis * @author Jefferson Magno */ public class DocumentServiceImpl implements DocumentServiceLocal { /** * If we are inserting a new static document, the binary file is required * @author Jefferson Magno */ public class BinaryFileValidation implements PropertyValidation { private static final long serialVersionUID = 7546191238179831809L; @Override public ValidationError validate(final Object object, final Object name, final Object value) { final StaticDocument document = (StaticDocument) object; if (document.isTransient() && document.getBinaryFile() == null) { return new RequiredError(); } return null; } } private BinaryFileDAO binaryFileDao; private DocumentDAO documentDao; private DocumentPageDAO documentPageDao; private GroupServiceLocal groupService; @Override public Document load(final Long id, final Relationship... fetch) { return documentDao.load(id, fetch); } @Override public int remove(final Long... ids) { return documentDao.delete(ids); } @Override public DynamicDocument saveDynamic(DynamicDocument document) { validate(document, false); // Store the pages final DocumentPage formPage = document.getFormPage(); final DocumentPage documentPage = document.getDocumentPage(); final boolean isInsert = document.isTransient(); if (isInsert) { // Save the document without pages document.setFormPage(null); document.setDocumentPage(null); AdminGroup group = (AdminGroup) groupService.load(LoggedUser.group().getId(), SystemGroup.Relationships.DOCUMENTS); document.addGroup(group); document = documentDao.insert(document); // Add the document to the group group.getDocuments().add(document); // Ensure the group have the adminMemberDocuments.details permission if (!group.getPermissions().contains(AdminMemberPermission.DOCUMENTS_DETAILS)) { group.getPermissions().add(AdminMemberPermission.DOCUMENTS_DETAILS); } // Update the group group = groupService.update(group, false); } else { // Update collections of groups and broker groups final Document loadedDocument = documentDao.load(document.getId(), Document.Relationships.GROUPS, Document.Relationships.BROKER_GROUPS); final Collection<SystemGroup> loadedGroups = loadedDocument.getGroups(); final Collection<BrokerGroup> loadedBrokerGroups = loadedDocument.getBrokerGroups(); document.setGroups(loadedGroups); document.setBrokerGroups(loadedBrokerGroups); // Update document document = documentDao.update(document); } // Save the pages if (formPage != null) { formPage.setDocument(document); formPage.setName("Form page of " + document.getName()); document.setFormPage(save(formPage)); } documentPage.setDocument(document); documentPage.setName("Document page of " + document.getName()); document.setDocumentPage(save(documentPage)); // Update the document with the pages if (isInsert) { document = documentDao.update(document); } return document; } @Override public StaticDocument saveStatic(final StaticDocument document, final InputStream stream, final int size, final String fileName, final String contentType) { return doSaveStatic(document, stream, size, fileName, contentType); } @Override public List<Document> search(final DocumentQuery documentQuery) { return documentDao.search(documentQuery); } public void setBinaryFileDao(final BinaryFileDAO binaryFileDao) { this.binaryFileDao = binaryFileDao; } public void setDocumentDao(final DocumentDAO documentDao) { this.documentDao = documentDao; } public void setDocumentPageDao(final DocumentPageDAO documentPageDao) { this.documentPageDao = documentPageDao; } public void setGroupServiceLocal(final GroupServiceLocal groupService) { this.groupService = groupService; } @Override public void validate(final Document document, final boolean validateBinaryFile) { if (document instanceof DynamicDocument) { getDynamicValidator().validate(document); } else if (document instanceof MemberDocument) { getMemberValidator(validateBinaryFile).validate(document); } else { // StaticDocument getStaticValidator(validateBinaryFile).validate(document); } } private StaticDocument doSaveStatic(StaticDocument document, final InputStream stream, final int size, final String fileName, final String contentType) { BinaryFile binaryFile = retrieveBinaryFile(stream, size, fileName, contentType); document.setBinaryFile(binaryFile); validate(document, true); if (document.isTransient()) { binaryFile = binaryFileDao.insert(binaryFile); document.setBinaryFile(binaryFile); final SystemGroup group = groupService.load(LoggedUser.group().getId(), SystemGroup.Relationships.DOCUMENTS); group.addDocument(document); document.addGroup(group); document = documentDao.insert(document); if (LoggedUser.isAdministrator()) { group.getPermissions().add(AdminMemberPermission.DOCUMENTS_DETAILS); } else if (LoggedUser.isBroker()) { group.getPermissions().add(BrokerPermission.DOCUMENTS_VIEW); } groupService.update(group, false); } else { // Update the binary file final StaticDocument loadedDocument = (StaticDocument) load(document.getId(), Document.Relationships.GROUPS, Document.Relationships.BROKER_GROUPS, StaticDocument.Relationships.BINARY_FILE); BinaryFile loadedBinaryFile = loadedDocument.getBinaryFile(); if (binaryFile != null) { loadedBinaryFile.setContentType(binaryFile.getContentType()); loadedBinaryFile.setName(binaryFile.getName()); loadedBinaryFile.setSize(binaryFile.getSize()); loadedBinaryFile.setLastModified(binaryFile.getLastModified()); loadedBinaryFile.setContents(binaryFile.getContents()); loadedBinaryFile = binaryFileDao.update(loadedBinaryFile); } document.setBinaryFile(loadedBinaryFile); // Update collections of groups and broker groups (if not a member document) if (!(loadedDocument instanceof MemberDocument)) { final Collection<SystemGroup> loadedGroups = loadedDocument.getGroups(); final Collection<BrokerGroup> loadedBrokerGroups = loadedDocument.getBrokerGroups(); document.setGroups(loadedGroups); document.setBrokerGroups(loadedBrokerGroups); } // Update document documentDao.update(document); } return document; } private Validator getBasicValidator() { final Validator validator = new Validator("document"); validator.property("name").required().maxLength(100); validator.property("description").maxLength(1000); return validator; } private Validator getDynamicValidator() { final Validator dynamicValidator = getBasicValidator(); dynamicValidator.property("documentPage.contents").key("document.documentPage").required(); return dynamicValidator; } private Validator getMemberValidator(final boolean validateBinaryFile) { final Validator memberValidator = getBasicValidator(); if (validateBinaryFile) { memberValidator.property("binaryFile").add(new BinaryFileValidation()); } memberValidator.property("member").required(); memberValidator.property("visibility").required(); return memberValidator; } private Validator getStaticValidator(final boolean validateBinaryFile) { final Validator staticValidator = getBasicValidator(); if (validateBinaryFile) { staticValidator.property("binaryFile").add(new BinaryFileValidation()); } return staticValidator; } private BinaryFile retrieveBinaryFile(final InputStream stream, final int size, final String fileName, final String contentType) { if (stream != null && size > 0) { // Generate blob contents for the binary file final Blob contents = documentDao.createBlob(stream, size); // Create binary file and set in the static document final BinaryFile binaryFile = new BinaryFile(); binaryFile.setContentType(contentType); binaryFile.setName(fileName); binaryFile.setSize(size); binaryFile.setLastModified(Calendar.getInstance()); binaryFile.setContents(contents); return binaryFile; } else { return null; } } private DocumentPage save(final DocumentPage page) { page.setLastModified(Calendar.getInstance()); if (page.isTransient()) { return documentPageDao.insert(page); } else { return documentPageDao.update(page); } } }