Java tutorial
/** * OpenKM, Open Document Management System (http://www.openkm.com) * Copyright (c) 2006-2015 Paco Avila & Josep Llort * * No bytes were intentionally harmed during the development of this application. * * This program 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. * * This program 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package com.openkm.module.db.base; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.openkm.automation.AutomationException; import com.openkm.automation.AutomationManager; import com.openkm.automation.AutomationUtils; import com.openkm.bean.Document; import com.openkm.bean.ExtendedAttributes; import com.openkm.bean.FileUploadResponse; import com.openkm.bean.Folder; import com.openkm.bean.LockInfo; import com.openkm.bean.Note; import com.openkm.bean.Permission; import com.openkm.bean.workflow.ProcessDefinition; import com.openkm.bean.workflow.ProcessInstance; import com.openkm.core.AccessDeniedException; import com.openkm.core.Config; import com.openkm.core.DatabaseException; import com.openkm.core.ItemExistsException; import com.openkm.core.PathNotFoundException; import com.openkm.core.Ref; import com.openkm.core.UserQuotaExceededException; import com.openkm.core.WorkflowException; import com.openkm.dao.NodeBaseDAO; import com.openkm.dao.NodeDocumentDAO; import com.openkm.dao.NodeDocumentVersionDAO; import com.openkm.dao.NodeFolderDAO; import com.openkm.dao.NodeNoteDAO; import com.openkm.dao.UserConfigDAO; import com.openkm.dao.bean.AutomationRule; import com.openkm.dao.bean.NodeBase; import com.openkm.dao.bean.NodeDocument; import com.openkm.dao.bean.NodeDocumentVersion; import com.openkm.dao.bean.NodeFolder; import com.openkm.dao.bean.NodeLock; import com.openkm.dao.bean.NodeNote; import com.openkm.dao.bean.NodeProperty; import com.openkm.dao.bean.ProfileMisc; import com.openkm.dao.bean.UserConfig; import com.openkm.module.common.CommonWorkflowModule; import com.openkm.module.db.stuff.DbUtils; import com.openkm.util.CloneUtils; import com.openkm.util.DocConverter; import com.openkm.util.UserActivity; public class BaseDocumentModule { private static Logger log = LoggerFactory.getLogger(BaseDocumentModule.class); /** * Create a new document */ @SuppressWarnings("unchecked") public static NodeDocument create(String user, String parentPath, NodeBase parentNode, String name, String title, Calendar created, String mimeType, InputStream is, long size, Set<String> keywords, Set<String> categories, Set<NodeProperty> propertyGroups, List<NodeNote> notes, Ref<FileUploadResponse> fuResponse) throws PathNotFoundException, AccessDeniedException, ItemExistsException, UserQuotaExceededException, AutomationException, DatabaseException, IOException { // Check user quota UserConfig uc = UserConfigDAO.findByPk(user); ProfileMisc pm = uc.getProfile().getPrfMisc(); // System user don't care quotas if (!Config.SYSTEM_USER.equals(user) && pm.getUserQuota() > 0) { long currentQuota = currentQuota = DbUtils.calculateQuota(user); if (currentQuota + size > pm.getUserQuota() * 1024 * 1024) { throw new UserQuotaExceededException(Long.toString(currentQuota + size)); } } // AUTOMATION - PRE Map<String, Object> env = new HashMap<String, Object>(); env.put(AutomationUtils.PARENT_UUID, parentNode.getUuid()); env.put(AutomationUtils.PARENT_PATH, parentPath); env.put(AutomationUtils.PARENT_NODE, parentNode); env.put(AutomationUtils.DOCUMENT_NAME, name); env.put(AutomationUtils.DOCUMENT_MIME_TYPE, mimeType); env.put(AutomationUtils.DOCUMENT_KEYWORDS, keywords); AutomationManager.getInstance().fireEvent(AutomationRule.EVENT_DOCUMENT_CREATE, AutomationRule.AT_PRE, env); parentNode = (NodeBase) env.get(AutomationUtils.PARENT_NODE); name = (String) env.get(AutomationUtils.DOCUMENT_NAME); mimeType = (String) env.get(AutomationUtils.DOCUMENT_MIME_TYPE); keywords = (Set<String>) env.get(AutomationUtils.DOCUMENT_KEYWORDS); // Create and add a new document node NodeDocument documentNode = new NodeDocument(); documentNode.setUuid(UUID.randomUUID().toString()); documentNode.setContext(parentNode.getContext()); documentNode.setParent(parentNode.getUuid()); documentNode.setAuthor(user); documentNode.setName(name); documentNode.setTitle(title); documentNode.setMimeType(mimeType); documentNode.setCreated(created != null ? created : Calendar.getInstance()); documentNode.setLastModified(documentNode.getCreated()); if (Config.STORE_NODE_PATH) { documentNode.setPath(parentNode.getPath() + "/" + name); } // Extended Copy Attributes documentNode.setKeywords(CloneUtils.clone(keywords)); documentNode.setCategories(CloneUtils.clone(categories)); for (NodeProperty nProp : CloneUtils.clone(propertyGroups)) { nProp.setNode(documentNode); documentNode.getProperties().add(nProp); } // Get parent node auth info Map<String, Integer> userPerms = parentNode.getUserPermissions(); Map<String, Integer> rolePerms = parentNode.getRolePermissions(); // Always assign all grants to creator if (Config.USER_ASSIGN_DOCUMENT_CREATION) { int allGrants = Permission.ALL_GRANTS; userPerms.put(user, allGrants); } // Set auth info // NOTICE: Pay attention to the need of cloning documentNode.setUserPermissions(CloneUtils.clone(userPerms)); documentNode.setRolePermissions(CloneUtils.clone(rolePerms)); NodeDocumentDAO.getInstance().create(documentNode, is, size); // Extended Copy Attributes for (NodeNote nNote : CloneUtils.clone(notes)) { BaseNoteModule.create(documentNode.getUuid(), nNote.getAuthor(), nNote.getText()); } // AUTOMATION - POST env.put(AutomationUtils.DOCUMENT_NODE, documentNode); AutomationManager.getInstance().fireEvent(AutomationRule.EVENT_DOCUMENT_CREATE, AutomationRule.AT_POST, env); // Setting wizard properties fuResponse.set((FileUploadResponse) env.get(AutomationUtils.UPLOAD_RESPONSE)); return documentNode; } /** * Add this 20/02/2017 * By AHOUANTCHEDE Herve */ @SuppressWarnings("unchecked") public static NodeDocument createByMigration(String user, String parentPath, NodeBase parentNode, String name, String title, Calendar created, String mimeType, InputStream is, long size, Set<String> keywords, Set<String> categories, Set<NodeProperty> propertyGroups, List<NodeNote> notes) throws PathNotFoundException, AccessDeniedException, ItemExistsException, UserQuotaExceededException, AutomationException, DatabaseException, IOException { // Check user quota UserConfig uc = UserConfigDAO.findByPk(user); ProfileMisc pm = uc.getProfile().getPrfMisc(); // System user don't care quotas if (!Config.SYSTEM_USER.equals(user) && pm.getUserQuota() > 0) { long currentQuota = currentQuota = DbUtils.calculateQuota(user); if (currentQuota + size > pm.getUserQuota() * 1024 * 1024) { throw new UserQuotaExceededException(Long.toString(currentQuota + size)); } } // AUTOMATION - PRE Map<String, Object> env = new HashMap<String, Object>(); env.put(AutomationUtils.PARENT_UUID, parentNode.getUuid()); env.put(AutomationUtils.PARENT_PATH, parentPath); env.put(AutomationUtils.PARENT_NODE, parentNode); env.put(AutomationUtils.DOCUMENT_NAME, name); env.put(AutomationUtils.DOCUMENT_MIME_TYPE, mimeType); env.put(AutomationUtils.DOCUMENT_KEYWORDS, keywords); AutomationManager.getInstance().fireEvent(AutomationRule.EVENT_DOCUMENT_CREATE, AutomationRule.AT_PRE, env); parentNode = (NodeBase) env.get(AutomationUtils.PARENT_NODE); name = (String) env.get(AutomationUtils.DOCUMENT_NAME); mimeType = (String) env.get(AutomationUtils.DOCUMENT_MIME_TYPE); keywords = (Set<String>) env.get(AutomationUtils.DOCUMENT_KEYWORDS); // Create and add a new document node NodeDocument documentNode = new NodeDocument(); documentNode.setUuid(UUID.randomUUID().toString()); documentNode.setContext(parentNode.getContext()); documentNode.setParent(parentNode.getUuid()); documentNode.setAuthor(user); documentNode.setName(name); documentNode.setTitle(title); documentNode.setMimeType(mimeType); documentNode.setCreated(created != null ? created : Calendar.getInstance()); documentNode.setLastModified(documentNode.getCreated()); if (Config.STORE_NODE_PATH) { documentNode.setPath(parentNode.getPath() + "/" + name); } // Extended Copy Attributes documentNode.setKeywords(CloneUtils.clone(keywords)); documentNode.setCategories(CloneUtils.clone(categories)); for (NodeProperty nProp : CloneUtils.clone(propertyGroups)) { nProp.setNode(documentNode); documentNode.getProperties().add(nProp); } // Get parent node auth info Map<String, Integer> userPerms = parentNode.getUserPermissions(); Map<String, Integer> rolePerms = parentNode.getRolePermissions(); // Always assign all grants to creator if (Config.USER_ASSIGN_DOCUMENT_CREATION) { int allGrants = Permission.ALL_GRANTS; userPerms.put(user, allGrants); } // Set auth info // NOTICE: Pay attention to the need of cloning documentNode.setUserPermissions(CloneUtils.clone(userPerms)); documentNode.setRolePermissions(CloneUtils.clone(rolePerms)); NodeDocumentDAO.getInstance().create(documentNode, is, size); // Extended Copy Attributes for (NodeNote nNote : CloneUtils.clone(notes)) { BaseNoteModule.create(documentNode.getUuid(), nNote.getAuthor(), nNote.getText()); } // AUTOMATION - POST env.put(AutomationUtils.DOCUMENT_NODE, documentNode); AutomationManager.getInstance().fireEvent(AutomationRule.EVENT_DOCUMENT_CREATE, AutomationRule.AT_POST, env); return documentNode; } /** * Get folder properties */ public static Document getProperties(String user, NodeDocument nDocument) throws PathNotFoundException, DatabaseException { log.debug("getProperties({}, {})", user, nDocument); long begin = System.currentTimeMillis(); Document doc = new Document(); // Properties String docPath = NodeBaseDAO.getInstance().getPathFromUuid(nDocument.getUuid()); doc.setPath(docPath); doc.setCreated(nDocument.getCreated()); doc.setLastModified(nDocument.getLastModified()); doc.setAuthor(nDocument.getAuthor()); doc.setUuid(nDocument.getUuid()); doc.setMimeType(nDocument.getMimeType()); doc.setCheckedOut(nDocument.isCheckedOut()); doc.setLocked(nDocument.isLocked()); if (doc.isLocked()) { NodeLock nLock = nDocument.getLock(); LockInfo lock = BaseModule.getProperties(nLock, docPath); doc.setLockInfo(lock); } else { doc.setLockInfo(null); } // Get current version NodeDocumentVersionDAO nodeDocVerDao = NodeDocumentVersionDAO.getInstance(); NodeDocumentVersion currentVersion = nodeDocVerDao.findCurrentVersion(doc.getUuid()); doc.setActualVersion(BaseModule.getProperties(currentVersion)); // Get permissions BaseModule.setPermissions(nDocument, doc); // Document conversion capabilities DocConverter convert = DocConverter.getInstance(); doc.setConvertibleToPdf(convert.convertibleToPdf(doc.getMimeType())); doc.setConvertibleToSwf(convert.convertibleToSwf(doc.getMimeType())); // Get user subscription & keywords doc.setSubscriptors(nDocument.getSubscriptors()); doc.setSubscribed(nDocument.getSubscriptors().contains(user)); doc.setKeywords(nDocument.getKeywords()); // Get categories Set<Folder> categories = new HashSet<Folder>(); NodeFolderDAO nFldDao = NodeFolderDAO.getInstance(); Set<NodeFolder> resolvedCategories = nFldDao.resolveCategories(nDocument.getCategories()); for (NodeFolder nfldCat : resolvedCategories) { categories.add(BaseFolderModule.getProperties(user, nfldCat)); } doc.setCategories(categories); // Get notes List<Note> notes = new ArrayList<Note>(); List<NodeNote> nNoteList = NodeNoteDAO.getInstance().findByParent(nDocument.getUuid()); for (NodeNote nNote : nNoteList) { notes.add(BaseNoteModule.getProperties(nNote, nNote.getUuid())); } doc.setNotes(notes); log.trace("getProperties.Time: {}", System.currentTimeMillis() - begin); log.debug("getProperties: {}", doc); return doc; } /** * Retrieve the content input stream from a document * * @param user The user who make the content petition. * @param docUuid UUID of the document to get the content. * @param docPath Path of the document to get the content. * @param checkout If the content is retrieved due to a checkout or not. * @param extendedSecurity If the extended security DOWNLOAD permission should be evaluated. * This is used to enable the document preview. */ public static InputStream getContent(String user, String docUuid, String docPath, boolean checkout, boolean extendedSecurity) throws IOException, PathNotFoundException, AccessDeniedException, DatabaseException { InputStream is = NodeDocumentVersionDAO.getInstance().getCurrentContentByParent(docUuid, extendedSecurity); // Activity log UserActivity.log(user, (checkout ? "GET_DOCUMENT_CONTENT_CHECKOUT" : "GET_DOCUMENT_CONTENT"), docUuid, docPath, Integer.toString(is.available())); return is; } /** * Check if a node is being used in a running workflow */ public static boolean hasWorkflowNodes(String docUuid) throws WorkflowException, PathNotFoundException, DatabaseException { Set<String> workflowNodes = new HashSet<String>(); for (ProcessDefinition procDef : CommonWorkflowModule.findAllProcessDefinitions()) { for (ProcessInstance procIns : CommonWorkflowModule.findProcessInstances(procDef.getId())) { if (procIns.getEnd() == null) { String uuid = (String) procIns.getVariables() .get(Config.WORKFLOW_PROCESS_INSTANCE_VARIABLE_UUID); workflowNodes.add(uuid); } } } if (workflowNodes.contains(docUuid)) { return true; } else { return false; } } /** * Is invoked from DbDocumentNode and DbFolderNode. */ public static NodeDocument copy(String user, NodeDocument srcDocNode, String dstPath, NodeBase dstNode, String docName, ExtendedAttributes extAttr) throws PathNotFoundException, AccessDeniedException, ItemExistsException, UserQuotaExceededException, AutomationException, DatabaseException, IOException { log.debug("copy({}, {}, {}, {}, {})", new Object[] { user, srcDocNode, dstNode, docName, extAttr }); InputStream is = null; NodeDocument newDocument = null; try { Set<String> keywords = new HashSet<String>(); Set<String> categories = new HashSet<String>(); Set<NodeProperty> propertyGroups = new HashSet<NodeProperty>(); List<NodeNote> notes = new ArrayList<NodeNote>(); if (extAttr != null) { if (extAttr.isKeywords()) { keywords = srcDocNode.getKeywords(); } if (extAttr.isCategories()) { categories = srcDocNode.getCategories(); } if (extAttr.isPropertyGroups()) { propertyGroups = srcDocNode.getProperties(); } if (extAttr.isNotes()) { notes = NodeNoteDAO.getInstance().findByParent(srcDocNode.getUuid()); } } Ref<FileUploadResponse> fuResponse = new Ref<FileUploadResponse>(new FileUploadResponse()); is = NodeDocumentVersionDAO.getInstance().getCurrentContentByParent(srcDocNode.getUuid(), true); NodeDocumentVersion nDocVer = NodeDocumentVersionDAO.getInstance() .findCurrentVersion(srcDocNode.getUuid()); newDocument = create(user, dstPath, dstNode, docName, srcDocNode.getTitle(), Calendar.getInstance(), srcDocNode.getMimeType(), is, nDocVer.getSize(), keywords, categories, propertyGroups, notes, fuResponse); } finally { IOUtils.closeQuietly(is); } log.debug("copy: {}", newDocument); return newDocument; } }