DocumentManager.java
/*
* The coLAB project
* Copyright (C) 2021-2023 AlbaSim, MEI, HEIG-VD, HES-SO
*
* Licensed under the MIT License
*/
package ch.colabproject.colab.api.controller.document;
import ch.colabproject.colab.api.model.document.Document;
import ch.colabproject.colab.api.model.document.DocumentFile;
import ch.colabproject.colab.api.model.document.TextDataBlock;
import ch.colabproject.colab.api.model.link.StickyNoteLink;
import ch.colabproject.colab.api.persistence.jpa.document.DocumentDao;
import ch.colabproject.colab.generator.model.exceptions.HttpErrorMessage;
import ch.colabproject.colab.generator.model.exceptions.MessageI18nKey;
import java.util.List;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Document specific logic
*
* @author sandra
*/
@Stateless
@LocalBean
public class DocumentManager {
/** logger */
private static final Logger logger = LoggerFactory.getLogger(DocumentManager.class);
// *********************************************************************************************
// injections
// *********************************************************************************************
/**
* Document persistence handler
*/
@Inject
private DocumentDao documentDao;
/**
* Index generation specific logic management
*/
@Inject
private IndexGeneratorHelper<Document> indexGenerator;
// *********************************************************************************************
// find document
// *********************************************************************************************
/**
* Retrieve the document. If not found, throw a {@link HttpErrorMessage}.
*
* @param documentId the id of the document
*
* @return the document if found
*
* @throws HttpErrorMessage if the document was not found
*/
public Document assertAndGetDocument(Long documentId) {
Document document = documentDao.findDocument(documentId);
if (document == null) {
logger.error("document #{} not found", documentId);
throw HttpErrorMessage.dataError(MessageI18nKey.DATA_NOT_FOUND);
}
return document;
}
/**
* Retrieve the text data block. If not found, throw a {@link HttpErrorMessage}.
*
* @param textDataBlockId the id of the text data block
*
* @return the text data block if found
*
* @throws HttpErrorMessage if the text data block was not found
*/
public TextDataBlock assertAndGetTextDataBlock(Long textDataBlockId) {
Document document = assertAndGetDocument(textDataBlockId);
if (!(document instanceof TextDataBlock)) {
logger.error("#{} is not a text data block", document);
throw HttpErrorMessage.dataError(MessageI18nKey.DATA_NOT_FOUND);
}
return (TextDataBlock) document;
}
/**
* Retrieve the document file. If not found, throw a {@link HttpErrorMessage}.
*
* @param documentFileId the id of the document file
*
* @return the document file if found
*
* @throws HttpErrorMessage if the document file was not found
*/
public DocumentFile assertAndGetDocumentFile(Long documentFileId) {
Document document = assertAndGetDocument(documentFileId);
if (!(document instanceof DocumentFile)) {
logger.error("#{} is not a document file", document);
throw HttpErrorMessage.dataError(MessageI18nKey.DATA_NOT_FOUND);
}
return (DocumentFile) document;
}
/**
* Retrieve the list of documents the given document is part of
*
* @param document the document
*
* @return the list of documents the given document is part of
*
* @throws HttpErrorMessage If no collection could be found
*/
public List<Document> getDocumentList(Document document) {
if (document.hasOwningCardContent()) {
return document.getOwningCardContent().getDeliverables();
} else if (document.hasOwningResource()) {
return document.getOwningResource().getDocuments();
}
throw HttpErrorMessage.dataError(MessageI18nKey.DATA_INTEGRITY_FAILURE);
}
// *********************************************************************************************
// move document
// *********************************************************************************************
/**
* Move the document to the top
*
* @param documentId the id of the document to move
*/
public void moveDocumentToTop(Long documentId) {
logger.debug("move document #{} at top", documentId);
Document document = assertAndGetDocument(documentId);
List<Document> docList = getDocumentList(document);
indexGenerator.moveItemToBeginning(document, docList);
}
/**
* Move the given document one floor up
*
* @param documentId the id of the document to move
*/
public void moveDocumentUp(Long documentId) {
logger.debug("move document #{} up", documentId);
Document document = assertAndGetDocument(documentId);
List<Document> docList = getDocumentList(document);
indexGenerator.moveOneStepAhead(document, docList);
}
/**
* Move the given document above the given reference item
*
* @param documentId the id of the document to move
* @param baseDocId the id of the reference document
*/
public void moveDocumentAbove(Long documentId, Long baseDocId) {
logger.debug("move document #{} above #{}", documentId, baseDocId);
Document document = assertAndGetDocument(documentId);
Document baseDocument = assertAndGetDocument(baseDocId);
List<Document> docList = getDocumentList(baseDocument);
indexGenerator.moveItemBefore(document, baseDocument, docList);
}
/**
* Move the given document one floor down
*
* @param documentId the id of the document to move
*/
public void moveDocumentDown(Long documentId) {
logger.debug("move document #{} down", documentId);
Document document = assertAndGetDocument(documentId);
List<Document> docList = getDocumentList(document);
indexGenerator.moveOneStepBehind(document, docList);
}
/**
* Move the given document below the given reference item.
*
* @param documentId the id of the document to move
* @param baseDocId the id of the reference document
*/
public void moveDocumentBelow(Long documentId, Long baseDocId) {
logger.debug("move document #{} below #{}", documentId, baseDocId);
Document document = assertAndGetDocument(documentId);
Document baseDocument = assertAndGetDocument(baseDocId);
List<Document> docList = getDocumentList(baseDocument);
indexGenerator.moveItemAfter(document, baseDocument, docList);
}
/**
* Move the document to the bottom
*
* @param documentId the id of the document to move
*/
public void moveDocumentToBottom(Long documentId) {
logger.debug("move document #{} at bottom", documentId);
Document document = assertAndGetDocument(documentId);
List<Document> docList = getDocumentList(document);
indexGenerator.moveItemToEnd(document, docList);
}
// *********************************************************************************************
// integrity check
// *********************************************************************************************
/**
* Check the integrity of the document
*
* @param document the document to check
*
* @return true iff the document is complete and safe
*/
public boolean checkIntegrity(Document document) {
if (document == null) {
return false;
}
if (countOwners(document) != 1) {
return false;
}
return true;
}
/**
* Count the number of entities owning the document. It should be only one.
*
* @param document the document to check
*
* @return the number of owning entities
*/
protected int countOwners(Document document) {
int result = 0;
if (document.hasOwningCardContent()) {
result++;
}
if (document.hasOwningResource()) {
result++;
}
if (document instanceof TextDataBlock) {
TextDataBlock block = (TextDataBlock) document;
if (block.getPurposingCardType() != null) {
result++;
}
if (block.getTeasingResource() != null) {
result++;
}
if (block.getExplainingStickyNoteLink() != null) {
result++;
}
}
return result;
}
// *********************************************************************************************
// retrieve the elements linked to documents
// *********************************************************************************************
/**
* Get all sticky note links of which the given document is the source
*
* @param docId the id of the document
*
* @return all sticky note links which has the given document as source
*/
public List<StickyNoteLink> getStickyNoteLinkAsSrc(Long docId) {
logger.debug("get sticky note links where the document #{} is the source", docId);
Document document = assertAndGetDocument(docId);
return document.getStickyNoteLinksAsSrc();
}
// *********************************************************************************************
//
// *********************************************************************************************
// As a document is either linked to a resource or to a card content, most of
// the operations are
// made from there
// *********************************************************************************************
//
// *********************************************************************************************
}