/*
- * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.
*
* This file is part of GSS.
*
package gr.ebs.gss.server.ejb;
import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
+
+import gr.ebs.gss.admin.client.ui.UsersTable;
import gr.ebs.gss.client.exceptions.DuplicateNameException;
import gr.ebs.gss.client.exceptions.GSSIOException;
import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
+import gr.ebs.gss.client.exceptions.InvitationUsedException;
import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
import gr.ebs.gss.client.exceptions.QuotaExceededException;
import gr.ebs.gss.server.domain.AuditInfo;
import gr.ebs.gss.server.domain.FileUploadStatus;
import gr.ebs.gss.server.domain.Folder;
import gr.ebs.gss.server.domain.Group;
+import gr.ebs.gss.server.domain.Invitation;
import gr.ebs.gss.server.domain.Nonce;
import gr.ebs.gss.server.domain.Permission;
import gr.ebs.gss.server.domain.User;
-import gr.ebs.gss.server.domain.dto.FileBodyDTO;
-import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
-import gr.ebs.gss.server.domain.dto.FolderDTO;
-import gr.ebs.gss.server.domain.dto.GroupDTO;
-import gr.ebs.gss.server.domain.dto.PermissionDTO;
+import gr.ebs.gss.server.domain.UserClass;
+import gr.ebs.gss.server.domain.UserLogin;
import gr.ebs.gss.server.domain.dto.StatsDTO;
import gr.ebs.gss.server.domain.dto.UserDTO;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import javax.ejb.EJB;
import javax.ejb.EJBException;
+import javax.ejb.EJBTransactionRolledbackException;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.jms.Queue;
import javax.jms.QueueConnectionFactory;
import javax.jms.Session;
-import javax.jws.WebMethod;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.HttpException;
-import org.apache.commons.httpclient.NameValuePair;
-import org.apache.commons.httpclient.methods.GetMethod;
-import org.apache.commons.httpclient.methods.PostMethod;
-import org.apache.commons.httpclient.methods.StringRequestEntity;
+import javax.persistence.PersistenceException;
+
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
+import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrDocument;
+import org.apache.solr.common.SolrDocumentList;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrInputDocument;
+import org.hibernate.exception.ConstraintViolationException;
+
+import com.novell.ldap.LDAPAttribute;
+import com.novell.ldap.LDAPAttributeSet;
+import com.novell.ldap.LDAPConnection;
+import com.novell.ldap.LDAPEntry;
+import com.novell.ldap.LDAPException;
/**
* The concrete implementation of the ExternalAPI interface.
*/
private static Random random = new Random();
+ /**
+ * Mark the folder and all of its parent folders as modified from the specified user.
+ */
+ private void touchParentFolders(Folder folder, User user, Date date) {
+ Folder f = folder;
+ while (f != null) {
+ AuditInfo ai = f.getAuditInfo();
+ ai.setModifiedBy(user);
+ ai.setModificationDate(date);
+ f.setAuditInfo(ai);
+ f = f.getParent();
+ }
+ }
+
+ private Long getRootFolderId(Long userId) throws ObjectNotFoundException {
+ if (userId == null)
+ throw new ObjectNotFoundException("No user specified");
+ return dao.getRootFolderId(userId);
+ }
+
@Override
- public FolderDTO getRootFolder(Long userId) throws ObjectNotFoundException {
+ public Folder getRootFolder(Long userId) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
Folder folder = dao.getRootFolder(userId);
- return folder.getDTO();
+ return folder;
}
- /*
- * (non-Javadoc)
- *
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getFolder(java.lang.Long)
- */
- public FolderDTO getFolder(final Long userId, final Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
+ @Override
+ public Folder getFolder(final Long userId, final Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (folderId == null)
// Check permissions
if (!folder.hasReadPermission(user))
throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
- return folder.getDTO();
+ return folder;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getUser(java.lang.Long)
- */
+ @Override
public User getUser(Long userId) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
return dao.getEntityById(User.class, userId);
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getUserDTO(java.lang.Long)
- */
+ @Override
public UserDTO getUserDTO(final Long userId) throws ObjectNotFoundException {
return getUser(userId).getDTO();
}
- /*
- * (non-Javadoc)
- *
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getGroup(java.lang.Long)
- */
- public GroupDTO getGroup(final Long groupId) throws ObjectNotFoundException {
+ @Override
+ public Group getGroup(final Long groupId) throws ObjectNotFoundException {
if (groupId == null)
throw new ObjectNotFoundException("No group specified");
final Group group = dao.getEntityById(Group.class, groupId);
- return group.getDTO();
+ return group;
}
@Override
- public GroupDTO getGroup(Long userId, String name) throws ObjectNotFoundException {
+ public Group getGroup(Long userId, String name) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (name == null)
List<Group> groups = user.getGroupsSpecified();
for (Group group: groups)
if (group.getName().equals(name))
- return group.getDTO();
+ return group;
throw new ObjectNotFoundException("Group " + name + " not found");
}
- /*
- * (non-Javadoc)
- *
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getGroups(java.lang.Long)
- */
- public List<GroupDTO> getGroups(final Long userId) throws ObjectNotFoundException {
+ @Override
+ public List<Group> getGroups(final Long userId) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
final List<Group> groups = dao.getGroups(userId);
- final List<GroupDTO> result = new ArrayList<GroupDTO>();
- for (final Group g : groups)
- result.add(g.getDTO());
- return result;
+ return groups;
}
@Override
- public List<FileHeaderDTO> getFiles(Long userId, Long folderId, boolean ignoreDeleted)
+ public List<FileHeader> getFiles(Long userId, Long folderId, boolean ignoreDeleted)
throws ObjectNotFoundException, InsufficientPermissionsException {
// Validate.
if (userId == null)
Folder folder = dao.getEntityById(Folder.class, folderId);
if (!folder.hasReadPermission(user))
throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
- // Do the actual work.
- List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
List<FileHeader> files = dao.getFiles(folderId, userId, ignoreDeleted);
- for (FileHeader f : files)
- result.add(f.getDTO());
- return result;
+ return files;
}
- /*
- * (non-Javadoc)
- *
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getUsers(java.lang.Long,
- * java.lang.Long)
- */
- public List<UserDTO> getUsers(final Long userId, final Long groupId) throws ObjectNotFoundException {
+ @Override
+ public List<User> getUsers(final Long userId, final Long groupId) throws ObjectNotFoundException {
// Validate.
if (userId == null)
throw new ObjectNotFoundException("No user specified");
// Do the actual work.
final List<User> users = dao.getUsers(groupId);
- final List<UserDTO> result = new ArrayList<UserDTO>();
- for (final User u : users)
- result.add(u.getDTO());
- return result;
+ return users;
}
@Override
- public FolderDTO createFolder(Long userId, Long parentId, String name)
+ public Folder createFolder(Long userId, Long parentId, String name)
throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException {
// Validate.
if (userId == null)
* @param creator
* @return the new folder
*/
- private FolderDTO createFolder(String name, Folder parent, User creator) {
+ private Folder createFolder(String name, Folder parent, User creator) {
Folder folder = new Folder();
folder.setName(name);
if (parent != null) {
auditInfo.setModifiedBy(creator);
auditInfo.setModificationDate(now);
folder.setAuditInfo(auditInfo);
+ touchParentFolders(folder, auditInfo.getModifiedBy(), auditInfo.getModificationDate());
if (parent != null)
for (Permission p : parent.getPermissions()) {
permission.setModifyACL(true);
folder.addPermission(permission);
}
+
+ if(parent != null)
+ folder.setReadForAll(parent.isReadForAll());
+
dao.create(folder);
- return folder.getDTO();
+ return folder;
}
- /*
- * Deletes the given folder and all its subfolders and files
- * Only the permissions for top folder are checked
- *
- * @see gr.ebs.gss.server.ejb.ExternalAPI#deleteFolder(java.lang.Long,
- * java.lang.Long)
- */
+ @Override
public void deleteFolder(final Long userId, final Long folderId) throws InsufficientPermissionsException, ObjectNotFoundException {
// Validate.
if (userId == null)
removeSubfolderFiles(folder);
parent.removeSubfolder(folder);
dao.delete(folder);
+ touchParentFolders(parent, user, new Date());
}
/**
}
}
+ @Override
@SuppressWarnings("unchecked")
- public List<FolderDTO> getSubfolders(Long userId, Long folderId)
+ public List<Folder> getSubfolders(Long userId, Long folderId)
throws ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
Folder folder = dao.getEntityById(Folder.class, folderId);
if (!folder.hasReadPermission(user))
throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
- List<FolderDTO> result = new ArrayList<FolderDTO>();
+ List<Folder> result = new ArrayList<Folder>();
if (folder.hasReadPermission(user))
for (Folder f : folder.getSubfolders())
if (f.hasReadPermission(user) && !f.isDeleted())
- result.add(f.getDTO());
+ result.add(f);
return result;
}
@Override
- public FolderDTO modifyFolder(Long userId, Long folderId, String folderName)
- throws InsufficientPermissionsException, ObjectNotFoundException, DuplicateNameException {
+ public Folder updateFolder(Long userId, Long folderId, String folderName,
+ Boolean readForAll,
+ Set<Permission> permissions)
+ throws InsufficientPermissionsException, ObjectNotFoundException,
+ DuplicateNameException {
// Validate.
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (folderId == null)
throw new ObjectNotFoundException("No folder specified");
- if (StringUtils.isEmpty(folderName))
- throw new ObjectNotFoundException("New folder name is empty");
Folder folder = dao.getEntityById(Folder.class, folderId);
User user = dao.getEntityById(User.class, userId);
- if (!folder.hasWritePermission(user))
+ if (folderName != null && !folder.hasWritePermission(user))
throw new InsufficientPermissionsException("You don't have the necessary permissions");
+ if(permissions != null && !permissions.isEmpty() && !folder.hasModifyACLPermission(user))
+ throw new InsufficientPermissionsException("You don't have the necessary permissions");
+ // Check permissions for making file public.
+ if (readForAll != null && !user.equals(folder.getOwner()))
+ throw new InsufficientPermissionsException("Only the owner can make a folder public or not public");
Folder parent = folder.getParent();
- if (parent != null)
- if (!folder.getName().equals(folderName) && dao.existsFolderOrFile(parent.getId(), folderName))
- throw new DuplicateNameException("A folder or file with the name '" + folderName + "' already exists at this level");
+ if (folderName != null) {
+ if (parent != null)
+ if (!folder.getName().equals(folderName) && dao.existsFolderOrFile(parent.getId(), folderName))
+ throw new DuplicateNameException("A folder or file with the name '" + folderName + "' already exists at this level");
- // Do the actual modification.
- folder.setName(folderName);
+ // Do the actual modification.
+ folder.setName(folderName);
+ }
+ if (permissions != null)
+ setFolderPermissions(user, folder, permissions);
+ if (readForAll != null)
+ setFolderReadForAll(user, folder, readForAll);
+ folder.getAuditInfo().setModificationDate(new Date());
+ folder.getAuditInfo().setModifiedBy(user);
dao.update(folder);
- return folder.getDTO();
+ touchParentFolders(folder, user, new Date());
+ // Re-index the folder contents if it was modified.
+ if ((permissions != null && !permissions.isEmpty()) || readForAll != null) {
+ indexFolder(folder);
+ }
+
+ return folder;
}
- /*
- * (non-Javadoc)
- *
- * @see gr.ebs.gss.server.ejb.ExternalAPI#createGroup(java.lang.Long,
- * java.lang.String)
- */
+ private void indexFolder(Folder folder) {
+ for (FileHeader fh : folder.getFiles())
+ indexFile(fh.getId(), false);
+ for (Folder f : folder.getSubfolders())
+ indexFolder(f);
+ }
+
+ @Override
public void createGroup(final Long userId, final String name) throws ObjectNotFoundException, DuplicateNameException {
// Validate.
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (StringUtils.isEmpty(name))
throw new ObjectNotFoundException("New group name is empty");
+ if (name.indexOf('/')>=0)
+ throw new IllegalArgumentException("Character '/' is not allowed in group name");
if (dao.existsGroup(userId, name))
throw new DuplicateNameException("A group with the name '" + name + "' already exists");
owner.createGroup(name);
}
- /*
- * (non-Javadoc)
- *
- * @see gr.ebs.gss.server.ejb.ExternalAPI#deleteGroup(java.lang.Long,
- * java.lang.Long)
- */
+ @Override
public void deleteGroup(final Long userId, final Long groupId) throws ObjectNotFoundException, InsufficientPermissionsException {
// Validate.
if (userId == null)
// Do the actual work.
final User owner = dao.getEntityById(User.class, userId);
final Group group = dao.getEntityById(Group.class, groupId);
+ final Date now = new Date();
// Only delete the group if actually owned by the user.
if (group.getOwner().equals(owner)) {
List<Folder> folders = dao.getFoldersPermittedForGroup(userId, groupId);
for (Folder f : folders){
f.getPermissions().removeAll(group.getPermissions());
- for(FileHeader file : f.getFiles())
+ for(FileHeader file : f.getFiles()){
file.getPermissions().removeAll(group.getPermissions());
+ }
}
- List<FileHeader> files = dao.getSharedFilesNotInSharedFolders(userId);
- for(FileHeader h : files)
+ List<FileHeader> files = dao.getFilesPermittedForGroup(userId, groupId);
+ for(FileHeader h : files){
h.getPermissions().removeAll(group.getPermissions());
+ }
owner.removeSpecifiedGroup(group);
dao.delete(group);
}
}
@Override
- public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
+ public FileHeader createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
InsufficientPermissionsException, QuotaExceededException {
File file = null;
/* (non-Javadoc)
* @see gr.ebs.gss.server.ejb.ExternalAPIRemote#indexFile(java.lang.Long, boolean)
*/
+ @Override
public void indexFile(Long fileId, boolean delete) {
Connection qConn = null;
Session session = null;
return secondFolder + File.separator + filename;
}
- /*
- * (non-Javadoc)
- *
- * @see gr.ebs.gss.server.ejb.ExternalAPI#deleteFile(java.lang.Long,
- * java.lang.Long)
- */
+ @Override
public void deleteFile(final Long userId, final Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
// Validate.
if (userId == null)
for (final FileBody body : file.getBodies())
deleteActualFile(body.getStoredFilePath());
dao.delete(file);
+ touchParentFolders(parent, user, new Date());
indexFile(fileId, true);
}
- private void deleteActualFile(String filePath) {
- if (filePath == null)
+ @Override
+ public void deleteActualFile(String path) {
+ if (path == null)
return;
- File file = new File(filePath);
+ File file = new File(path);
if (!file.delete())
- logger.error("Could not delete file " + filePath);
+ logger.error("Could not delete file " + path);
}
- /*
- * (non-Javadoc)
- *
- * @see gr.ebs.gss.server.ejb.ExternalAPI#createTag(java.lang.Long,
- * java.lang.Long, java.lang.String)
- */
+ @Override
public void createTag(final Long userId, final Long fileHeaderId, final String tag) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
final User user = dao.getEntityById(User.class, userId);
final FileHeader fh = dao.getEntityById(FileHeader.class, fileHeaderId);
+ final Folder parent = fh.getFolder();
+ if (parent == null)
+ throw new ObjectNotFoundException("The specified file has no parent folder");
user.addTag(fh, tag);
+ touchParentFolders(parent, user, new Date());
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getUserTags(java.lang.Long)
- */
- @WebMethod(operationName = "getUserTags")
+ @Override
public Set<String> getUserTags(final Long userId) throws ObjectNotFoundException {
return dao.getUserTags(userId);
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#updateFile(java.lang.Long, java.lang.Long, java.lang.String, java.util.Set)
- */
- public void updateFile(Long userId, Long fileId, String name, String tagSet) throws ObjectNotFoundException, InsufficientPermissionsException {
+ @Override
+ public void updateFile(Long userId, Long fileId, String name,
+ String tagSet, Date modificationDate, Boolean versioned,
+ Boolean readForAll, Set<Permission> permissions)
+ throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (fileId == null)
throw new ObjectNotFoundException("No file specified");
FileHeader file = dao.getEntityById(FileHeader.class, fileId);
- User user = dao.getEntityById(User.class, userId);
- if (!file.hasWritePermission(user))
- throw new InsufficientPermissionsException("User " + user.getId() + " cannot update file " + file.getName() + "(" + file.getId() + ")");
+ final Folder parent = file.getFolder();
+ if (parent == null)
+ throw new ObjectNotFoundException("The specified file has no parent folder");
- if (name != null)
+ User user = dao.getEntityById(User.class, userId);
+ // Check permissions for modifying the file metadata.
+ if ((name != null || tagSet != null || modificationDate != null || versioned != null) && !file.hasWritePermission(user))
+ throw new InsufficientPermissionsException("User " + user.getId() + " cannot update file " + file.getName() + "(" + file.getId() + ")");
+ // Check permissions for making file public.
+ if (readForAll != null && !user.equals(file.getOwner()))
+ throw new InsufficientPermissionsException("Only the owner can make a file public or not public");
+ // Check permissions for modifying the ACL.
+ if(permissions != null && !permissions.isEmpty() && !file.hasModifyACLPermission(user))
+ throw new InsufficientPermissionsException("User " + user.getId() + " cannot update the permissions on file " + file.getName() + "(" + file.getId() + ")");
+
+ if (name != null) {
+ // Do plain check for file already exists.
+ // Extreme concurrency case should be caught by constraint violation later.
+ if (dao.existsFolderOrFile(parent.getId(), name)) throw new DuplicateNameException("A file or folder with the name '" + name + "' already exists");
file.setName(name);
- List<FileTag> tags = file.getFileTags();
+ }
+ if (modificationDate != null)
+ file.getAuditInfo().setModificationDate(modificationDate);
+ else
+ file.getAuditInfo().setModificationDate(new Date());
+ file.getAuditInfo().setModifiedBy(user);
+
+ List<FileTag> tags = file.getFileTags();
if (tagSet != null) {
Iterator<FileTag> i = tags.iterator();
while (i.hasNext()) {
while (st.hasMoreTokens())
new FileTag(user, file, st.nextToken().trim());
}
+ if (versioned != null && !file.isVersioned() == versioned) {
+ if (file.isVersioned())
+ removeOldVersions(userId, fileId);
+ file.setVersioned(versioned);
+ }
+ if (readForAll != null && user.equals(file.getOwner()))
+ file.setReadForAll(readForAll);
+ if (permissions != null && !permissions.isEmpty())
+ setFilePermissions(file, permissions);
+
+ /*
+ * Force constraint violation to manifest itself here.
+ * This should cover extreme concurrency cases that the simple check
+ * above hasn't caught.
+ */
+ try {
+ dao.flush();
+ }
+ catch (EJBTransactionRolledbackException e) {
+ Throwable cause = e.getCause();
+ if (cause instanceof PersistenceException && cause.getCause() instanceof ConstraintViolationException)
+ throw new DuplicateNameException("A file or folder with the name '" + name + "' already exists");
+ throw e;
+ }
+
+ touchParentFolders(parent, user, new Date());
// Re-index the file if it was modified.
- if (name != null || tagSet != null)
+ if (name != null || tagSet != null || (permissions != null && !permissions.isEmpty()) || readForAll != null)
indexFile(fileId, false);
}
/* (non-Javadoc)
* @see gr.ebs.gss.server.ejb.ExternalAPI#getFileContents(java.lang.Long, java.lang.Long, java.lang.Long)
*/
+ @Override
public InputStream getFileContents(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
}
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getFile(java.lang.Long, java.lang.Long)
- */
- public FileHeaderDTO getFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
+ @Override
+ public FileHeader getFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (fileId == null)
final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
throw new InsufficientPermissionsException("You don't have the necessary permissions");
- return file.getDTO();
+ return file;
}
@Override
- public FileBodyDTO getFileBody(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
+ public FileBody getFileBody(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (fileId == null)
if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
throw new InsufficientPermissionsException("You don't have the necessary permissions");
FileBody body = dao.getEntityById(FileBody.class, bodyId);
- return body.getDTO();
+ return body;
}
@Override
return getRootFolder(owner.getId());
// Store the last element, since it requires special handling.
String lastElement = pathElements.remove(pathElements.size() - 1);
- FolderDTO cursor = getRootFolder(owner.getId());
+
+ Folder cursor = null;
+ Long rootFolderId = getRootFolderId(owner.getId());
// Traverse and verify the specified folder path.
for (String pathElement : pathElements) {
- cursor = getFolder(cursor.getId(), pathElement);
+ cursor = getFolder(cursor==null ? rootFolderId : cursor.getId(), pathElement);
if (cursor.isDeleted())
throw new ObjectNotFoundException("Folder " + cursor.getPath() + " not found");
}
// Use the lastElement to retrieve the actual resource.
Object resource = null;
try {
- FileHeaderDTO file = getFile(cursor.getId(), lastElement);
+ FileHeader file = getFile(cursor==null ? rootFolderId : cursor.getId(), lastElement);
if (ignoreDeleted && file.isDeleted())
throw new ObjectNotFoundException("Resource not found");
resource = file;
} catch (ObjectNotFoundException e) {
// Perhaps the requested resource is not a file, so
// check for folders as well.
- FolderDTO folder = getFolder(cursor.getId(), lastElement);
+ Folder folder = getFolder(cursor==null ? rootFolderId : cursor.getId(), lastElement).getDTO();
if (ignoreDeleted && folder.isDeleted())
throw new ObjectNotFoundException("Resource not found");
resource = folder;
* Retrieve a file for the specified user that has the specified name and
* its parent folder has id equal to folderId.
*
- * @param userId the ID of the current user
* @param folderId the ID of the parent folder
* @param name the name of the requested file
* @return the file found
* found, with the exception message mentioning the precise
* problem
*/
- private FileHeaderDTO getFile(Long folderId, String name) throws ObjectNotFoundException {
+ private FileHeader getFile(Long folderId, String name) throws ObjectNotFoundException {
if (folderId == null)
throw new ObjectNotFoundException("No parent folder specified");
if (StringUtils.isEmpty(name))
throw new ObjectNotFoundException("No file specified");
FileHeader file = dao.getFile(folderId, name);
- return file.getDTO();
+ return file;
}
/**
* found, with the exception message mentioning the precise
* problem
*/
- private FolderDTO getFolder(Long parentId, String name) throws ObjectNotFoundException {
+ private Folder getFolder(Long parentId, String name) throws ObjectNotFoundException {
if (parentId == null)
throw new ObjectNotFoundException("No parent folder specified");
if (StringUtils.isEmpty(name))
throw new ObjectNotFoundException("No folder specified");
Folder folder = dao.getFolder(parentId, name);
- return folder.getDTO();
+ return folder;
}
- private FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
+ private FileHeader updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
File file = null;
try {
file = uploadFile(resourceInputStream, userId);
throw new ObjectNotFoundException("No destination specified");
Object destination = getResourceAtPath(userId, getParentPath(dest), true);
- if (!(destination instanceof FolderDTO))
+ if (!(destination instanceof Folder))
throw new ObjectNotFoundException("Destination parent folder not found");
- FolderDTO parent = (FolderDTO) destination;
+ Folder parent = (Folder) destination;
copyFile(userId, fileId, parent.getId(), getLastElement(dest));
}
throw new ObjectNotFoundException("No destination specified");
Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
- if (!(destination instanceof FolderDTO))
+ if (!(destination instanceof Folder))
throw new ObjectNotFoundException("Destination parent folder not found");
- FolderDTO parent = (FolderDTO) destination;
+ Folder parent = (Folder) destination;
copyFile(userId, fileId, parent.getId(), getLastElement(dest));
}
throw new ObjectNotFoundException("No destination specified");
Object destination = getResourceAtPath(userId, getParentPath(dest), true);
- if (!(destination instanceof FolderDTO))
+ if (!(destination instanceof Folder))
throw new ObjectNotFoundException("Destination folder not found");
- FolderDTO parent = (FolderDTO) destination;
+ Folder parent = (Folder) destination;
copyFolder(userId, folderId, parent.getId(), getLastElement(dest));
}
throw new ObjectNotFoundException("No destination specified");
Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
- if (!(destination instanceof FolderDTO))
+ if (!(destination instanceof Folder))
throw new ObjectNotFoundException("Destination folder not found");
- FolderDTO parent = (FolderDTO) destination;
+ Folder parent = (Folder) destination;
copyFolderStructure(userId, folderId, parent.getId(), getLastElement(dest));
}
if (parent == null)
throw new ObjectNotFoundException("The specified file has no parent folder");
User user = dao.getEntityById(User.class, userId);
- if (!file.hasDeletePermission(user))
- throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
-
- file.setDeleted(true);
- dao.update(file);
+ trashFile(user, file);
+ touchParentFolders(parent, user, new Date());
}
+ private void trashFile(User user, FileHeader file) throws InsufficientPermissionsException {
+ if (!file.hasDeletePermission(user))
+ throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
+
+ file.setDeleted(true);
+ }
+
@Override
public void moveFileToPath(Long userId, Long ownerId, Long fileId, String dest) throws ObjectNotFoundException, InsufficientPermissionsException, QuotaExceededException {
if (userId == null)
throw new ObjectNotFoundException("No destination specified");
Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
- if (!(destination instanceof FolderDTO))
+ if (!(destination instanceof Folder))
throw new ObjectNotFoundException("Destination parent folder not found");
- FolderDTO parent = (FolderDTO) destination;
+ Folder parent = (Folder) destination;
moveFile(userId, fileId, parent.getId(), getLastElement(dest));
}
throw new ObjectNotFoundException("No destination file name specified");
FileHeader file = dao.getEntityById(FileHeader.class, fileId);
+ Folder source = file.getFolder();
Folder destination = dao.getEntityById(Folder.class, destId);
User owner = dao.getEntityById(User.class, userId);
}
// move the file to the destination folder
file.setFolder(destination);
+ touchParentFolders(source, owner, new Date());
+ touchParentFolders(destination, owner, new Date());
}
@Override
- public void moveFolderToPath(Long userId, Long ownerId, Long folderId, String dest) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
+ public void moveFolderToPath(Long userId, Long ownerId, Long folderId, String dest) throws ObjectNotFoundException, InsufficientPermissionsException, QuotaExceededException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (ownerId == null)
throw new ObjectNotFoundException("No destination specified");
Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
- if (!(destination instanceof FolderDTO))
+ if (!(destination instanceof Folder))
throw new ObjectNotFoundException("Destination parent folder not found");
- FolderDTO parent = (FolderDTO) destination;
+ Folder parent = (Folder) destination;
moveFolder(userId, folderId, parent.getId(), getLastElement(dest));
}
@Override
- public void moveFolder(Long userId, Long folderId, Long destId, String destName) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
- // TODO Simple Move and delete of original folder, in production
- // scenario we must first check individual files and folders permissions
- copyFolderStructure(userId, folderId, destId, destName);
- deleteFolder(userId, folderId);
+ public void moveFolder(Long userId, Long folderId, Long destId, String destName)
+ throws ObjectNotFoundException, InsufficientPermissionsException,
+ QuotaExceededException {
+ Folder source = dao.getEntityById(Folder.class, folderId);
+ Folder destination = dao.getEntityById(Folder.class, destId);
+ User user = dao.getEntityById(User.class, userId);
+ User sourceOwner = source.getOwner();
+ User destinationOwner = destination.getOwner();
+ // Do not move trashed folders and contents.
+ if (source.isDeleted())
+ return;
+ // Check permissions.
+ if (!destination.hasWritePermission(user)
+ || !source.hasReadPermission(user)
+ || !source.hasWritePermission(user))
+ throw new InsufficientPermissionsException("You don't have the " +
+ "necessary permissions");
+ // Use the same timestamp for all subsequent modifications to make
+ // changes appear simultaneous.
+ Date now = new Date();
+ // If source and destination are not in the same user's namespace,
+ // change owners and check quota.
+ if (!sourceOwner.equals(destinationOwner)) {
+ changeOwner(source, destinationOwner, user, now);
+ if (getQuotaLeft(destinationOwner.getId()) < 0)
+ throw new QuotaExceededException("Not enough free space " +
+ "available in destination folder");
+ }
+ // Perform the move.
+ Folder oldParent = source.getParent();
+ oldParent.removeSubfolder(source);
+ destination.addSubfolder(source);
+ // Mark the former parent and destination trees upwards as modified.
+ touchParentFolders(oldParent, user, now);
+ touchParentFolders(source, user, now);
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getDeletedFiles(java.lang.Long)
+ /**
+ * Recursively change the owner of the specified folder and all of its
+ * contents to the specified owner. Also mark them all as modified with the
+ * specified modifier and modificationDate.
*/
- public List<FileHeaderDTO> getDeletedFiles(Long userId) throws ObjectNotFoundException {
+ private void changeOwner(Folder folder, User owner, User modifier, Date modificationDate) {
+ for (FileHeader file: folder.getFiles()) {
+ file.setOwner(owner);
+ file.getAuditInfo().setModificationDate(modificationDate);
+ file.getAuditInfo().setModifiedBy(modifier);
+ }
+ for (Folder sub: folder.getSubfolders())
+ changeOwner(sub, owner, modifier, modificationDate);
+ folder.setOwner(owner);
+ folder.getAuditInfo().setModificationDate(modificationDate);
+ folder.getAuditInfo().setModifiedBy(modifier);
+ }
+
+ @Override
+ public List<FileHeader> getDeletedFiles(Long userId) throws ObjectNotFoundException {
// Validate.
if (userId == null)
throw new ObjectNotFoundException("No user specified");
// Do the actual work.
- final List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
final List<FileHeader> files = dao.getDeletedFiles(userId);
- for (final FileHeader f : files)
- result.add(f.getDTO());
- return result;
+ return files;
}
@Override
if (parent == null)
throw new ObjectNotFoundException("The specified file has no parent folder");
User user = dao.getEntityById(User.class, userId);
- if (!file.hasDeletePermission(user))
- throw new InsufficientPermissionsException("User " + user.getUsername() +
- " cannot restore file " + file.getName());
-
- file.setDeleted(false);
- dao.update(file);
+ untrashFile(user, file);
+ touchParentFolders(parent, user, new Date());
}
+ private void untrashFile(User user, FileHeader file) throws InsufficientPermissionsException {
+ if (!file.hasDeletePermission(user))
+ throw new InsufficientPermissionsException("User " + user.getUsername() +
+ " cannot restore file " + file.getName());
+
+ file.setDeleted(false);
+ }
+
@Override
public void moveFolderToTrash(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
- if (userId == null)
- throw new ObjectNotFoundException("No user specified");
- if (folderId == null)
- throw new ObjectNotFoundException("No folder specified");
- Folder folder = dao.getEntityById(Folder.class, folderId);
- User user = dao.getEntityById(User.class, userId);
- if (!folder.hasDeletePermission(user))
- throw new InsufficientPermissionsException("You don't have the necessary permissions");
- folder.setDeleted(true);
- dao.update(folder);
- for (FileHeader file : folder.getFiles())
- moveFileToTrash(userId, file.getId());
- for (Folder subFolder : folder.getSubfolders())
- moveFolderToTrash(userId, subFolder.getId());
-
- }
+ if (userId == null)
+ throw new ObjectNotFoundException("No user specified");
+ if (folderId == null)
+ throw new ObjectNotFoundException("No folder specified");
+ Folder folder = dao.getEntityById(Folder.class, folderId);
+ User user = dao.getEntityById(User.class, userId);
+ trashFolder(user, folder);
+ touchParentFolders(folder, user, new Date());
+ }
+
+ private void trashFolder(User user, Folder folder) throws ObjectNotFoundException, InsufficientPermissionsException {
+ if (!folder.hasDeletePermission(user))
+ throw new InsufficientPermissionsException("You don't have the necessary permissions");
+ folder.setDeleted(true);
+ for (FileHeader file : folder.getFiles())
+ trashFile(user, file);
+ for (Folder subFolder : folder.getSubfolders())
+ trashFolder(user, subFolder);
+ }
@Override
public void removeFolderFromTrash(Long userId, Long folderId)
throw new ObjectNotFoundException("No folder specified");
Folder folder = dao.getEntityById(Folder.class, folderId);
User user = dao.getEntityById(User.class, userId);
- if (!folder.hasDeletePermission(user))
- throw new InsufficientPermissionsException("User " + user.getUsername() +
- " cannot restore folder " + folder.getName());
- folder.setDeleted(false);
- for (FileHeader file : folder.getFiles())
- removeFileFromTrash(userId, file.getId());
- for (Folder subFolder : folder.getSubfolders())
- removeFolderFromTrash(userId, subFolder.getId());
- dao.update(folder);
+ untrashFolder(user, folder);
+ touchParentFolders(folder, user, new Date());
}
+ private void untrashFolder(User user, Folder folder) throws ObjectNotFoundException, InsufficientPermissionsException {
+ if (!folder.hasDeletePermission(user))
+ throw new InsufficientPermissionsException("User " + user.getUsername() +
+ " cannot restore folder " + folder.getName());
+ folder.setDeleted(false);
+ for (FileHeader file : folder.getFiles())
+ untrashFile(user, file);
+ for (Folder subFolder : folder.getSubfolders())
+ untrashFolder(user, subFolder);
+ }
+
@Override
- public List<FolderDTO> getDeletedRootFolders(Long userId) throws ObjectNotFoundException {
+ public List<Folder> getDeletedRootFolders(Long userId) throws ObjectNotFoundException {
List<Folder> folders = dao.getDeletedRootFolders(userId);
- List<FolderDTO> result = new ArrayList<FolderDTO>();
- for (Folder folder : folders)
- result.add(folder.getDTO());
- return result;
+ return folders;
}
@Override
public void emptyTrash(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException {
- List<FolderDTO> deletedRootFolders = getDeletedRootFolders(userId);
- for (FolderDTO fdto : deletedRootFolders)
- deleteFolder(userId, fdto.getId());
- List<FileHeaderDTO> deletedFiles = getDeletedFiles(userId);
- for (FileHeaderDTO filedto : deletedFiles)
- deleteFile(userId, filedto.getId());
+ List<Folder> deletedRootFolders = getDeletedRootFolders(userId);
+ for (Folder folder : deletedRootFolders)
+ deleteFolder(userId, folder.getId());
+ List<FileHeader> deletedFiles = getDeletedFiles(userId);
+ for (FileHeader file : deletedFiles)
+ deleteFile(userId, file.getId());
}
@Override
public void restoreTrash(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException {
- List<FolderDTO> deletedRootFolders = getDeletedRootFolders(userId);
- for (FolderDTO fdto : deletedRootFolders)
- removeFolderFromTrash(userId, fdto.getId());
- List<FileHeaderDTO> deletedFiles = getDeletedFiles(userId);
- for (FileHeaderDTO filedto : deletedFiles)
- removeFileFromTrash(userId, filedto.getId());
+ List<Folder> deletedRootFolders = getDeletedRootFolders(userId);
+ for (Folder folder : deletedRootFolders)
+ removeFolderFromTrash(userId, folder.getId());
+ List<FileHeader> deletedFiles = getDeletedFiles(userId);
+ for (FileHeader file : deletedFiles)
+ removeFileFromTrash(userId, file.getId());
}
@Override
- public User createUser(String username, String name, String mail) throws ObjectNotFoundException {
+ public User createUser(String username, String name, String mail,
+ String idp, String idpid) throws ObjectNotFoundException {
if (username == null)
throw new ObjectNotFoundException("No username specified");
if (name == null)
user.setUsername(username);
user.setName(name);
user.setEmail(mail);
+ user.setIdentityProvider(idp);
+ user.setIdentityProviderId(idpid);
Date now = new Date();
AuditInfo auditInfo = new AuditInfo();
auditInfo.setCreationDate(now);
auditInfo.setModificationDate(now);
user.setAuditInfo(auditInfo);
+ user.setActive(true);
user.generateAuthToken();
user.generateWebDAVPassword();
+ user.setUserClass(getDefaultUserClass());
dao.create(user);
// Make sure we get an ID in the user object.
dao.flush();
return user;
}
+ /**
+ * Get the default user class, which is the one with the lowest quota.
+ */
+ private UserClass getDefaultUserClass() {
+ return getUserClasses().get(0);
+ }
+
+ @Override
+ public List<UserClass> getUserClasses() {
+ List<UserClass> classes = dao.getUserClasses();
+ // Create a default user class for first-time use. Afterwards, the
+ // admin should modify or add to the userclass table.
+ if (classes.size() == 0) {
+ UserClass defaultClass = new UserClass();
+ defaultClass.setName("default");
+ Long defaultQuota = getConfiguration().getLong("quota", new Long(52428800L));
+ defaultClass.setQuota(defaultQuota);
+ dao.create(defaultClass);
+ classes.add(defaultClass);
+ }
+ return classes;
+ }
+
@Override
public User findUserByEmail(String email) {
return dao.findUserByEmail(email);
}
@Override
- public User updateUser(String username, String name, String mail) throws ObjectNotFoundException {
- if (username == null)
- throw new ObjectNotFoundException("No username specified");
-
- User user = dao.getUser(username);
- user.setName(name);
- user.setEmail(mail);
- return user;
- }
-
- @Override
public User findUser(String username) {
if (username == null)
return null;
return user;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getFolderPermissions(java.lang.Long, java.lang.Long)
- */
@Override
- public Set<PermissionDTO> getFolderPermissions(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
+ public Set<Permission> getFolderPermissions(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (folderId == null)
if(!folder.hasReadPermission(user))
throw new InsufficientPermissionsException("You don't have the necessary permissions");
Set<Permission> perms = folder.getPermissions();
- Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
+ Set<Permission> result = new LinkedHashSet<Permission>();
for (Permission perm : perms)
if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId()))
- result.add(perm.getDTO());
+ result.add(perm);
for (Permission perm : perms)
if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId())) {
} else
- result.add(perm.getDTO());
+ result.add(perm);
return result;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#setFolderPermissions(java.lang.Long, java.lang.Long, java.util.Set)
+ /**
+ * Set the provided permissions as the new permissions of the specified
+ * folder.
+ *
+ * @param user
+ * @param folder
+ * @param permissions
+ * @throws ObjectNotFoundException
+ * @throws InsufficientPermissionsException
*/
- @Override
- public void setFolderPermissions(Long userId, Long folderId, Set<PermissionDTO> permissions) throws ObjectNotFoundException, InsufficientPermissionsException {
- if (userId == null)
- throw new ObjectNotFoundException("No user specified");
- if (folderId == null)
- throw new ObjectNotFoundException("No folder specified");
- User user = dao.getEntityById(User.class, userId);
- Folder folder = dao.getEntityById(Folder.class, folderId);
- if(!folder.hasModifyACLPermission(user))
- throw new InsufficientPermissionsException("You don't have the necessary permissions");
- // Delete previous entries
- for (Permission perm: folder.getPermissions())
- dao.delete(perm);
- folder.getPermissions().clear();
- for (PermissionDTO dto : permissions) {
- if (dto.getUser()!=null && dto.getUser().getId().equals(folder.getOwner().getId()) && (!dto.hasRead() || !dto.hasWrite() || !dto.hasModifyACL()))
- throw new InsufficientPermissionsException("Can't remove permissions from owner");
- // Don't include 'empty' permission
- if (!dto.getRead() && !dto.getWrite() && !dto.getModifyACL()) continue;
- folder.addPermission(getPermission(dto));
+ private void setFolderPermissions(User user, Folder folder, Set<Permission> permissions) throws ObjectNotFoundException, InsufficientPermissionsException {
+ if (permissions != null && !permissions.isEmpty()) {
+ User owner = folder.getOwner();
+ Permission ownerPerm = null;
+ for (Permission perm : permissions)
+ if (perm.getUser() != null && perm.getUser().getId().equals(owner.getId())) {
+ ownerPerm = perm;
+ break;
+ }
+ if (ownerPerm == null || !ownerPerm.hasRead() || !ownerPerm.hasWrite() || !ownerPerm.hasModifyACL())
+ throw new InsufficientPermissionsException("Can't remove permissions from owner");
+ // Delete previous entries
+ for (Permission perm: folder.getPermissions())
+ dao.delete(perm);
+ folder.getPermissions().clear();
+ for (Permission p : permissions) {
+ // Skip 'empty' permission entries.
+ if (!p.getRead() && !p.getWrite() && !p.getModifyACL()) continue;
+ folder.addPermission(getPermission(p));
+ }
+ dao.update(folder);
+ for (FileHeader file : folder.getFiles()) {
+ setFilePermissions(file, permissions);
+ Date now = new Date();
+ file.getAuditInfo().setModificationDate(now);
+ file.getAuditInfo().setModifiedBy(user);
+ }
+ for (Folder sub : folder.getSubfolders())
+ setFolderPermissions(user, sub, permissions);
}
- dao.update(folder);
- for (FileHeader fh : folder.getFiles())
- setFilePermissions(userId, fh.getId(), fh.isReadForAll(), permissions);
- for (Folder sub : folder.getSubfolders())
- setFolderPermissions(userId, sub.getId(), permissions);
}
- private Permission getPermission(PermissionDTO dto) throws ObjectNotFoundException {
+ private Permission getPermission(Permission perm) throws ObjectNotFoundException {
Permission res = new Permission();
- if (dto.getGroup() != null)
- res.setGroup(dao.getEntityById(Group.class, dto.getGroup().getId()));
- else if (dto.getUser() != null)
- if (dto.getUser().getId() == null)
- res.setUser(dao.getUser(dto.getUser().getUsername()));
+ if (perm.getGroup() != null)
+ res.setGroup(dao.getEntityById(Group.class, perm.getGroup().getId()));
+ else if (perm.getUser() != null)
+ if (perm.getUser().getId() == null)
+ res.setUser(dao.getUser(perm.getUser().getUsername()));
else
- res.setUser(dao.getEntityById(User.class, dto.getUser().getId()));
- res.setRead(dto.hasRead());
- res.setWrite(dto.hasWrite());
- res.setModifyACL(dto.hasModifyACL());
+ res.setUser(dao.getEntityById(User.class, perm.getUser().getId()));
+ res.setRead(perm.hasRead());
+ res.setWrite(perm.hasWrite());
+ res.setModifyACL(perm.hasModifyACL());
return res;
}
* @see gr.ebs.gss.server.ejb.ExternalAPI#getUsersByUserNameLike(java.lang.String)
*/
@Override
- public List<UserDTO> getUsersByUserNameLike(String username) {
+ public List<User> getUsersByUserNameLike(String username) {
List<User> users = dao.getUsersByUserNameLike(username);
- List<UserDTO> result = new ArrayList<UserDTO>();
- for (User u : users)
- result.add(u.getDTO());
- return result;
+ return users;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#addUserToGroup(java.lang.Long, java.lang.Long, java.lang.Long)
- */
@Override
public void addUserToGroup(Long userId, Long groupId, Long userToAddId) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException {
if (userId == null)
}
@Override
- public List<FolderDTO> getSharedRootFolders(Long userId) throws ObjectNotFoundException {
+ public List<Folder> getSharedRootFolders(Long userId) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
List<Folder> folders = dao.getSharedRootFolders(userId);
- List<FolderDTO> result = new ArrayList<FolderDTO>();
+ List<Folder> result = new ArrayList<Folder>();
for (Folder f : folders) {
- FolderDTO dto = f.getDTO();
- dto.setSubfolders(getSharedSubfolders(userId, f.getId()));
- result.add(dto);
+ Folder lf = f;
+ lf.setSubfolders(getSharedSubfolders(userId, f.getId()));
+ result.add(lf);
}
return result;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#removeMemberFromGroup(java.lang.Long, java.lang.Long, java.lang.Long)
- */
@Override
public void removeMemberFromGroup(Long userId, Long groupId, Long memberId) throws ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getUsersSharingFoldersForUser(java.lang.Long)
- */
@Override
- public List<UserDTO> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException {
+ public List<User> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException {
List<User> users = dao.getUsersSharingFoldersForUser(userId);
List<User> usersFiles = dao.getUsersSharingFilesForUser(userId);
- List<UserDTO> res = new ArrayList<UserDTO>();
+ List<User> result = new ArrayList<User>();
for (User u : users)
- res.add(u.getDTO());
+ result.add(u);
for(User fu : usersFiles)
if(!users.contains(fu))
- res.add(fu.getDTO());
- return res;
+ result.add(fu);
+ return result;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getFilePermissions(java.lang.Long, java.lang.Long)
- */
@Override
- public Set<PermissionDTO> getFilePermissions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
+ public Set<Permission> getFilePermissions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (fileId == null)
if(!folder.hasReadPermission(user))
throw new InsufficientPermissionsException("You don't have the necessary permissions");
Set<Permission> perms = folder.getPermissions();
- Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
+ Set<Permission> result = new LinkedHashSet<Permission>();
for (Permission perm : perms)
if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId()))
- result.add(perm.getDTO());
+ result.add(perm);
for (Permission perm : perms)
if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId())) {
} else
- result.add(perm.getDTO());
+ result.add(perm);
return result;
}
- @Override
- public void setFilePermissions(Long userId, Long fileId, Boolean readForAll, Set<PermissionDTO> permissions) throws ObjectNotFoundException, InsufficientPermissionsException {
- if (userId == null)
- throw new ObjectNotFoundException("No user specified");
- if (fileId == null)
- throw new ObjectNotFoundException("No folder specified");
-
- User user = dao.getEntityById(User.class, userId);
- FileHeader file = dao.getEntityById(FileHeader.class, fileId);
- if(!file.hasModifyACLPermission(user))
- throw new InsufficientPermissionsException("You don't have the necessary permissions");
-
- if (readForAll != null)
- if (user.equals(file.getOwner()))
- file.setReadForAll(readForAll);
- else
- throw new InsufficientPermissionsException("Only the owner can change the read-for-all flag");
-
- // Update the file if there was a change.
- if (readForAll != null || permissions != null && !permissions.isEmpty()) {
- if (permissions != null && !permissions.isEmpty()) {
- // Delete previous entries
- for (Permission perm: file.getPermissions())
- dao.delete(perm);
- file.getPermissions().clear();
- for (PermissionDTO dto : permissions) {
- if (dto.getUser()!=null && dto.getUser().getId().equals(file.getOwner().getId()) && (!dto.hasRead() || !dto.hasWrite() || !dto.hasModifyACL()))
- throw new InsufficientPermissionsException("Can't remove permissions from owner");
- // Don't include 'empty' permission
- if (!dto.getRead() && !dto.getWrite() && !dto.getModifyACL()) continue;
- file.addPermission(getPermission(dto));
+ /**
+ * Set the provided permissions as the new permissions of the specified
+ * file. This method sets the modification date/user attributes to the
+ * current values as a side effect.
+ *
+ * @param file
+ * @param permissions
+ * @throws ObjectNotFoundException
+ * @throws InsufficientPermissionsException
+ */
+ private void setFilePermissions(FileHeader file,
+ Set<Permission> permissions)
+ throws ObjectNotFoundException, InsufficientPermissionsException {
+ if (permissions != null && !permissions.isEmpty()) {
+ Permission ownerPerm = null;
+ for (Permission perm : permissions)
+ if (perm.getUser() != null && perm.getUser().getId().equals(file.getOwner().getId())) {
+ ownerPerm = perm;
+ break;
}
+ if (ownerPerm == null || !ownerPerm.hasRead() || !ownerPerm.hasWrite() || !ownerPerm.hasModifyACL())
+ throw new InsufficientPermissionsException("Can't remove permissions from owner");
+ // Delete previous entries.
+ for (Permission perm: file.getPermissions())
+ dao.delete(perm);
+ file.getPermissions().clear();
+ for (Permission perm : permissions) {
+ // Skip 'empty' permission entries.
+ if (!perm.getRead() && !perm.getWrite() && !perm.getModifyACL()) continue;
+ file.addPermission(getPermission(perm));
}
-
- dao.update(file);
+ dao.flush();
}
}
@Override
- public List<FileHeaderDTO> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException {
+ public List<FileHeader> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
List<FileHeader> files = dao.getSharedFilesNotInSharedFolders(userId);
- List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
- for (FileHeader f : files)
- result.add(f.getDTO());
- return result;
+ return files;
}
@Override
- public List<FileHeaderDTO> getSharedFiles(Long userId) throws ObjectNotFoundException {
+ public List<FileHeader> getSharedFiles(Long userId) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
List<FileHeader> files = dao.getSharedFiles(userId);
- List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
- for (FileHeader f : files)
- result.add(f.getDTO());
- return result;
+ return files;
}
@Override
- public List<FolderDTO> getSharedFolders(Long userId) throws ObjectNotFoundException {
+ public List<Folder> getSharedFolders(Long userId) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
List<Folder> folders = dao.getSharedFolders(userId);
- List<FolderDTO> result = new ArrayList<FolderDTO>();
- for (Folder f : folders)
- result.add(f.getDTO());
- return result;
+ return folders;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getSharedFiles(java.lang.Long, java.lang.Long)
- */
@Override
- public List<FileHeaderDTO> getSharedFiles(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
+ public List<FileHeader> getSharedFiles(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
if (ownerId == null)
throw new ObjectNotFoundException("No owner specified");
if (callingUserId == null)
throw new ObjectNotFoundException("No calling user specified");
List<FileHeader> folders = dao.getSharedFiles(ownerId, callingUserId);
- List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
- for (FileHeader f : folders)
- result.add(f.getDTO());
- return result;
+ return folders;
}
@Override
- public List<FolderDTO> getSharedRootFolders(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
+ public List<Folder> getSharedRootFolders(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
if (ownerId == null)
throw new ObjectNotFoundException("No owner specified");
if (callingUserId == null)
throw new ObjectNotFoundException("No calling user specified");
List<Folder> folders = dao.getSharedRootFolders(ownerId, callingUserId);
- List<FolderDTO> result = new ArrayList<FolderDTO>();
+ List<Folder> result = new ArrayList<Folder>();
for (Folder f : folders) {
- FolderDTO dto = f.getDTO();
- dto.setSubfolders(getSharedSubfolders(ownerId, callingUserId, f.getId()));
- result.add(dto);
+ Folder lf = f;
+ lf.setSubfolders(getSharedSubfolders(ownerId, callingUserId, f.getId()));
+ result.add(lf);
}
return result;
}
@Override
- public List<FolderDTO> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException {
+ public List<Folder> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (folderId == null)
throw new ObjectNotFoundException("No folder specified");
User user = dao.getEntityById(User.class, userId);
Folder folder = dao.getEntityById(Folder.class, folderId);
- List<FolderDTO> result = new ArrayList<FolderDTO>();
- if (folder.isShared(user))
+ List<Folder> result = new ArrayList<Folder>();
+ if (folder.isShared(user) || folder.isReadForAll())
for (Folder f : folder.getSubfolders())
- if (f.isShared(user) && !f.isDeleted())
- result.add(f.getDTO());
+ if ((f.isShared(user) || f.isReadForAll()) && !f.isDeleted())
+ result.add(f);
return result;
}
@Override
- public List<FolderDTO> getSharedSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException {
+ public List<Folder> getSharedSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (callingUserId == null)
throw new ObjectNotFoundException("No folder specified");
User user = dao.getEntityById(User.class, callingUserId);
Folder folder = dao.getEntityById(Folder.class, folderId);
- List<FolderDTO> result = new ArrayList<FolderDTO>();
+ List<Folder> result = new ArrayList<Folder>();
if (folder.isSharedForOtherUser(user))
for (Folder f : folder.getSubfolders())
if (f.isSharedForOtherUser(user) && !f.isDeleted()){
- FolderDTO dto = f.getDTO();
- dto.setSubfolders(getSharedSubfolders(userId, callingUserId, dto.getId()));
- result.add(dto);
+ Folder lf = f;
+ lf.setSubfolders(getSharedSubfolders(userId, callingUserId, lf.getId()));
+ result.add(lf);
}
return result;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#searchFiles(java.lang.Long, java.lang.String)
- */
@Override
- public List<FileHeaderDTO> searchFiles(Long userId, String query) throws ObjectNotFoundException {
+ public List<FileHeader> searchFiles(Long userId, String query) throws ObjectNotFoundException {
+ long startTime = System.currentTimeMillis();
if (userId == null)
throw new ObjectNotFoundException("No user specified");
User user = getUser(userId);
if (query == null)
throw new ObjectNotFoundException("No query specified");
List<FileHeader> files = search(user.getId(), query);
- List<FileHeaderDTO> res = new ArrayList<FileHeaderDTO>();
- for(FileHeader f : files)
- res.add(f.getDTO());
- return res;
+
+ long stopTime = System.currentTimeMillis();
+ logger.info("Total time: " + (stopTime - startTime));
+ return files;
}
/**
* Performs the actuals search on the solr server and returns the results
*
- * We have to use the dismax query type (instead of the
- * standard) because it allows for search time field boosting. This is because we can't use indexing
- * time field boosting due to the patched rich indexing API that does not allow it
- *
* @param userId
* @param query
* @return a List of FileHeader objects
*/
private List<FileHeader> search(Long userId, String query) {
+ final int maxRows = 100;
+ List<FileHeader> result = new ArrayList<FileHeader>();
try {
- HttpClient httpClient = new HttpClient();
-
- GetMethod method = new GetMethod(getConfiguration().getString("solrSelectUrl"));
- NameValuePair[] params = {new NameValuePair("qt", "dismax"),
- new NameValuePair("q", query),
- new NameValuePair("sort", "score desc"),
- new NameValuePair("indent", "on")};
- method.setQueryString(params);
- int retryCount = 0;
- int statusCode = 0;
- String response = null;
- do {
- statusCode = httpClient.executeMethod(method);
- logger.debug("HTTP status: " + statusCode);
- response = method.getResponseBodyAsString();
- logger.debug(response);
- retryCount++;
- if (statusCode != 200 && retryCount < 3)
- try {
- Thread.sleep(3000); //Give Solr a little time to be available
- } catch (InterruptedException e) {
- }
- } while (statusCode != 200 && retryCount < 3);
- if (statusCode != 200)
- throw new EJBException("Search query return error:\n" + response);
-
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- DocumentBuilder db = dbf.newDocumentBuilder();
- Document doc = db.parse(method.getResponseBodyAsStream());
- method.releaseConnection();
-
- Node root = doc.getElementsByTagName("response").item(0);
- Node lst = root.getFirstChild().getNextSibling();
- Node status = lst.getFirstChild().getNextSibling();
- if (status.getAttributes().getNamedItem("name").getNodeValue().equals("status") &&
- status.getTextContent().equals("0")) {
- List<FileHeader> fileResult = new ArrayList<FileHeader>();
- Node result = lst.getNextSibling().getNextSibling();
- NodeList docs = result.getChildNodes();
- User user = getUser(userId);
- for (int i=1; i<docs.getLength(); i=i+2) {
- Node d = docs.item(i);
- NodeList docData = d.getChildNodes();
- for (int j=1; j<docData.getLength(); j=j+2) {
- Node dd = docData.item(j);
- if (dd.getAttributes().item(0).getNodeName().equals("name") &&
- dd.getAttributes().item(0).getNodeValue().equals("id")) {
- Long fileId = Long.valueOf(dd.getTextContent());
- try {
- FileHeader file = dao.getEntityById(FileHeader.class, fileId);
- if (file.hasReadPermission(user)) {
- fileResult.add(file);
- logger.debug("File added " + fileId);
- }
- } catch (ObjectNotFoundException e) {
- logger.warn("Search result not found", e);
- }
- }
- }
+ CommonsHttpSolrServer solr = new CommonsHttpSolrServer(getConfiguration().getString("solr.url"));
+ List<Group> groups = dao.getGroupsContainingUser(userId);
+ String constructedQuery = escapeCharacters(normalizeSearchQuery(query)) + " AND (public: true OR ureaders: " + userId;
+ if (!groups.isEmpty()) {
+ constructedQuery += " OR (";
+ for (int i=0; i<groups.size(); i++) {
+ Group g = groups.get(i);
+ constructedQuery += "greaders :" + g.getId();
+ if (i < groups.size() - 1)
+ constructedQuery += " OR ";
+ }
+ constructedQuery += ")";
+ }
+ constructedQuery += ")";
+ SolrQuery solrQuery = new SolrQuery(constructedQuery);
+ solrQuery.setRows(maxRows);
+ long startTime = System.currentTimeMillis();
+ QueryResponse response = solr.query(solrQuery);
+ SolrDocumentList results = response.getResults();
+ if (results.getNumFound() > maxRows) {
+ solrQuery.setRows(Integer.valueOf((int) results.getNumFound()));
+ response = solr.query(solrQuery);
+ results = response.getResults();
+ }
+ long stopTime = System.currentTimeMillis();
+ logger.info("Search time:" + (stopTime - startTime));
+ User user = getUser(userId);
+ startTime = System.currentTimeMillis();
+ for (SolrDocument d : results) {
+ Long id = Long.valueOf((String) d.getFieldValue("id"));
+ try {
+ FileHeader f = dao.getEntityById(FileHeader.class, id);
+ result.add(f);
+ } catch (ObjectNotFoundException e) {
+ logger.warn("Search result id " + id + " cannot be found", e);
}
- return fileResult;
}
- throw new EJBException();
- } catch (HttpException e) {
- throw new EJBException(e);
- } catch (IOException e) {
- throw new EJBException(e);
- } catch (SAXException e) {
+ stopTime = System.currentTimeMillis();
+ logger.info("File loads: " + (stopTime - startTime));
+ } catch (MalformedURLException e) {
+ logger.error(e);
throw new EJBException(e);
- } catch (ParserConfigurationException e) {
+ } catch (SolrServerException e) {
+ logger.error(e);
throw new EJBException(e);
} catch (ObjectNotFoundException e) {
+ logger.error(e);
throw new EJBException(e);
}
+ return result;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#copyFiles(java.lang.Long, java.util.List, java.lang.Long)
- */
@Override
public void copyFiles(Long userId, List<Long> fileIds, Long destId) throws ObjectNotFoundException, DuplicateNameException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
for(Long l : fileIds){
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#moveFiles(java.lang.Long, java.util.List, java.lang.Long)
- */
@Override
public void moveFiles(Long userId, List<Long> fileIds, Long destId) throws InsufficientPermissionsException, ObjectNotFoundException, QuotaExceededException {
for(Long l : fileIds){
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#deleteFiles(java.lang.Long, java.util.List)
- */
- @Override
- public void deleteFiles(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
- if (userId == null)
- throw new ObjectNotFoundException("No user specified");
- final User user = dao.getEntityById(User.class, userId);
- List<String> filesToRemove = new ArrayList<String>();
- //first delete database objects
- for(Long fileId : fileIds){
- if (fileId == null)
- throw new ObjectNotFoundException("No file specified");
- final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
- final Folder parent = file.getFolder();
- if (parent == null)
- throw new ObjectNotFoundException("The specified file has no parent folder");
- if (!file.hasDeletePermission(user))
- throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
-
- parent.removeFile(file);
- for (final FileBody body : file.getBodies())
- filesToRemove.add(body.getStoredFilePath());
- dao.delete(file);
- }
- //then remove physical files if everything is ok
- for(String physicalFileName : filesToRemove)
- deleteActualFile(physicalFileName);
- //then unindex deleted files
- for(Long fileId : fileIds)
- indexFile(fileId, true);
-
- }
-
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#moveFilesToTrash(java.lang.Long, java.util.List)
- */
- @Override
- public void moveFilesToTrash(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
- for(Long l : fileIds)
- moveFileToTrash(userId, l);
-
- }
-
- @Override
- public void removeFilesFromTrash(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
- for(Long l : fileIds)
- removeFileFromTrash(userId, l);
-
- }
-
@Override
public Nonce createNonce(Long userId) throws ObjectNotFoundException {
if (userId == null)
user.setNonceExpiryDate(nonceExpiryDate);
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getUserStatistics(java.lang.Long)
- */
@Override
public StatsDTO getUserStatistics(Long userId) throws ObjectNotFoundException {
if (userId == null)
return stats;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#getVersions(java.lang.Long, java.lang.Long)
- */
- @Override
- public List<FileBodyDTO> getVersions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
- if (userId == null)
- throw new ObjectNotFoundException("No user specified");
- if (fileId == null)
- throw new ObjectNotFoundException("No file specified");
- User user = dao.getEntityById(User.class, userId);
- FileHeader header = dao.getEntityById(FileHeader.class, fileId);
- if(!header.hasReadPermission(user))
- throw new InsufficientPermissionsException("You don't have the necessary permissions");
- List<FileBodyDTO> result = new LinkedList<FileBodyDTO>();
- for(int i = header.getBodies().size()-1 ; i>=0; i--)
- result.add(header.getBodies().get(i).getDTO());
- return result;
- }
-
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#removeVersion(java.lang.Long, java.lang.Long, java.lang.Long)
- */
- @Override
- public void removeVersion(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
- if (userId == null)
- throw new ObjectNotFoundException("No user specified");
- if (fileId == null)
- throw new ObjectNotFoundException("No file specified");
- if (bodyId == null)
- throw new ObjectNotFoundException("No body specified");
- User user = dao.getEntityById(User.class, userId);
- FileHeader header = dao.getEntityById(FileHeader.class, fileId);
- if(!header.hasWritePermission(user))
- throw new InsufficientPermissionsException("You don't have the necessary permissions");
- FileBody body = dao.getEntityById(FileBody.class, bodyId);
- if(body.equals(header.getCurrentBody())){
-
- if(header.getBodies().size() == 1)
- throw new InsufficientPermissionsException("You cant delete this version, Delete file instead!");
- for(FileBody b : header.getBodies())
- if(b.getVersion() == body.getVersion()-1)
- header.setCurrentBody(b);
- }
- deleteActualFile(body.getStoredFilePath());
- header.getBodies().remove(body);
-
-
- }
-
@Override
public void restoreVersion(Long userId, Long fileId, int version) throws ObjectNotFoundException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
if (userId == null)
}
header.getCurrentBody().setVersion(1);
- }
-
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#toggleFileVersioning(java.lang.Long, java.lang.Long, boolean)
- */
- @Override
- public void toggleFileVersioning(Long userId, Long fileId, boolean versioned) throws ObjectNotFoundException, InsufficientPermissionsException {
- if (userId == null)
- throw new ObjectNotFoundException("No user specified");
- if (fileId == null)
- throw new ObjectNotFoundException("No file specified");
- User user = dao.getEntityById(User.class, userId);
- FileHeader header = dao.getEntityById(FileHeader.class, fileId);
- if(!header.hasWritePermission(user))
- throw new InsufficientPermissionsException("You don't have the necessary permissions");
- if(!header.isVersioned() == versioned){
- if(header.isVersioned())
- removeOldVersions(userId, fileId);
- header.setVersioned(versioned);
-
- }
+ Folder parent = header.getFolder();
+ touchParentFolders(parent, user, new Date());
}
/**
- * Gets the quota left for specified userId
- * @param userId
- * @return
+ * Gets the quota left for specified user ID.
*/
- private Long getQuotaLeft(Long userId){
+ private Long getQuotaLeft(Long userId) throws ObjectNotFoundException{
Long fileSize = dao.getFileSize(userId);
Long quota = getQuota(userId);
return quota - fileSize;
}
/**
- * Gets the quota for specified userId
- * @param userId
- * @return
+ * Gets the quota for specified user ID.
*/
- private Long getQuota(@SuppressWarnings("unused") Long userId){
- Long quota = getConfiguration().getLong("quota", new Long(52428800L));
- return quota;
+ private Long getQuota(Long userId) throws ObjectNotFoundException{
+ UserClass uc = getUser(userId).getUserClass();
+ if (uc == null)
+ uc = getDefaultUserClass();
+ return uc.getQuota();
}
- public void rebuildSolrIndex() {
- MessageProducer sender = null;
- Session session = null;
- Connection qConn = null;
+ @Override
+ @TransactionAttribute(TransactionAttributeType.NEVER)
+ public String rebuildSolrIndex() {
try {
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- DocumentBuilder db = dbf.newDocumentBuilder();
- Document doc = db.newDocument();
- Node root = doc.createElement("delete");
- doc.appendChild(root);
- Node queryNode = doc.createElement("query");
- root.appendChild(queryNode);
- queryNode.appendChild(doc.createTextNode("*:*"));
-
- TransformerFactory fact = TransformerFactory.newInstance();
- Transformer trans = fact.newTransformer();
- trans.setOutputProperty(OutputKeys.INDENT, "yes");
- StringWriter sw = new StringWriter();
- StreamResult sr = new StreamResult(sw);
- DOMSource source = new DOMSource(doc);
- trans.transform(source, sr);
- logger.debug(sw.toString());
-
- HttpClient httpClient = new HttpClient();
- PostMethod method = new PostMethod(getConfiguration().getString("solrUpdateUrl"));
- method.setRequestEntity(new StringRequestEntity(sw.toString()));
- int retryCount = 0;
- int statusCode = 0;
- String response = null;
- do {
- statusCode = httpClient.executeMethod(method);
- logger.debug("HTTP status: " + statusCode);
- response = method.getResponseBodyAsString();
- logger.debug(response);
- retryCount++;
- if (statusCode != 200 && retryCount < 3)
- try {
- Thread.sleep(10000); //Give Solr a little time to be available
- } catch (InterruptedException e) {
- }
- } while (statusCode != 200 && retryCount < 3);
- method.releaseConnection();
- if (statusCode != 200)
- throw new EJBException("Cannot clear Solr index. Solr response is:\n" + response);
- List<Long> fileIds = dao.getAllFileIds();
-
- Context jndiCtx = new InitialContext();
- ConnectionFactory factory = (QueueConnectionFactory) jndiCtx.lookup("java:/JmsXA");
- Queue queue = (Queue) jndiCtx.lookup("queue/gss-indexingQueue");
- qConn = factory.createConnection();
- session = qConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- sender = session.createProducer(queue);
+ CommonsHttpSolrServer solr = new CommonsHttpSolrServer(getConfiguration().getString("solr.url"));
+ solr.deleteByQuery("*:*");
+ solr.commit();
+ logger.info("Deleted everything in solr");
+ List<Long> fileIds = dao.getAllFileIds();
+ logger.info("Total of " + fileIds.size() + " will be indexed");
+ int i = 0;
for (Long id : fileIds) {
- MapMessage map = session.createMapMessage();
- map.setObject("id", id);
- map.setBoolean("delete", false);
- sender.send(map);
+ postFileToSolr(solr, id);
+ i++;
+ if (i % 10 == 0) {
+ solr.commit();
+ logger.info("Sent commit to solr at file " + i);
+ }
}
- sendOptimize(httpClient, 0);
- } catch (DOMException e) {
- throw new EJBException(e);
- } catch (TransformerConfigurationException e) {
- throw new EJBException(e);
- } catch (IllegalArgumentException e) {
- throw new EJBException(e);
- } catch (HttpException e) {
- throw new EJBException(e);
- } catch (UnsupportedEncodingException e) {
- throw new EJBException(e);
- } catch (ParserConfigurationException e) {
- throw new EJBException(e);
- } catch (TransformerException e) {
- throw new EJBException(e);
+ solr.optimize();
+ solr.commit();
+ logger.info("Finished indexing of " + i + " files");
+ return "Finished indexing of " + i + " files";
} catch (IOException e) {
throw new EJBException(e);
- } catch (NamingException e) {
- throw new EJBException(e);
- } catch (JMSException e) {
+ } catch (SolrServerException e) {
throw new EJBException(e);
}
- finally {
- try {
- if (sender != null)
- sender.close();
- if (session != null)
- session.close();
- if (qConn != null)
- qConn.close();
- }
- catch (JMSException e) {
- logger.warn(e);
- }
- }
}
- /**
- * Sends a optimize message to the solr server
- *
- * @param httpClient
- * @param retryCount If the commit fails, it is retried three times. This parameter is passed in the recursive
- * calls to stop the recursion
- * @throws UnsupportedEncodingException
- * @throws IOException
- * @throws HttpException
- */
- private void sendOptimize(HttpClient httpClient, int retryCount) throws UnsupportedEncodingException, IOException, HttpException {
- PostMethod method = null;
+ @Override
+ @TransactionAttribute(TransactionAttributeType.NEVER)
+ public String refreshSolrIndex() {
try {
- logger.debug("Optimize retry: " + retryCount);
- method = new PostMethod(getConfiguration().getString("solrUpdateUrl"));
- method.setRequestEntity(new StringRequestEntity("<optimize/>", "text/xml", "iso8859-1"));
- int statusCode = httpClient.executeMethod(method);
- logger.debug("HTTP status: " + statusCode);
- String response = method.getResponseBodyAsString();
- logger.debug(response);
- if (statusCode != 200 && retryCount < 2) {
- try {
- Thread.sleep(10000); //Give Solr a little time to be available
- } catch (InterruptedException e) {
- }
- sendOptimize(httpClient, retryCount + 1);
+ CommonsHttpSolrServer solr = new CommonsHttpSolrServer(getConfiguration().getString("solr.url"));
+
+ List<Long> fileIds = dao.getAllFileIds();
+ logger.info("Total of " + fileIds.size() + " will be indexed");
+ int i = 0;
+ for (Long id : fileIds) {
+ postFileToSolr(solr, id);
+ i++;
}
- }
- finally {
- if (method != null)
- method.releaseConnection();
+ if (i % 10 == 0) {
+ solr.commit();
+ logger.info("Sent commit to solr at file " + i);
+ }
+ solr.optimize();
+ solr.commit();
+ logger.info("Finished indexing of " + i + " files");
+ return "Finished indexing of " + i + " files";
+ } catch (IOException e) {
+ throw new EJBException(e);
+ } catch (SolrServerException e) {
+ throw new EJBException(e);
}
}
- public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, long fileSize, String filePath)
+ @Override
+ public FileHeader createFile(Long userId, Long folderId, String name, String mimeType, long fileSize, String filePath)
throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
InsufficientPermissionsException, QuotaExceededException {
// Validate.
parent.addFile(file);
// set file owner to folder owner
file.setOwner(parent.getOwner());
+ //set file's readForAll value according to parent folder readForAll value
+ file.setReadForAll(parent.isReadForAll());
final Date now = new Date();
final AuditInfo auditInfo = new AuditInfo();
} catch (FileNotFoundException e) {
throw new GSSIOException(e);
}
+ touchParentFolders(parent, owner, new Date());
dao.flush();
indexFile(file.getId(), false);
- return file.getDTO();
+ return file;
}
- /* (non-Javadoc)
- * @see gr.ebs.gss.server.ejb.ExternalAPI#updateFileContents(java.lang.Long, java.lang.Long, java.lang.String, java.io.InputStream)
- */
- public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, long fileSize, String filePath) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
+ @Override
+ public FileHeader updateFileContents(Long userId, Long fileId, String mimeType, long fileSize, String filePath) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (fileId == null)
} catch (FileNotFoundException e) {
throw new GSSIOException(e);
}
+ Folder parent = file.getFolder();
+ touchParentFolders(parent, owner, new Date());
indexFile(fileId, false);
- return file.getDTO();
+ return file;
}
/**
* @param filePath the uploaded file full path
* @param header the file header that will be associated with the new body
* @param auditInfo the audit info
- * @param owner the owner of the file
* @throws FileNotFoundException
* @throws QuotaExceededException
+ * @throws ObjectNotFoundException if the owner was not found
*/
private void createFileBody(String name, String mimeType, long fileSize, String filePath,
FileHeader header, AuditInfo auditInfo)
- throws FileNotFoundException, QuotaExceededException {
+ throws FileNotFoundException, QuotaExceededException, ObjectNotFoundException {
long currentTotalSize = 0;
if (!header.isVersioned() && header.getCurrentBody() != null && header.getBodies() != null)
dao.flush();
header.addBody(body);
+ header.setAuditInfo(auditInfo);
dao.create(body);
}
+ @Override
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public File uploadFile(InputStream stream, Long userId) throws IOException, ObjectNotFoundException {
if (userId == null)
}
+ @Override
public void createFileUploadProgress(Long userId, String filename, Long bytesTransfered, Long fileSize) throws ObjectNotFoundException{
if (userId == null)
}
+ @Override
public void removeFileUploadProgress(Long userId, String filename) throws ObjectNotFoundException{
if (userId == null)
throw new ObjectNotFoundException("No user specified");
}
@Override
- public FolderDTO getFolderWithSubfolders(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
- if (userId == null)
- throw new ObjectNotFoundException("No user specified");
- if (folderId == null)
- throw new ObjectNotFoundException("No folder specified");
- final User user = dao.getEntityById(User.class, userId);
- final Folder folder = dao.getEntityById(Folder.class, folderId);
- // Check permissions
- if (!folder.hasReadPermission(user))
- throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
- List<FolderDTO> subfolders = new ArrayList<FolderDTO>();
- if (folder.hasReadPermission(user))
- for (Folder f : folder.getSubfolders())
- if (f.hasReadPermission(user) && !f.isDeleted())
- subfolders.add(f.getDTO());
- FolderDTO result = folder.getDTO();
- result.setSubfolders(subfolders);
- return folder.getDTO();
- }
-
- @Override
- public FolderDTO getFolderWithSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
- if (userId == null)
- throw new ObjectNotFoundException("No user specified");
- if (folderId == null)
- throw new ObjectNotFoundException("No folder specified");
- User user = dao.getEntityById(User.class, callingUserId);
- Folder folder = dao.getEntityById(Folder.class, folderId);
- // Check permissions
- if (!folder.hasReadPermission(user))
- throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
-
- FolderDTO result = folder.getDTO();
- result.setSubfolders(getSharedSubfolders(userId, callingUserId, folder.getId()));
- return result;
- }
-
- @Override
- public FileBodyDTO getFileVersion(Long userId, Long fileId, int version)
+ public FileBody getFileVersion(Long userId, Long fileId, int version)
throws ObjectNotFoundException, InsufficientPermissionsException {
if (userId == null)
throw new ObjectNotFoundException("No user specified");
if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
throw new InsufficientPermissionsException("You don't have the necessary permissions");
FileBody body = dao.getFileVersion(fileId, version);
- return body.getDTO();
+ return body;
}
@Override
return true;
}
- /**
- * Reset WebDAV password for given user.
- *
- * @param userId
- * @return the new password
- * @throws ObjectNotFoundException
- */
@Override
public String resetWebDAVPassword(Long userId) throws ObjectNotFoundException {
if (userId == null)
return user.getWebDAVPassword();
}
+ @Override
+ public Invitation findInvite(String code) {
+ if (code == null)
+ return null;
+ return dao.findInvite(code);
+ }
+
+ @Override
+ public void createLdapUser(String username, String firstname, String lastname, String email, String password) {
+ LDAPConnection lc = new LDAPConnection();
+ LDAPAttributeSet attributeSet = new LDAPAttributeSet();
+ attributeSet.add(new LDAPAttribute("objectClass", getConfiguration().getStringArray("objectClass")));
+ attributeSet.add(new LDAPAttribute("uid", username));
+ attributeSet.add(new LDAPAttribute("cn", new String[]{firstname + " " + lastname}));
+ attributeSet.add(new LDAPAttribute("sn", lastname));
+ attributeSet.add(new LDAPAttribute("givenName", firstname));
+ attributeSet.add(new LDAPAttribute("mail", email));
+ attributeSet.add(new LDAPAttribute("userPassword", password));
+ String dn = "uid=" + username + "," + getConfiguration().getString("baseDn");
+ LDAPEntry newEntry = new LDAPEntry(dn, attributeSet);
+ try {
+ lc.connect(getConfiguration().getString("ldapHost"), LDAPConnection.DEFAULT_PORT);
+ lc.bind(LDAPConnection.LDAP_V3, getConfiguration().getString("bindDn"),
+ getConfiguration().getString("bindPassword").getBytes("UTF8"));
+ lc.add(newEntry);
+ logger.info("Successfully added LDAP account: " + dn);
+ lc.disconnect();
+ } catch(LDAPException e) {
+ throw new RuntimeException(e);
+ } catch(UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ @Override
+ public UserClass upgradeUserClass(String username, String code) throws ObjectNotFoundException, InvitationUsedException {
+ User user = findUser(username);
+ if (user == null)
+ throw new ObjectNotFoundException("The user was not found");
+ Invitation invite = findInvite(code);
+ if (invite.getUser() != null)
+ throw new InvitationUsedException("This code has already been used");
+ invite.setUser(user);
+ UserClass couponClass = getCouponUserClass();
+ user.setUserClass(couponClass);
+ return couponClass;
+ }
+
+ @Override
+ public UserClass getCouponUserClass() {
+ return dao.findCouponUserClass();
+ }
+
+ /**
+ * Set the provided readForAll as the new readforAll value of the specified
+ * folder and sub-folders.
+ *
+ * @param user
+ * @param folder
+ * @param readForAll
+ * @throws ObjectNotFoundException
+ *
+ */
+ private void setFolderReadForAll(User user, Folder folder, Boolean readForAll){
+ if (readForAll != null && user.equals(folder.getOwner())){
+ folder.setReadForAll(readForAll);
+ dao.update(folder);
+ for (FileHeader file : folder.getFiles())
+ file.setReadForAll(readForAll);
+ if(readForAll)
+ //only update subfolders when readforall is true. otherwise all sub-folders stay untouched
+ for (Folder sub : folder.getSubfolders())
+ setFolderReadForAll(user, sub, readForAll);
+
+ }
+
+ }
+
+ /**
+ * Update the userLogin with the values from the supplied object.
+ */
+
+ public void addUserLogin(UserLogin userLogin) {
+ dao.update(userLogin);
+
+ }
+
+ /**
+ * Retrieves the current session user login and the user's last login
+ *
+ * @param userId
+ * @return a list of last two user logins
+ * @throws ObjectNotFoundException
+ */
+
+ public List<UserLogin> getLastUserLogins(Long userId) throws ObjectNotFoundException{
+ List<UserLogin> userLoginResults = new ArrayList<UserLogin>();
+ userLoginResults = dao.getLoginsForUser(userId);
+ if(userLoginResults.size() == 0)
+ throw new ObjectNotFoundException("No userlogin found for the user");
+ //if the user logins for the first time lastLoginDate = currentLoginDate
+ if(userLoginResults.size()==1)
+ userLoginResults.add(userLoginResults.get(0));
+ return userLoginResults;
+ }
+
+
+ @Override
+ public void postFileToSolr(CommonsHttpSolrServer solr, Long id) {
+ try {
+ FileHeader file = dao.getFileForIndexing(id);
+ FileBody body = file.getCurrentBody();
+ String mime = body.getMimeType();
+ boolean multipart = true;
+ if (!mime.equals("application/pdf")
+ && !mime.equals("text/plain")
+ && !mime.equals("text/html")
+ && !mime.endsWith("msword")
+ && !mime.endsWith("ms-excel")
+ && !mime.endsWith("powerpoint")
+ || (body.getFileSize() > getConfiguration().getLong("solrDocumentUploadLimitInKB") * 1024))
+ multipart = false;
+
+ if (!multipart)
+ sendMetaDataOnly(solr, file);
+ else {
+ ContentStreamUpdateRequest solrRequest = new ContentStreamUpdateRequest(getConfiguration().getString("solr.rich.update.path"));
+ solrRequest.setParam("literal.id", file.getId().toString());
+ solrRequest.setParam("literal.name", file.getName());
+ for (FileTag t : file.getFileTags()) {
+ solrRequest.getParams().add("literal.tag", t.getTag());
+ }
+ for (Permission p : file.getPermissions()) {
+ if (p.getRead()) {
+ if (p.getUser() != null)
+ solrRequest.setParam("literal.ureaders", p.getUser().getId().toString());
+ else if (p.getGroup() != null)
+ solrRequest.setParam("literal.greaders", p.getGroup().getId().toString());
+ }
+ }
+ solrRequest.setParam("literal.owner", file.getOwner().getId().toString());
+ solrRequest.setParam("literal.public", String.valueOf(file.isReadForAll()));
+ File fsFile = new File(body.getStoredFilePath());
+ solrRequest.addFile(fsFile);
+ try {
+ solr.request(solrRequest);
+ }
+ catch (SolrException e) {
+ logger.warn("File " + id + " failed with SolrException: " + e.getLocalizedMessage() + ". Retrying without the file");
+ //Let 's try without the file
+ sendMetaDataOnly(solr, file);
+ }
+ catch (NullPointerException e) {
+ logger.warn("File " + id + " failed with NullPointerException: " + e.getLocalizedMessage() + ". Retrying without the file");
+ //Let 's try without the file
+ sendMetaDataOnly(solr, file);
+ }
+ catch (SolrServerException e) {
+ logger.warn("File " + id + " failed with SolrServerException: " + e.getLocalizedMessage() + ". Retrying without the file");
+ //Let 's try without the file
+ sendMetaDataOnly(solr, file);
+ }
+ }
+ } catch (MalformedURLException e) {
+ throw new EJBException(e);
+ } catch (ObjectNotFoundException e) {
+ logger.error("Indexing of file id " + id + " failed.", e);
+ } catch (SolrServerException e) {
+ throw new EJBException(e);
+ } catch (IOException e) {
+ throw new EJBException(e);
+ }
+ }
+
+ private void sendMetaDataOnly(CommonsHttpSolrServer solr, FileHeader file) throws SolrServerException, IOException {
+ SolrInputDocument solrDoc = new SolrInputDocument();
+ solrDoc.addField("id", file.getId().toString());
+ solrDoc.addField("name", file.getName());
+ for (FileTag t : file.getFileTags()) {
+ solrDoc.addField("tag", t.getTag());
+ }
+ for (Permission p : file.getPermissions()) {
+ if (p.getRead()) {
+ if (p.getUser() != null)
+ solrDoc.addField("ureaders", p.getUser().getId());
+ else if (p.getGroup() != null)
+ solrDoc.addField("greaders", p.getGroup().getId());
+ }
+ }
+ solrDoc.addField("owner", file.getOwner().getId());
+ solrDoc.addField("public", file.isReadForAll());
+ solr.add(solrDoc);
+ }
+
+ private String tokenizeFilename(String filename){
+ StringBuffer result = new StringBuffer();
+ StringTokenizer tokenizer = new StringTokenizer(filename,"._");
+ while(tokenizer.hasMoreTokens()){
+ result.append(tokenizer.nextToken());
+ result.append(" ");
+ }
+ result.append(filename);
+ return result.toString();
+ }
+
+ private String normalizeSearchQuery(String query) {
+ if (query.contains("*"))
+ return query.toLowerCase().replace('ά', 'α').replace('έ', 'ε').replace('ί', 'ι').replace('ή', 'η').replace('ύ', 'υ')
+ .replace('ό', 'ο').replace('ς', 'σ').replace('ώ', 'ω').replace('ϊ', 'ι').replace('ϋ', 'υ');
+ else
+ return query;
+ }
+
+ private String escapeCharacters(String text) {
+ return text.replaceAll(":", "\\\\:");
+ }
+
+ /*** NEW METHODS IN ORDER TO AVOID LAZY loading exception in json render
+ ****/
+ @Override
+ public Folder expandFolder(Folder folder) throws ObjectNotFoundException{
+ Folder result = dao.getEntityById(Folder.class, folder.getId());
+ result.getSubfolders().size();
+ result.getFiles().size();
+ result.getPermissions().size();
+ return result;
+}
+
+ @Override
+ public FileHeader expandFile(FileHeader folder) throws ObjectNotFoundException{
+ FileHeader result = dao.getEntityById(FileHeader.class, folder.getId());
+ result.getFolder();
+ result.getPermissions().size();
+ result.getFileTags().size();
+ return result;
+ }
+
+ @Override
+ public Group expandGroup(Group folder) throws ObjectNotFoundException{
+ Group result = dao.getEntityById(Group.class, folder.getId());
+ result.getMembers().size();
+ return result;
+ }
}