/**
* OpenKM, Open Document Management System (http://www.openkm.com)
* Copyright (c) 2006-2011 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.direct;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Session;
import org.apache.jackrabbit.api.XASession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.openkm.bean.Mail;
import com.openkm.bean.Repository;
import com.openkm.core.AccessDeniedException;
import com.openkm.core.Config;
import com.openkm.core.DatabaseException;
import com.openkm.core.ItemExistsException;
import com.openkm.core.JcrSessionManager;
import com.openkm.core.LockException;
import com.openkm.core.PathNotFoundException;
import com.openkm.core.RepositoryException;
import com.openkm.core.UserQuotaExceededException;
import com.openkm.core.VirusDetectedException;
import com.openkm.jcr.JCRUtils;
import com.openkm.module.MailModule;
import com.openkm.module.base.BaseMailModule;
import com.openkm.module.base.BaseNotificationModule;
import com.openkm.module.base.BaseScriptingModule;
import com.openkm.util.Transaction;
import com.openkm.util.UserActivity;
public class DirectMailModule implements MailModule {
private static Logger log = LoggerFactory.getLogger(DirectMailModule.class);
@Override
public Mail create(String token, Mail mail) throws AccessDeniedException, RepositoryException,
PathNotFoundException, ItemExistsException, VirusDetectedException, DatabaseException,
UserQuotaExceededException {
log.debug("create({}, {})", token, mail);
return create(token, mail, null);
}
/**
* Used when importing mail from scheduler
*/
public Mail create(String token, Mail mail, String userId) throws AccessDeniedException, RepositoryException,
PathNotFoundException, ItemExistsException, VirusDetectedException, DatabaseException,
UserQuotaExceededException {
log.debug("create({}, {}, {})", new Object[] { token, mail, userId });
Mail newMail = null;
Transaction t = null;
XASession session = null;
if (Config.SYSTEM_READONLY) {
throw new AccessDeniedException("System is in read-only mode");
}
try {
if (token == null) {
session = (XASession) JCRUtils.getSession();
} else {
session = (XASession) JcrSessionManager.getInstance().get(token);
}
String parent = JCRUtils.getParent(mail.getPath());
String name = JCRUtils.getName(mail.getPath());
Node parentNode = session.getRootNode().getNode(parent.substring(1));
// Escape dangerous chars in name
name = JCRUtils.escape(name);
mail.setPath(parent + "/" + name);
t = new Transaction(session);
t.start();
// Create node
Node mailNode = BaseMailModule.create(session, parentNode, name, mail.getSize(),
mail.getFrom(), mail.getReply(), mail.getTo(), mail.getCc(), mail.getBcc(),
mail.getSentDate(), mail.getReceivedDate(), mail.getSubject(), mail.getContent(),
mail.getMimeType());
// Set returned mail properties
newMail = BaseMailModule.getProperties(session, mailNode);
t.end();
t.commit();
if (userId == null) {
userId = session.getUserID();
}
// Check subscriptions
BaseNotificationModule.checkSubscriptions(mailNode, userId, "CREATE_MAIL", null);
// Check scripting
BaseScriptingModule.checkScripts(session, parentNode, mailNode, "CREATE_MAIL");
// Activity log
UserActivity.log(userId, "CREATE_MAIL", mailNode.getUUID(), mail.getPath());
} catch (javax.jcr.PathNotFoundException e) {
log.warn(e.getMessage(), e);
throw new PathNotFoundException(e.getMessage(), e);
} catch (javax.jcr.ItemExistsException e) {
log.warn(e.getMessage(), e);
t.rollback();
throw new ItemExistsException(e.getMessage(), e);
} catch (javax.jcr.AccessDeniedException e) {
log.warn(e.getMessage(), e);
t.rollback();
throw new AccessDeniedException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
t.rollback();
throw new RepositoryException(e.getMessage(), e);
} catch (IOException e) {
log.error(e.getMessage(), e);
t.rollback();
throw new RepositoryException(e.getMessage(), e);
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("create: {}", newMail);
return newMail;
}
@Override
public Mail getProperties(String token, String mailPath) throws PathNotFoundException,
RepositoryException, DatabaseException {
log.debug("getProperties({}, {})", token, mailPath);
Mail mail = null;
Session session = null;
try {
if (token == null) {
session = JCRUtils.getSession();
} else {
session = JcrSessionManager.getInstance().get(token);
}
Node mailNode = session.getRootNode().getNode(mailPath.substring(1));
mail = BaseMailModule.getProperties(session, mailNode);
// Activity log
UserActivity.log(session.getUserID(), "GET_MAIL_PROPERTIES", mailNode.getUUID(), mailPath);
} catch (javax.jcr.PathNotFoundException e) {
log.warn(e.getMessage(), e);
throw new PathNotFoundException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
throw new RepositoryException(e.getMessage(), e);
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("get: {}", mail);
return mail;
}
@Override
public void delete(String token, String mailPath) throws AccessDeniedException, RepositoryException,
PathNotFoundException, LockException, DatabaseException {
log.debug("delete({}, {})", token, mailPath);
Session session = null;
if (Config.SYSTEM_READONLY) {
throw new AccessDeniedException("System is in read-only mode");
}
try {
if (token == null) {
session = JCRUtils.getSession();
} else {
session = JcrSessionManager.getInstance().get(token);
}
String name = JCRUtils.getName(mailPath);
Node mailNode = session.getRootNode().getNode(mailPath.substring(1));
Node parentNode = mailNode.getParent();
Node userTrash = session.getRootNode().getNode(Repository.TRASH+"/"+session.getUserID());
// Test if already exists a mail with the same name in the trash
String destPath = userTrash.getPath()+"/";
String testName = name;
for (int i=1; session.itemExists(destPath+testName); i++) {
testName = name+" ("+i+")";
}
session.move(mailNode.getPath(), destPath+testName);
session.getRootNode().save();
// Check scripting
BaseScriptingModule.checkScripts(session, parentNode, mailNode, "DELETE_MAIL");
// Activity log
UserActivity.log(session.getUserID(), "DELETE_MAIL", mailNode.getUUID(), mailPath);
} catch (javax.jcr.PathNotFoundException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new PathNotFoundException(e.getMessage(), e);
} catch (javax.jcr.AccessDeniedException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new AccessDeniedException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new RepositoryException(e.getMessage(), e);
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("delete: void");
}
@Override
public void purge(String token, String mailPath) throws AccessDeniedException, RepositoryException,
PathNotFoundException, DatabaseException {
log.debug("purge({}, {})", token, mailPath);
Node parentNode = null;
Session session = null;
if (Config.SYSTEM_READONLY) {
throw new AccessDeniedException("System is in read-only mode");
}
try {
if (token == null) {
session = JCRUtils.getSession();
} else {
session = JcrSessionManager.getInstance().get(token);
}
Node mailNode = session.getRootNode().getNode(mailPath.substring(1));
String mailUuid = mailNode.getUUID();
parentNode = mailNode.getParent();
mailNode.remove();
parentNode.save();
// Check scripting
BaseScriptingModule.checkScripts(session, parentNode, mailNode, "PURGE_MAIL");
// Activity log
UserActivity.log(session.getUserID(), "PURGE_MAIL", mailUuid, mailPath);
} catch (javax.jcr.PathNotFoundException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(parentNode);
throw new PathNotFoundException(e.getMessage(), e);
} catch (javax.jcr.AccessDeniedException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(parentNode);
throw new AccessDeniedException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
JCRUtils.discardsPendingChanges(parentNode);
throw new RepositoryException(e.getMessage(), e);
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("purge: void");
}
@Override
public Mail rename(String token, String mailPath, String newName) throws AccessDeniedException,
RepositoryException, PathNotFoundException, ItemExistsException, DatabaseException {
log.debug("rename({}, {}, {})", new Object[] { token, mailPath, newName });
Mail renamedMail = null;
Session session = null;
Node mailNode = null;
if (Config.SYSTEM_READONLY) {
throw new AccessDeniedException("System is in read-only mode");
}
try {
if (token == null) {
session = JCRUtils.getSession();
} else {
session = JcrSessionManager.getInstance().get(token);
}
String parent = JCRUtils.getParent(mailPath);
String name = JCRUtils.getName(mailPath);
// Escape dangerous chars in name
newName = JCRUtils.escape(newName);
if (newName != null && !newName.equals("") && !newName.equals(name)) {
String newPath = parent+"/"+newName;
session.move(mailPath, newPath);
// Set new name
mailNode = session.getRootNode().getNode(newPath.substring(1));
mailNode.setProperty(Mail.SUBJECT, newName);
// Publish changes
session.save();
// Set returned document properties
renamedMail = BaseMailModule.getProperties(session, mailNode);
} else {
// Don't change anything
mailNode = session.getRootNode().getNode(mailPath.substring(1));
renamedMail = BaseMailModule.getProperties(session, mailNode);
}
// Activity log
UserActivity.log(session.getUserID(), "RENAME_MAIL", mailNode.getUUID(), newName+", "+mailPath);
} catch (javax.jcr.PathNotFoundException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new PathNotFoundException(e.getMessage(), e);
} catch (javax.jcr.ItemExistsException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new ItemExistsException(e.getMessage(), e);
} catch (javax.jcr.AccessDeniedException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new AccessDeniedException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new RepositoryException(e.getMessage(), e);
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("rename: {}", renamedMail);
return renamedMail;
}
@Override
public void move(String token, String mailPath, String dstPath) throws AccessDeniedException,
RepositoryException, PathNotFoundException, ItemExistsException, DatabaseException {
log.debug("move({}, {}, {})", new Object[] { token, mailPath, dstPath });
Session session = null;
if (Config.SYSTEM_READONLY) {
throw new AccessDeniedException("System is in read-only mode");
}
try {
if (token == null) {
session = JCRUtils.getSession();
} else {
session = JcrSessionManager.getInstance().get(token);
}
//Node mailNode = session.getRootNode().getNode(mailPath.substring(1));
String name = JCRUtils.getName(mailPath);
String dstNodePath = dstPath + "/" + name;
session.move(mailPath, dstPath + "/" + name);
session.save();
Node dstMailNode = session.getRootNode().getNode(dstNodePath.substring(1));
// Check scripting
BaseScriptingModule.checkScripts(session, dstMailNode.getParent(), dstMailNode, "MOVE_MAIL");
// Activity log
UserActivity.log(session.getUserID(), "MOVE_MAIL", dstMailNode.getUUID(), dstPath+", "+mailPath);
} catch (javax.jcr.PathNotFoundException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new PathNotFoundException(e.getMessage(), e);
} catch (javax.jcr.ItemExistsException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new ItemExistsException(e.getMessage(), e);
} catch (javax.jcr.AccessDeniedException e) {
log.warn(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new AccessDeniedException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
JCRUtils.discardsPendingChanges(session);
throw new RepositoryException(e.getMessage(), e);
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("move: void");
}
@Override
public void copy(String token, String mailPath, String dstPath) throws AccessDeniedException,
RepositoryException, PathNotFoundException, ItemExistsException, IOException, DatabaseException,
UserQuotaExceededException {
log.debug("copy({}, {}, {})", new Object[] { token, mailPath, dstPath });
Transaction t = null;
XASession session = null;
if (Config.SYSTEM_READONLY) {
throw new AccessDeniedException("System is in read-only mode");
}
try {
if (token == null) {
session = (XASession) JCRUtils.getSession();
} else {
session = (XASession) JcrSessionManager.getInstance().get(token);
}
t = new Transaction(session);
t.start();
// Make some work
Node srcMailNode = session.getRootNode().getNode(mailPath.substring(1));
Node dstFolderNode = session.getRootNode().getNode(dstPath.substring(1));
BaseMailModule.copy(session, srcMailNode, dstFolderNode);
t.end();
t.commit();
// Check subscriptions
BaseNotificationModule.checkSubscriptions(dstFolderNode, session.getUserID(), "COPY", null);
// Activity log
UserActivity.log(session.getUserID(), "COPY_MAIL", srcMailNode.getUUID(), dstPath+", "+mailPath);
} catch (javax.jcr.PathNotFoundException e) {
log.warn(e.getMessage(), e);
t.rollback();
throw new PathNotFoundException(e.getMessage(), e);
} catch (javax.jcr.ItemExistsException e) {
log.warn(e.getMessage(), e);
t.rollback();
throw new ItemExistsException(e.getMessage(), e);
} catch (javax.jcr.AccessDeniedException e) {
log.warn(e.getMessage(), e);
t.rollback();
throw new AccessDeniedException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
t.rollback();
throw new RepositoryException(e.getMessage(), e);
} catch (java.io.IOException e) {
log.error(e.getMessage(), e);
t.rollback();
throw e;
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("copy: void");
}
@Override
public List<Mail> getChilds(String token, String fldPath) throws PathNotFoundException,
RepositoryException, DatabaseException {
log.debug("findChilds({}, {})", token, fldPath);
List<Mail> childs = new ArrayList<Mail>();
Session session = null;
try {
if (token == null) {
session = JCRUtils.getSession();
} else {
session = JcrSessionManager.getInstance().get(token);
}
Node folderNode = session.getRootNode().getNode(fldPath.substring(1));
for (NodeIterator ni = folderNode.getNodes(); ni.hasNext(); ) {
Node child = ni.nextNode();
if (child.isNodeType(Mail.TYPE)) {
childs.add(BaseMailModule.getProperties(session, child));
}
}
// Activity log
UserActivity.log(session.getUserID(), "GET_CHILD_MAILS", folderNode.getUUID(), fldPath);
} catch (javax.jcr.PathNotFoundException e) {
log.warn(e.getMessage(), e);
throw new PathNotFoundException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
throw new RepositoryException(e.getMessage(), e);
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("findChilds: {}", childs);
return childs;
}
@Override
public boolean isValid(String token, String mailPath) throws PathNotFoundException,
AccessDeniedException, RepositoryException, DatabaseException {
log.debug("isValid({}, {})", token, mailPath);
boolean valid = false;
Session session = null;
try {
if (token == null) {
session = JCRUtils.getSession();
} else {
session = JcrSessionManager.getInstance().get(token);
}
Node node = session.getRootNode().getNode(mailPath.substring(1));
if (node.isNodeType(Mail.TYPE)) {
valid = true;
}
} catch (javax.jcr.PathNotFoundException e) {
log.warn(e.getMessage(), e);
throw new PathNotFoundException(e.getMessage(), e);
} catch (javax.jcr.AccessDeniedException e) {
log.warn(e.getMessage(), e);
throw new AccessDeniedException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
throw new RepositoryException(e.getMessage(), e);
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("isValid: {}", valid);
return valid;
}
@Override
public String getPath(String token, String uuid) throws AccessDeniedException, RepositoryException,
DatabaseException {
log.debug("getPath({}, {})", token, uuid);
String path = null;
Session session = null;
try {
if (token == null) {
session = JCRUtils.getSession();
} else {
session = JcrSessionManager.getInstance().get(token);
}
Node node = session.getNodeByUUID(uuid);
if (node.isNodeType(Mail.TYPE)) {
path = node.getPath();
}
} catch (javax.jcr.AccessDeniedException e) {
log.warn(e.getMessage(), e);
throw new AccessDeniedException(e.getMessage(), e);
} catch (javax.jcr.RepositoryException e) {
log.error(e.getMessage(), e);
throw new RepositoryException(e.getMessage(), e);
} finally {
if (token == null) JCRUtils.logout(session);
}
log.debug("getPath: {}", path);
return path;
}
}