2 * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.
4 * This file is part of GSS.
6 * GSS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GSS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GSS. If not, see <http://www.gnu.org/licenses/>.
19 package gr.ebs.gss.server.ejb;
21 import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
22 import gr.ebs.gss.client.exceptions.DuplicateNameException;
23 import gr.ebs.gss.client.exceptions.GSSIOException;
24 import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
25 import gr.ebs.gss.client.exceptions.InvitationUsedException;
26 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
27 import gr.ebs.gss.client.exceptions.QuotaExceededException;
28 import gr.ebs.gss.server.domain.AuditInfo;
29 import gr.ebs.gss.server.domain.FileBody;
30 import gr.ebs.gss.server.domain.FileHeader;
31 import gr.ebs.gss.server.domain.FileTag;
32 import gr.ebs.gss.server.domain.FileUploadStatus;
33 import gr.ebs.gss.server.domain.Folder;
34 import gr.ebs.gss.server.domain.Group;
35 import gr.ebs.gss.server.domain.Invitation;
36 import gr.ebs.gss.server.domain.Nonce;
37 import gr.ebs.gss.server.domain.Permission;
38 import gr.ebs.gss.server.domain.User;
39 import gr.ebs.gss.server.domain.UserClass;
40 import gr.ebs.gss.server.domain.UserLogin;
41 import gr.ebs.gss.server.domain.dto.FileBodyDTO;
42 import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
43 import gr.ebs.gss.server.domain.dto.FolderDTO;
44 import gr.ebs.gss.server.domain.dto.GroupDTO;
45 import gr.ebs.gss.server.domain.dto.PermissionDTO;
46 import gr.ebs.gss.server.domain.dto.StatsDTO;
47 import gr.ebs.gss.server.domain.dto.UserDTO;
50 import java.io.FileInputStream;
51 import java.io.FileNotFoundException;
52 import java.io.FileOutputStream;
53 import java.io.IOException;
54 import java.io.InputStream;
55 import java.io.UnsupportedEncodingException;
56 import java.net.MalformedURLException;
57 import java.util.ArrayList;
58 import java.util.Date;
59 import java.util.Iterator;
60 import java.util.LinkedHashSet;
61 import java.util.LinkedList;
62 import java.util.List;
63 import java.util.Locale;
64 import java.util.Random;
66 import java.util.StringTokenizer;
69 import javax.ejb.EJBException;
70 import javax.ejb.EJBTransactionRolledbackException;
71 import javax.ejb.Stateless;
72 import javax.ejb.TransactionAttribute;
73 import javax.ejb.TransactionAttributeType;
74 import javax.jms.Connection;
75 import javax.jms.ConnectionFactory;
76 import javax.jms.JMSException;
77 import javax.jms.MapMessage;
78 import javax.jms.MessageProducer;
79 import javax.jms.Queue;
80 import javax.jms.QueueConnectionFactory;
81 import javax.jms.Session;
82 import javax.naming.Context;
83 import javax.naming.InitialContext;
84 import javax.naming.NamingException;
85 import javax.persistence.PersistenceException;
87 import org.apache.commons.lang.StringUtils;
88 import org.apache.commons.logging.Log;
89 import org.apache.commons.logging.LogFactory;
90 import org.apache.solr.client.solrj.SolrQuery;
91 import org.apache.solr.client.solrj.SolrServerException;
92 import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
93 import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;
94 import org.apache.solr.client.solrj.response.QueryResponse;
95 import org.apache.solr.common.SolrDocument;
96 import org.apache.solr.common.SolrDocumentList;
97 import org.apache.solr.common.SolrException;
98 import org.apache.solr.common.SolrInputDocument;
99 import org.hibernate.exception.ConstraintViolationException;
101 import com.novell.ldap.LDAPAttribute;
102 import com.novell.ldap.LDAPAttributeSet;
103 import com.novell.ldap.LDAPConnection;
104 import com.novell.ldap.LDAPEntry;
105 import com.novell.ldap.LDAPException;
108 * The concrete implementation of the ExternalAPI interface.
113 public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
115 * The default MIME type for files without an explicit one.
117 private static final String DEFAULT_MIME_TYPE = "application/octet-stream";
120 * The size of the buffer that is used to temporarily store chunks of
121 * uploaded files, while storing them to the file repository.
123 private static final int UPLOAD_BUFFER_SIZE = 1024 * 4;
128 private static Log logger = LogFactory.getLog(ExternalAPIBean.class);
131 * Injected reference to the GSSDAO data access facade.
138 * A cached random number generator for creating unique filenames.
140 private static Random random = new Random();
143 * Mark the folder and all of its parent folders as modified from the specified user.
145 private void touchParentFolders(Folder folder, User user, Date date) {
148 AuditInfo ai = f.getAuditInfo();
149 ai.setModifiedBy(user);
150 ai.setModificationDate(date);
157 public FolderDTO getRootFolder(Long userId) throws ObjectNotFoundException {
159 throw new ObjectNotFoundException("No user specified");
160 Folder folder = dao.getRootFolder(userId);
161 return folder.getDTO();
165 public FolderDTO getFolder(final Long userId, final Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
167 throw new ObjectNotFoundException("No user specified");
168 if (folderId == null)
169 throw new ObjectNotFoundException("No folder specified");
170 final User user = dao.getEntityById(User.class, userId);
171 final Folder folder = dao.getEntityById(Folder.class, folderId);
173 if (!folder.hasReadPermission(user))
174 throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
175 return folder.getDTO();
179 public User getUser(Long userId) throws ObjectNotFoundException {
181 throw new ObjectNotFoundException("No user specified");
182 return dao.getEntityById(User.class, userId);
186 public UserDTO getUserDTO(final Long userId) throws ObjectNotFoundException {
187 return getUser(userId).getDTO();
191 public GroupDTO getGroup(final Long groupId) throws ObjectNotFoundException {
193 throw new ObjectNotFoundException("No group specified");
194 final Group group = dao.getEntityById(Group.class, groupId);
195 return group.getDTO();
199 public GroupDTO getGroup(Long userId, String name) throws ObjectNotFoundException {
201 throw new ObjectNotFoundException("No user specified");
203 throw new ObjectNotFoundException("No group specified");
204 User user = dao.getEntityById(User.class, userId);
205 List<Group> groups = user.getGroupsSpecified();
206 for (Group group: groups)
207 if (group.getName().equals(name))
208 return group.getDTO();
209 throw new ObjectNotFoundException("Group " + name + " not found");
213 public List<GroupDTO> getGroups(final Long userId) throws ObjectNotFoundException {
215 throw new ObjectNotFoundException("No user specified");
216 final List<Group> groups = dao.getGroups(userId);
217 final List<GroupDTO> result = new ArrayList<GroupDTO>();
218 for (final Group g : groups)
219 result.add(g.getDTO());
224 public List<FileHeaderDTO> getFiles(Long userId, Long folderId, boolean ignoreDeleted)
225 throws ObjectNotFoundException, InsufficientPermissionsException {
228 throw new ObjectNotFoundException("No user specified");
229 if (folderId == null)
230 throw new ObjectNotFoundException("No folder specified");
231 User user = dao.getEntityById(User.class, userId);
232 Folder folder = dao.getEntityById(Folder.class, folderId);
233 if (!folder.hasReadPermission(user))
234 throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
235 // Do the actual work.
236 List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
237 List<FileHeader> files = dao.getFiles(folderId, userId, ignoreDeleted);
238 for (FileHeader f : files)
239 result.add(f.getDTO());
244 public List<UserDTO> getUsers(final Long userId, final Long groupId) throws ObjectNotFoundException {
247 throw new ObjectNotFoundException("No user specified");
249 throw new ObjectNotFoundException("No group specified");
251 // Do the actual work.
252 final List<User> users = dao.getUsers(groupId);
253 final List<UserDTO> result = new ArrayList<UserDTO>();
254 for (final User u : users)
255 result.add(u.getDTO());
260 public FolderDTO createFolder(Long userId, Long parentId, String name)
261 throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException {
264 throw new ObjectNotFoundException("No user specified");
265 if (StringUtils.isEmpty(name))
266 throw new ObjectNotFoundException("New folder name is empty");
267 if (parentId == null)
268 throw new ObjectNotFoundException("No parent specified");
269 if (dao.existsFolderOrFile(parentId, name))
270 throw new DuplicateNameException("A folder or file with the name '" +
271 name + "' already exists at this level");
273 User creator = dao.getEntityById(User.class, userId);
275 Folder parent = null;
277 parent = dao.getEntityById(Folder.class, parentId);
278 } catch (ObjectNotFoundException onfe) {
279 // Supply a more accurate problem description.
280 throw new ObjectNotFoundException("Parent folder not found");
282 if (!parent.hasWritePermission(creator))
283 throw new InsufficientPermissionsException("You don't have the permissions" +
284 " to write to this folder");
286 // Do the actual work.
287 return createFolder(name, parent, creator);
291 * Create a new folder with the provided name, parent and owner.
296 * @return the new folder
298 private FolderDTO createFolder(String name, Folder parent, User creator) {
299 Folder folder = new Folder();
300 folder.setName(name);
301 if (parent != null) {
302 parent.addSubfolder(folder);
303 folder.setOwner(parent.getOwner());
305 folder.setOwner(creator);
307 Date now = new Date();
308 AuditInfo auditInfo = new AuditInfo();
309 auditInfo.setCreatedBy(creator);
310 auditInfo.setCreationDate(now);
311 auditInfo.setModifiedBy(creator);
312 auditInfo.setModificationDate(now);
313 folder.setAuditInfo(auditInfo);
314 touchParentFolders(folder, auditInfo.getModifiedBy(), auditInfo.getModificationDate());
317 for (Permission p : parent.getPermissions()) {
318 Permission permission = new Permission();
319 permission.setGroup(p.getGroup());
320 permission.setUser(p.getUser());
321 permission.setRead(p.getRead());
322 permission.setWrite(p.getWrite());
323 permission.setModifyACL(p.getModifyACL());
324 folder.addPermission(permission);
327 Permission permission = new Permission();
328 permission.setUser(creator);
329 permission.setRead(true);
330 permission.setWrite(true);
331 permission.setModifyACL(true);
332 folder.addPermission(permission);
336 folder.setReadForAll(parent.isReadForAll());
339 return folder.getDTO();
343 public void deleteFolder(final Long userId, final Long folderId) throws InsufficientPermissionsException, ObjectNotFoundException {
346 throw new ObjectNotFoundException("No user specified");
347 if (folderId == null)
348 throw new ObjectNotFoundException("No folder specified");
350 // Do the actual work.
351 final Folder folder = dao.getEntityById(Folder.class, folderId);
352 final Folder parent = folder.getParent();
354 throw new ObjectNotFoundException("Deleting the root folder is not allowed");
355 final User user = dao.getEntityById(User.class, userId);
356 if (!folder.hasDeletePermission(user)) {
357 logger.info("User " + user.getId() + " cannot delete folder " + folder.getName() + "(" + folder.getId() + ")");
358 throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete folder " + folder.getName() + "(" + folder.getId() + ")");
360 removeSubfolderFiles(folder);
361 parent.removeSubfolder(folder);
363 touchParentFolders(parent, user, new Date());
367 * Traverses the folder and deletes all actual files (file system)
368 * regardless of permissions
372 private void removeSubfolderFiles(Folder folder) {
373 //remove files for all subfolders
374 for (Folder subfolder:folder.getSubfolders())
375 removeSubfolderFiles(subfolder);
376 //remove this folder's file bodies (actual files)
377 for (FileHeader file:folder.getFiles()) {
378 for (FileBody body:file.getBodies())
379 deleteActualFile(body.getStoredFilePath());
380 indexFile(file.getId(), true);
385 @SuppressWarnings("unchecked")
386 public List<FolderDTO> getSubfolders(Long userId, Long folderId)
387 throws ObjectNotFoundException, InsufficientPermissionsException {
389 throw new ObjectNotFoundException("No user specified");
390 if (folderId == null)
391 throw new ObjectNotFoundException("No folder specified");
392 User user = dao.getEntityById(User.class, userId);
393 Folder folder = dao.getEntityById(Folder.class, folderId);
394 if (!folder.hasReadPermission(user))
395 throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
396 List<FolderDTO> result = new ArrayList<FolderDTO>();
397 if (folder.hasReadPermission(user))
398 for (Folder f : folder.getSubfolders())
399 if (f.hasReadPermission(user) && !f.isDeleted())
400 result.add(f.getDTO());
405 public FolderDTO updateFolder(Long userId, Long folderId, String folderName,
407 Set<PermissionDTO> permissions)
408 throws InsufficientPermissionsException, ObjectNotFoundException,
409 DuplicateNameException {
413 throw new ObjectNotFoundException("No user specified");
414 if (folderId == null)
415 throw new ObjectNotFoundException("No folder specified");
417 Folder folder = dao.getEntityById(Folder.class, folderId);
418 User user = dao.getEntityById(User.class, userId);
419 if (folderName != null && !folder.hasWritePermission(user))
420 throw new InsufficientPermissionsException("You don't have the necessary permissions");
421 if(permissions != null && !permissions.isEmpty() && !folder.hasModifyACLPermission(user))
422 throw new InsufficientPermissionsException("You don't have the necessary permissions");
423 // Check permissions for making file public.
424 if (readForAll != null && !user.equals(folder.getOwner()))
425 throw new InsufficientPermissionsException("Only the owner can make a folder public or not public");
427 Folder parent = folder.getParent();
428 if (folderName != null) {
430 if (!folder.getName().equals(folderName) && dao.existsFolderOrFile(parent.getId(), folderName))
431 throw new DuplicateNameException("A folder or file with the name '" + folderName + "' already exists at this level");
433 // Do the actual modification.
434 folder.setName(folderName);
436 if (permissions != null)
437 setFolderPermissions(user, folder, permissions);
438 if (readForAll != null)
439 setFolderReadForAll(user, folder, readForAll);
440 folder.getAuditInfo().setModificationDate(new Date());
441 folder.getAuditInfo().setModifiedBy(user);
443 touchParentFolders(folder, user, new Date());
444 return folder.getDTO();
448 public void createGroup(final Long userId, final String name) throws ObjectNotFoundException, DuplicateNameException {
451 throw new ObjectNotFoundException("No user specified");
452 if (StringUtils.isEmpty(name))
453 throw new ObjectNotFoundException("New group name is empty");
454 if (name.indexOf('/')>=0)
455 throw new IllegalArgumentException("Character '/' is not allowed in group name");
456 if (dao.existsGroup(userId, name))
457 throw new DuplicateNameException("A group with the name '" + name + "' already exists");
459 // TODO: Check permissions
461 final User owner = dao.getEntityById(User.class, userId);
463 // Do the actual work.
464 owner.createGroup(name);
468 public void deleteGroup(final Long userId, final Long groupId) throws ObjectNotFoundException, InsufficientPermissionsException {
471 throw new ObjectNotFoundException("No user specified");
473 throw new ObjectNotFoundException("No group specified");
475 // Do the actual work.
476 final User owner = dao.getEntityById(User.class, userId);
477 final Group group = dao.getEntityById(Group.class, groupId);
478 final Date now = new Date();
479 // Only delete the group if actually owned by the user.
480 if (group.getOwner().equals(owner)) {
481 List<Folder> folders = dao.getFoldersPermittedForGroup(userId, groupId);
482 for (Folder f : folders){
483 f.getPermissions().removeAll(group.getPermissions());
484 touchFolder(f, owner, now);
485 for(FileHeader file : f.getFiles()){
486 file.getPermissions().removeAll(group.getPermissions());
487 touchFile(file, owner, now);
490 List<FileHeader> files = dao.getFilesPermittedForGroup(userId, groupId);
491 for(FileHeader h : files){
492 h.getPermissions().removeAll(group.getPermissions());
493 touchFile(h, owner, now);
495 owner.removeSpecifiedGroup(group);
498 else throw new InsufficientPermissionsException("You are not the owner of this group");
502 public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
503 throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
504 InsufficientPermissionsException, QuotaExceededException {
507 file = uploadFile(stream, userId);
508 } catch ( IOException ioe) {
509 // Supply a more accurate problem description.
510 throw new GSSIOException("Problem creating file",ioe);
512 return createFile(userId, folderId, name, mimeType, file.length(), file.getAbsolutePath());
516 * @see gr.ebs.gss.server.ejb.ExternalAPIRemote#indexFile(java.lang.Long, boolean)
519 public void indexFile(Long fileId, boolean delete) {
520 Connection qConn = null;
521 Session session = null;
522 MessageProducer sender = null;
524 Context jndiCtx = new InitialContext();
525 ConnectionFactory factory = (QueueConnectionFactory) jndiCtx.lookup("java:/JmsXA");
526 Queue queue = (Queue) jndiCtx.lookup("queue/gss-indexingQueue");
527 qConn = factory.createConnection();
528 session = qConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
529 sender = session.createProducer(queue);
531 MapMessage map = session.createMapMessage();
532 map.setObject("id", fileId);
533 map.setBoolean("delete", delete);
536 catch (NamingException e) {
537 logger.error("Index was not updated: ", e);
539 catch (JMSException e) {
540 logger.error("Index was not updated: ", e);
551 catch (JMSException e) {
560 * A helper method that generates a unique file path for a stored file. The
561 * files are stored using random hash names that are distributed evenly in
562 * a 2-level tree of subdirectories named after the first two hex characters
563 * in the name. For example, file ab1234cd5769f will be stored in the path
564 * /file-repository-root/a/b/ab1234cd5769f. The directories will be created
565 * if they don't already exist.
567 * @return a unique new file path
569 private String generateRepositoryFilePath() {
570 String filename = Long.toHexString(random.nextLong());
571 String fileRepositoryPath = getConfiguration().getString("fileRepositoryPath","/tmp");
572 File root = new File(fileRepositoryPath);
575 File firstFolder = new File(root + File.separator + filename.substring(0, 1));
576 if (!firstFolder.exists())
578 File secondFolder = new File(firstFolder + File.separator + filename.substring(1, 2));
579 if (!secondFolder.exists())
580 secondFolder.mkdir();
581 return secondFolder + File.separator + filename;
585 public void deleteFile(final Long userId, final Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
588 throw new ObjectNotFoundException("No user specified");
590 throw new ObjectNotFoundException("No file specified");
592 // Do the actual work.
593 final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
594 final Folder parent = file.getFolder();
596 throw new ObjectNotFoundException("The specified file has no parent folder");
597 final User user = dao.getEntityById(User.class, userId);
598 if (!file.hasDeletePermission(user))
599 throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
600 for (final FileBody body : file.getBodies())
601 deleteActualFile(body.getStoredFilePath());
603 touchParentFolders(parent, user, new Date());
604 indexFile(fileId, true);
608 public void deleteActualFile(String path) {
611 File file = new File(path);
613 logger.error("Could not delete file " + path);
617 public void createTag(final Long userId, final Long fileHeaderId, final String tag) throws ObjectNotFoundException {
619 throw new ObjectNotFoundException("No user specified");
620 if (fileHeaderId == null)
621 throw new ObjectNotFoundException("No file specified");
622 if (StringUtils.isEmpty(tag))
623 throw new ObjectNotFoundException("Tag is empty");
625 final User user = dao.getEntityById(User.class, userId);
626 final FileHeader fh = dao.getEntityById(FileHeader.class, fileHeaderId);
627 final Folder parent = fh.getFolder();
629 throw new ObjectNotFoundException("The specified file has no parent folder");
630 user.addTag(fh, tag);
631 touchParentFolders(parent, user, new Date());
635 public Set<String> getUserTags(final Long userId) throws ObjectNotFoundException {
636 return dao.getUserTags(userId);
640 public void updateFile(Long userId, Long fileId, String name,
641 String tagSet, Date modificationDate, Boolean versioned,
642 Boolean readForAll, Set<PermissionDTO> permissions)
643 throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException {
645 throw new ObjectNotFoundException("No user specified");
647 throw new ObjectNotFoundException("No file specified");
648 FileHeader file = dao.getEntityById(FileHeader.class, fileId);
649 final Folder parent = file.getFolder();
651 throw new ObjectNotFoundException("The specified file has no parent folder");
653 User user = dao.getEntityById(User.class, userId);
654 // Check permissions for modifying the file metadata.
655 if ((name != null || tagSet != null || modificationDate != null || versioned != null) && !file.hasWritePermission(user))
656 throw new InsufficientPermissionsException("User " + user.getId() + " cannot update file " + file.getName() + "(" + file.getId() + ")");
657 // Check permissions for making file public.
658 if (readForAll != null && !user.equals(file.getOwner()))
659 throw new InsufficientPermissionsException("Only the owner can make a file public or not public");
660 // Check permissions for modifying the ACL.
661 if(permissions != null && !permissions.isEmpty() && !file.hasModifyACLPermission(user))
662 throw new InsufficientPermissionsException("User " + user.getId() + " cannot update the permissions on file " + file.getName() + "(" + file.getId() + ")");
665 // Do plain check for file already exists.
666 // Extreme concurrency case should be caught by constraint violation later.
667 if (dao.existsFolderOrFile(parent.getId(), name)) throw new DuplicateNameException("A file or folder with the name '" + name + "' already exists");
671 if (modificationDate != null)
672 file.getAuditInfo().setModificationDate(modificationDate);
674 file.getAuditInfo().setModificationDate(new Date());
675 file.getAuditInfo().setModifiedBy(user);
677 List<FileTag> tags = file.getFileTags();
678 if (tagSet != null) {
679 Iterator<FileTag> i = tags.iterator();
680 while (i.hasNext()) {
681 FileTag tag = i.next();
688 StringTokenizer st = new StringTokenizer(tagSet, ",");
689 while (st.hasMoreTokens())
690 new FileTag(user, file, st.nextToken().trim());
692 if (versioned != null && !file.isVersioned() == versioned) {
693 if (file.isVersioned())
694 removeOldVersions(userId, fileId);
695 file.setVersioned(versioned);
697 if (readForAll != null && user.equals(file.getOwner()))
698 file.setReadForAll(readForAll);
699 if (permissions != null && !permissions.isEmpty())
700 setFilePermissions(file, permissions);
703 * Force constraint violation to manifest itself here.
704 * This should cover extreme concurrency cases that the simple check
705 * above hasn't caught.
710 catch (EJBTransactionRolledbackException e) {
711 Throwable cause = e.getCause();
712 if (cause instanceof PersistenceException && cause.getCause() instanceof ConstraintViolationException)
713 throw new DuplicateNameException("A file or folder with the name '" + name + "' already exists");
717 touchParentFolders(parent, user, new Date());
719 // Re-index the file if it was modified.
720 if (name != null || tagSet != null || (permissions != null && !permissions.isEmpty()) || readForAll != null)
721 indexFile(fileId, false);
725 public InputStream getFileContents(Long userId, Long fileId)
726 throws ObjectNotFoundException, InsufficientPermissionsException {
728 throw new ObjectNotFoundException("No user specified");
730 throw new ObjectNotFoundException("No file specified");
732 FileHeader header = dao.getEntityById(FileHeader.class, fileId);
733 User user = dao.getEntityById(User.class, userId);
734 if (!header.hasReadPermission(user)) {
735 logger.info("User " + user.getId() + " cannot read file " + header.getName() + "(" + fileId + ")");
736 throw new InsufficientPermissionsException("You don't have the necessary permissions");
739 File f = new File(header.getCurrentBody().getStoredFilePath());
741 return new FileInputStream(f);
742 } catch (FileNotFoundException e) {
743 logger.error("Could not locate the contents of file " + f.getAbsolutePath());
744 throw new ObjectNotFoundException("The file contents could not be located");
749 * @see gr.ebs.gss.server.ejb.ExternalAPI#getFileContents(java.lang.Long, java.lang.Long, java.lang.Long)
752 public InputStream getFileContents(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
754 throw new ObjectNotFoundException("No user specified");
756 throw new ObjectNotFoundException("No file specified");
758 throw new ObjectNotFoundException("No file specified");
760 final FileHeader header = dao.getEntityById(FileHeader.class, fileId);
761 final FileBody body = dao.getEntityById(FileBody.class, bodyId);
762 final User user = dao.getEntityById(User.class, userId);
763 if (!header.hasReadPermission(user)) {
764 logger.info("User " + user.getId() + " cannot read file " + header.getName() + "(" + fileId + ")");
765 throw new InsufficientPermissionsException("You don't have the necessary permissions");
768 File f = new File(body.getStoredFilePath());
770 return new FileInputStream(f);
771 } catch (FileNotFoundException e) {
772 logger.error("Could not locate the contents of file " + f.getAbsolutePath());
773 throw new ObjectNotFoundException("The file contents could not be located");
778 public FileHeaderDTO getFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
780 throw new ObjectNotFoundException("No user specified");
782 throw new ObjectNotFoundException("No file specified");
783 final User user = dao.getEntityById(User.class, userId);
784 final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
785 if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
786 throw new InsufficientPermissionsException("You don't have the necessary permissions");
787 return file.getDTO();
791 public FileBodyDTO getFileBody(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
793 throw new ObjectNotFoundException("No user specified");
795 throw new ObjectNotFoundException("No file specified");
796 User user = dao.getEntityById(User.class, userId);
797 FileHeader file = dao.getEntityById(FileHeader.class, fileId);
798 if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
799 throw new InsufficientPermissionsException("You don't have the necessary permissions");
800 FileBody body = dao.getEntityById(FileBody.class, bodyId);
801 return body.getDTO();
805 public Object getResourceAtPath(Long ownerId, String path, boolean ignoreDeleted)
806 throws ObjectNotFoundException {
808 throw new ObjectNotFoundException("No user specified");
809 if (StringUtils.isEmpty(path))
810 throw new ObjectNotFoundException("No path specified");
812 User owner = dao.getEntityById(User.class, ownerId);
813 List<String> pathElements = new ArrayList<String>();
814 StringTokenizer st = new StringTokenizer(path, "/");
815 while (st.hasMoreTokens())
816 pathElements.add(st.nextToken());
817 if (pathElements.size() < 1)
818 return getRootFolder(owner.getId());
819 // Store the last element, since it requires special handling.
820 String lastElement = pathElements.remove(pathElements.size() - 1);
821 FolderDTO cursor = getRootFolder(owner.getId());
822 // Traverse and verify the specified folder path.
823 for (String pathElement : pathElements) {
824 cursor = getFolder(cursor.getId(), pathElement);
825 if (cursor.isDeleted())
826 throw new ObjectNotFoundException("Folder " + cursor.getPath() + " not found");
829 // Use the lastElement to retrieve the actual resource.
830 Object resource = null;
832 FileHeaderDTO file = getFile(cursor.getId(), lastElement);
833 if (ignoreDeleted && file.isDeleted())
834 throw new ObjectNotFoundException("Resource not found");
836 } catch (ObjectNotFoundException e) {
837 // Perhaps the requested resource is not a file, so
838 // check for folders as well.
839 FolderDTO folder = getFolder(cursor.getId(), lastElement);
840 if (ignoreDeleted && folder.isDeleted())
841 throw new ObjectNotFoundException("Resource not found");
848 * Retrieve a file for the specified user that has the specified name and
849 * its parent folder has id equal to folderId.
851 * @param folderId the ID of the parent folder
852 * @param name the name of the requested file
853 * @return the file found
854 * @throws ObjectNotFoundException if the specified folder or file was not
855 * found, with the exception message mentioning the precise
858 private FileHeaderDTO getFile(Long folderId, String name) throws ObjectNotFoundException {
859 if (folderId == null)
860 throw new ObjectNotFoundException("No parent folder specified");
861 if (StringUtils.isEmpty(name))
862 throw new ObjectNotFoundException("No file specified");
864 FileHeader file = dao.getFile(folderId, name);
865 return file.getDTO();
869 * Retrieve a folder for the specified user that has the specified name and
870 * its parent folder has id equal to parentId.
872 * @param parentId the ID of the parent folder
873 * @param name the name of the requested folder
874 * @return the folder found
875 * @throws ObjectNotFoundException if the specified folder or parent was not
876 * found, with the exception message mentioning the precise
879 private FolderDTO getFolder(Long parentId, String name) throws ObjectNotFoundException {
880 if (parentId == null)
881 throw new ObjectNotFoundException("No parent folder specified");
882 if (StringUtils.isEmpty(name))
883 throw new ObjectNotFoundException("No folder specified");
885 Folder folder = dao.getFolder(parentId, name);
886 return folder.getDTO();
889 private FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
892 file = uploadFile(resourceInputStream, userId);
893 } catch ( IOException ioe) {
894 // Supply a more accurate problem description.
895 throw new GSSIOException("Problem creating file",ioe);
897 return updateFileContents(userId, fileId, mimeType, file.length(), file.getAbsolutePath());
901 public void copyFile(Long userId, Long fileId, String dest) throws ObjectNotFoundException, DuplicateNameException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
903 throw new ObjectNotFoundException("No user specified");
905 throw new ObjectNotFoundException("No file specified");
906 if (StringUtils.isEmpty(dest))
907 throw new ObjectNotFoundException("No destination specified");
909 Object destination = getResourceAtPath(userId, getParentPath(dest), true);
910 if (!(destination instanceof FolderDTO))
911 throw new ObjectNotFoundException("Destination parent folder not found");
912 FolderDTO parent = (FolderDTO) destination;
913 copyFile(userId, fileId, parent.getId(), getLastElement(dest));
917 public void copyFileToPath(Long userId, Long ownerId, Long fileId, String dest) throws ObjectNotFoundException, DuplicateNameException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
919 throw new ObjectNotFoundException("No user specified");
921 throw new ObjectNotFoundException("No owner specified");
923 throw new ObjectNotFoundException("No file specified");
924 if (StringUtils.isEmpty(dest))
925 throw new ObjectNotFoundException("No destination specified");
927 Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
928 if (!(destination instanceof FolderDTO))
929 throw new ObjectNotFoundException("Destination parent folder not found");
930 FolderDTO parent = (FolderDTO) destination;
931 copyFile(userId, fileId, parent.getId(), getLastElement(dest));
935 public void copyFile(Long userId, Long fileId, Long destId, String destName) throws ObjectNotFoundException, DuplicateNameException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
937 throw new ObjectNotFoundException("No user specified");
939 throw new ObjectNotFoundException("No file specified");
941 throw new ObjectNotFoundException("No destination specified");
942 if (StringUtils.isEmpty(destName))
943 throw new ObjectNotFoundException("No destination file name specified");
945 FileHeader file = dao.getEntityById(FileHeader.class, fileId);
946 Folder destination = dao.getEntityById(Folder.class, destId);
947 User user = dao.getEntityById(User.class, userId);
948 if (!file.hasReadPermission(user) || !destination.hasWritePermission(user))
949 throw new InsufficientPermissionsException("You don't have the necessary permissions");
950 boolean versioned = file.isVersioned();
951 int versionsNumber = file.getBodies().size();
952 FileBody oldestBody = file.getBodies().get(0);
953 assert oldestBody != null;
954 File contents = new File(oldestBody.getStoredFilePath());
956 createFile(user.getId(), destination.getId(), destName, oldestBody.getMimeType(), new FileInputStream(contents));
957 FileHeader copiedFile = dao.getFile(destination.getId(), destName);
958 copiedFile.setVersioned(versioned);
960 if (versionsNumber > 1)
961 for (int i = 1; i < versionsNumber; i++) {
962 FileBody body = file.getBodies().get(i);
964 contents = new File(body.getStoredFilePath());
965 updateFileContents(user.getId(), copiedFile.getId(), body.getMimeType(), new FileInputStream(contents));
967 List<FileTag> tags = file.getFileTags();
968 for (FileTag tag : tags)
969 createTag(userId, copiedFile.getId(), tag.getTag());
971 } catch (FileNotFoundException e) {
972 throw new ObjectNotFoundException("File contents not found for file " + contents.getAbsolutePath());
978 public void copyFolder(Long userId, Long folderId, String dest) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException {
980 throw new ObjectNotFoundException("No user specified");
981 if (folderId == null)
982 throw new ObjectNotFoundException("No folder specified");
983 if (StringUtils.isEmpty(dest))
984 throw new ObjectNotFoundException("No destination specified");
986 Object destination = getResourceAtPath(userId, getParentPath(dest), true);
987 if (!(destination instanceof FolderDTO))
988 throw new ObjectNotFoundException("Destination folder not found");
989 FolderDTO parent = (FolderDTO) destination;
990 copyFolder(userId, folderId, parent.getId(), getLastElement(dest));
994 public void copyFolder(Long userId, Long folderId, Long destId, String destName) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException {
996 throw new ObjectNotFoundException("No user specified");
997 if (folderId == null)
998 throw new ObjectNotFoundException("No folder specified");
1000 throw new ObjectNotFoundException("No destination specified");
1001 if (StringUtils.isEmpty(destName))
1002 throw new ObjectNotFoundException("No destination folder name specified");
1003 Folder folder = dao.getEntityById(Folder.class, folderId);
1004 Folder destination = dao.getEntityById(Folder.class, destId);
1005 User user = dao.getEntityById(User.class, userId);
1006 if (!destination.hasWritePermission(user) || !folder.hasReadPermission(user))
1007 throw new InsufficientPermissionsException("You don't have the necessary permissions");
1008 createFolder(user.getId(), destination.getId(), destName);
1012 public void copyFolderStructureToPath(Long userId, Long ownerId, Long folderId, String dest) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
1014 throw new ObjectNotFoundException("No user specified");
1015 if (ownerId == null)
1016 throw new ObjectNotFoundException("No owner specified");
1017 if (folderId == null)
1018 throw new ObjectNotFoundException("No folder specified");
1019 if (StringUtils.isEmpty(dest))
1020 throw new ObjectNotFoundException("No destination specified");
1022 Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
1023 if (!(destination instanceof FolderDTO))
1024 throw new ObjectNotFoundException("Destination folder not found");
1025 FolderDTO parent = (FolderDTO) destination;
1026 copyFolderStructure(userId, folderId, parent.getId(), getLastElement(dest));
1030 public void copyFolderStructure(Long userId, Long folderId, Long destId, String destName) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
1032 throw new ObjectNotFoundException("No user specified");
1033 if (folderId == null)
1034 throw new ObjectNotFoundException("No folder specified");
1036 throw new ObjectNotFoundException("No destination specified");
1037 if (StringUtils.isEmpty(destName))
1038 throw new ObjectNotFoundException("No destination folder name specified");
1040 Folder folder = dao.getEntityById(Folder.class, folderId);
1041 Folder destination = dao.getEntityById(Folder.class, destId);
1042 final User user = dao.getEntityById(User.class, userId);
1043 // XXX: quick fix need to copy only visible items to user (Source
1045 if (!folder.getOwner().getId().equals(userId) && !folder.hasReadPermission(user))
1047 if(folder.isDeleted())//do not copy trashed folder and contents
1049 if (!destination.hasWritePermission(user) || !folder.hasReadPermission(user))
1050 throw new InsufficientPermissionsException("You don't have the necessary permissions");
1051 createFolder(user.getId(), destination.getId(), destName);
1052 Folder createdFolder = dao.getFolder(destination.getId(), destName);
1053 List<FileHeader> files = folder.getFiles();
1055 for (FileHeader file : files)
1056 if(!file.isDeleted())
1057 copyFile(userId, file.getId(), createdFolder.getId(), file.getName());
1058 List<Folder> subFolders = folder.getSubfolders();
1059 if (subFolders != null)
1060 for (Folder sub : subFolders)
1061 if(!sub.getId().equals(createdFolder.getId()))
1062 copyFolderStructure(userId, sub.getId(), createdFolder.getId(), sub.getName());
1067 * For a provided path, remove the last element and return the rest, that is
1068 * the path of the parent folder.
1070 * @param path the specified path
1071 * @return the path of the parent folder
1072 * @throws ObjectNotFoundException if the provided string contains no path
1075 private String getParentPath(String path) throws ObjectNotFoundException {
1076 int lastDelimiter = path.lastIndexOf('/');
1077 if (lastDelimiter == 0)
1079 if (lastDelimiter == -1)
1081 throw new ObjectNotFoundException("There is no parent in the path: " + path);
1082 else if (lastDelimiter < path.length() - 1)
1083 // Return the part before the delimiter.
1084 return path.substring(0, lastDelimiter);
1086 // Remove the trailing delimiter and then recurse.
1087 String strippedTrail = path.substring(0, lastDelimiter);
1088 return getParentPath(strippedTrail);
1093 * Get the last element in a path that denotes the file or folder name.
1095 * @param path the provided path
1096 * @return the last element in the path
1098 private String getLastElement(String path) {
1099 int lastDelimiter = path.lastIndexOf('/');
1100 if (lastDelimiter == -1)
1103 else if (lastDelimiter < path.length() - 1)
1104 // Return the part after the delimiter.
1105 return path.substring(lastDelimiter + 1);
1107 // Remove the trailing delimiter and then recurse.
1108 String strippedTrail = path.substring(0, lastDelimiter);
1109 return getLastElement(strippedTrail);
1114 public void moveFileToTrash(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
1116 throw new ObjectNotFoundException("No user specified");
1118 throw new ObjectNotFoundException("No file specified");
1120 // Do the actual work.
1121 FileHeader file = dao.getEntityById(FileHeader.class, fileId);
1122 Folder parent = file.getFolder();
1124 throw new ObjectNotFoundException("The specified file has no parent folder");
1125 User user = dao.getEntityById(User.class, userId);
1126 if (!file.hasDeletePermission(user))
1127 throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
1129 file.setDeleted(true);
1131 touchParentFolders(parent, user, new Date());
1135 public void moveFileToPath(Long userId, Long ownerId, Long fileId, String dest) throws ObjectNotFoundException, InsufficientPermissionsException, QuotaExceededException {
1137 throw new ObjectNotFoundException("No user specified");
1138 if (ownerId == null)
1139 throw new ObjectNotFoundException("No owner specified");
1141 throw new ObjectNotFoundException("No file specified");
1142 if (StringUtils.isEmpty(dest))
1143 throw new ObjectNotFoundException("No destination specified");
1145 Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
1146 if (!(destination instanceof FolderDTO))
1147 throw new ObjectNotFoundException("Destination parent folder not found");
1148 FolderDTO parent = (FolderDTO) destination;
1149 moveFile(userId, fileId, parent.getId(), getLastElement(dest));
1153 public void moveFile(Long userId, Long fileId, Long destId, String destName) throws InsufficientPermissionsException, ObjectNotFoundException, QuotaExceededException {
1155 throw new ObjectNotFoundException("No user specified");
1157 throw new ObjectNotFoundException("No file specified");
1159 throw new ObjectNotFoundException("No destination specified");
1160 if (StringUtils.isEmpty(destName))
1161 throw new ObjectNotFoundException("No destination file name specified");
1163 FileHeader file = dao.getEntityById(FileHeader.class, fileId);
1164 Folder source = file.getFolder();
1165 Folder destination = dao.getEntityById(Folder.class, destId);
1167 User owner = dao.getEntityById(User.class, userId);
1168 if (!file.hasDeletePermission(owner) || !destination.hasWritePermission(owner))
1169 throw new InsufficientPermissionsException("User " + owner.getId() + " cannot move file " + file.getName() + "(" + file.getId() + ")");
1171 // if the destination folder belongs to another user:
1172 if (!file.getOwner().equals(destination.getOwner())) {
1173 // (a) check if the destination quota allows the move
1174 if(getQuotaLeft(destination.getOwner().getId()) < file.getTotalSize())
1175 throw new QuotaExceededException("Not enough free space available");
1176 User newOwner = destination.getOwner();
1177 // (b) if quota OK, change the owner of the file
1178 file.setOwner(newOwner);
1179 // if the file has no permission for the new owner, add it
1180 Permission ownerPermission = null;
1181 for (final Permission p : file.getPermissions())
1182 if (p.getUser() != null)
1183 if (p.getUser().equals(newOwner)) {
1184 ownerPermission = p;
1187 if (ownerPermission == null) {
1188 ownerPermission = new Permission();
1189 ownerPermission.setUser(newOwner);
1190 file.addPermission(ownerPermission);
1192 ownerPermission.setRead(true);
1193 ownerPermission.setWrite(true);
1194 ownerPermission.setModifyACL(true);
1196 // move the file to the destination folder
1197 file.setFolder(destination);
1198 touchParentFolders(source, owner, new Date());
1199 touchParentFolders(destination, owner, new Date());
1203 public void moveFolderToPath(Long userId, Long ownerId, Long folderId, String dest) throws ObjectNotFoundException, InsufficientPermissionsException, QuotaExceededException {
1205 throw new ObjectNotFoundException("No user specified");
1206 if (ownerId == null)
1207 throw new ObjectNotFoundException("No owner specified");
1208 if (folderId == null)
1209 throw new ObjectNotFoundException("No folder specified");
1210 if (StringUtils.isEmpty(dest))
1211 throw new ObjectNotFoundException("No destination specified");
1213 Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
1214 if (!(destination instanceof FolderDTO))
1215 throw new ObjectNotFoundException("Destination parent folder not found");
1216 FolderDTO parent = (FolderDTO) destination;
1217 moveFolder(userId, folderId, parent.getId(), getLastElement(dest));
1221 public void moveFolder(Long userId, Long folderId, Long destId, String destName)
1222 throws ObjectNotFoundException, InsufficientPermissionsException,
1223 QuotaExceededException {
1224 Folder source = dao.getEntityById(Folder.class, folderId);
1225 Folder destination = dao.getEntityById(Folder.class, destId);
1226 User user = dao.getEntityById(User.class, userId);
1227 User sourceOwner = source.getOwner();
1228 User destinationOwner = destination.getOwner();
1229 // Do not move trashed folders and contents.
1230 if (source.isDeleted())
1232 // Check permissions.
1233 if (!destination.hasWritePermission(user)
1234 || !source.hasReadPermission(user)
1235 || !source.hasWritePermission(user))
1236 throw new InsufficientPermissionsException("You don't have the " +
1237 "necessary permissions");
1238 // Use the same timestamp for all subsequent modifications to make
1239 // changes appear simultaneous.
1240 Date now = new Date();
1241 // If source and destination are not in the same user's namespace,
1242 // change owners and check quota.
1243 if (!sourceOwner.equals(destinationOwner)) {
1244 changeOwner(source, destinationOwner, user, now);
1245 if (getQuotaLeft(destinationOwner.getId()) < 0)
1246 throw new QuotaExceededException("Not enough free space " +
1247 "available in destination folder");
1249 // Perform the move.
1250 Folder oldParent = source.getParent();
1251 oldParent.removeSubfolder(source);
1252 destination.addSubfolder(source);
1253 // Mark the former parent and destination trees upwards as modified.
1254 touchParentFolders(oldParent, user, now);
1255 touchParentFolders(source, user, now);
1259 * Recursively change the owner of the specified folder and all of its
1260 * contents to the specified owner. Also mark them all as modified with the
1261 * specified modifier and modificationDate.
1263 private void changeOwner(Folder folder, User owner, User modifier, Date modificationDate) {
1264 for (FileHeader file: folder.getFiles()) {
1265 file.setOwner(owner);
1266 file.getAuditInfo().setModificationDate(modificationDate);
1267 file.getAuditInfo().setModifiedBy(modifier);
1269 for (Folder sub: folder.getSubfolders())
1270 changeOwner(sub, owner, modifier, modificationDate);
1271 folder.setOwner(owner);
1272 folder.getAuditInfo().setModificationDate(modificationDate);
1273 folder.getAuditInfo().setModifiedBy(modifier);
1277 public List<FileHeaderDTO> getDeletedFiles(Long userId) throws ObjectNotFoundException {
1280 throw new ObjectNotFoundException("No user specified");
1282 // Do the actual work.
1283 final List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
1284 final List<FileHeader> files = dao.getDeletedFiles(userId);
1285 for (final FileHeader f : files)
1286 result.add(f.getDTO());
1291 public void removeFileFromTrash(Long userId, Long fileId)
1292 throws ObjectNotFoundException, InsufficientPermissionsException {
1294 throw new ObjectNotFoundException("No user specified");
1296 throw new ObjectNotFoundException("No file specified");
1298 // Do the actual work.
1299 FileHeader file = dao.getEntityById(FileHeader.class, fileId);
1300 Folder parent = file.getFolder();
1302 throw new ObjectNotFoundException("The specified file has no parent folder");
1303 User user = dao.getEntityById(User.class, userId);
1304 if (!file.hasDeletePermission(user))
1305 throw new InsufficientPermissionsException("User " + user.getUsername() +
1306 " cannot restore file " + file.getName());
1308 file.setDeleted(false);
1310 touchParentFolders(parent, user, new Date());
1314 public void moveFolderToTrash(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
1316 throw new ObjectNotFoundException("No user specified");
1317 if (folderId == null)
1318 throw new ObjectNotFoundException("No folder specified");
1319 Folder folder = dao.getEntityById(Folder.class, folderId);
1320 User user = dao.getEntityById(User.class, userId);
1321 if (!folder.hasDeletePermission(user))
1322 throw new InsufficientPermissionsException("You don't have the necessary permissions");
1323 folder.setDeleted(true);
1325 touchParentFolders(folder, user, new Date());
1326 for (FileHeader file : folder.getFiles())
1327 moveFileToTrash(userId, file.getId());
1328 for (Folder subFolder : folder.getSubfolders())
1329 moveFolderToTrash(userId, subFolder.getId());
1334 public void removeFolderFromTrash(Long userId, Long folderId)
1335 throws ObjectNotFoundException, InsufficientPermissionsException {
1337 throw new ObjectNotFoundException("No user specified");
1338 if (folderId == null)
1339 throw new ObjectNotFoundException("No folder specified");
1340 Folder folder = dao.getEntityById(Folder.class, folderId);
1341 User user = dao.getEntityById(User.class, userId);
1342 if (!folder.hasDeletePermission(user))
1343 throw new InsufficientPermissionsException("User " + user.getUsername() +
1344 " cannot restore folder " + folder.getName());
1345 folder.setDeleted(false);
1346 for (FileHeader file : folder.getFiles())
1347 removeFileFromTrash(userId, file.getId());
1348 for (Folder subFolder : folder.getSubfolders())
1349 removeFolderFromTrash(userId, subFolder.getId());
1351 touchParentFolders(folder, user, new Date());
1355 public List<FolderDTO> getDeletedRootFolders(Long userId) throws ObjectNotFoundException {
1356 List<Folder> folders = dao.getDeletedRootFolders(userId);
1357 List<FolderDTO> result = new ArrayList<FolderDTO>();
1358 for (Folder folder : folders)
1359 result.add(folder.getDTO());
1364 public void emptyTrash(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException {
1365 List<FolderDTO> deletedRootFolders = getDeletedRootFolders(userId);
1366 for (FolderDTO fdto : deletedRootFolders)
1367 deleteFolder(userId, fdto.getId());
1368 List<FileHeaderDTO> deletedFiles = getDeletedFiles(userId);
1369 for (FileHeaderDTO filedto : deletedFiles)
1370 deleteFile(userId, filedto.getId());
1374 public void restoreTrash(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException {
1375 List<FolderDTO> deletedRootFolders = getDeletedRootFolders(userId);
1376 for (FolderDTO fdto : deletedRootFolders)
1377 removeFolderFromTrash(userId, fdto.getId());
1378 List<FileHeaderDTO> deletedFiles = getDeletedFiles(userId);
1379 for (FileHeaderDTO filedto : deletedFiles)
1380 removeFileFromTrash(userId, filedto.getId());
1384 public User createUser(String username, String name, String mail,
1385 String idp, String idpid) throws ObjectNotFoundException {
1386 if (username == null)
1387 throw new ObjectNotFoundException("No username specified");
1389 throw new ObjectNotFoundException("No name specified");
1391 User user = new User();
1392 user.setUsername(username);
1394 user.setEmail(mail);
1395 user.setIdentityProvider(idp);
1396 user.setIdentityProviderId(idpid);
1397 Date now = new Date();
1398 AuditInfo auditInfo = new AuditInfo();
1399 auditInfo.setCreationDate(now);
1400 auditInfo.setModificationDate(now);
1401 user.setAuditInfo(auditInfo);
1402 user.setActive(true);
1403 user.generateAuthToken();
1404 user.generateWebDAVPassword();
1405 user.setUserClass(getDefaultUserClass());
1407 // Make sure we get an ID in the user object.
1409 // Create the root folder for the user.
1410 createFolder(user.getName(), null, user);
1415 * Get the default user class, which is the one with the lowest quota.
1417 private UserClass getDefaultUserClass() {
1418 return getUserClasses().get(0);
1422 public List<UserClass> getUserClasses() {
1423 List<UserClass> classes = dao.getUserClasses();
1424 // Create a default user class for first-time use. Afterwards, the
1425 // admin should modify or add to the userclass table.
1426 if (classes.size() == 0) {
1427 UserClass defaultClass = new UserClass();
1428 defaultClass.setName("default");
1429 Long defaultQuota = getConfiguration().getLong("quota", new Long(52428800L));
1430 defaultClass.setQuota(defaultQuota);
1431 dao.create(defaultClass);
1432 classes.add(defaultClass);
1438 public User findUserByEmail(String email) {
1439 return dao.findUserByEmail(email);
1443 public void updateUser(User user) {
1448 public User findUser(String username) {
1449 if (username == null)
1451 return dao.findUser(username);
1455 public User updateUserToken(Long userId) throws ObjectNotFoundException {
1457 throw new ObjectNotFoundException("No user specified");
1458 User user = dao.getEntityById(User.class, userId);
1459 user.generateAuthToken();
1464 public Set<PermissionDTO> getFolderPermissions(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
1466 throw new ObjectNotFoundException("No user specified");
1467 if (folderId == null)
1468 throw new ObjectNotFoundException("No folder specified");
1469 User user = dao.getEntityById(User.class, userId);
1470 Folder folder = dao.getEntityById(Folder.class, folderId);
1471 if(!folder.hasReadPermission(user))
1472 throw new InsufficientPermissionsException("You don't have the necessary permissions");
1473 Set<Permission> perms = folder.getPermissions();
1474 Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
1475 for (Permission perm : perms)
1476 if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId()))
1477 result.add(perm.getDTO());
1478 for (Permission perm : perms)
1479 if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId())) {
1481 result.add(perm.getDTO());
1487 * Set the provided permissions as the new permissions of the specified
1492 * @param permissions
1493 * @throws ObjectNotFoundException
1494 * @throws InsufficientPermissionsException
1496 private void setFolderPermissions(User user, Folder folder, Set<PermissionDTO> permissions) throws ObjectNotFoundException, InsufficientPermissionsException {
1497 if (permissions != null && !permissions.isEmpty()) {
1498 User owner = folder.getOwner();
1499 PermissionDTO ownerPerm = null;
1500 for (PermissionDTO dto : permissions)
1501 if (dto.getUser() != null && dto.getUser().getId().equals(owner.getId())) {
1505 if (ownerPerm == null || !ownerPerm.hasRead() || !ownerPerm.hasWrite() || !ownerPerm.hasModifyACL())
1506 throw new InsufficientPermissionsException("Can't remove permissions from owner");
1507 // Delete previous entries
1508 for (Permission perm: folder.getPermissions())
1510 folder.getPermissions().clear();
1511 for (PermissionDTO dto : permissions) {
1512 // Skip 'empty' permission entries.
1513 if (!dto.getRead() && !dto.getWrite() && !dto.getModifyACL()) continue;
1514 folder.addPermission(getPermission(dto));
1517 for (FileHeader file : folder.getFiles()) {
1518 setFilePermissions(file, permissions);
1519 Date now = new Date();
1520 file.getAuditInfo().setModificationDate(now);
1521 file.getAuditInfo().setModifiedBy(user);
1523 for (Folder sub : folder.getSubfolders())
1524 setFolderPermissions(user, sub, permissions);
1528 private Permission getPermission(PermissionDTO dto) throws ObjectNotFoundException {
1529 Permission res = new Permission();
1530 if (dto.getGroup() != null)
1531 res.setGroup(dao.getEntityById(Group.class, dto.getGroup().getId()));
1532 else if (dto.getUser() != null)
1533 if (dto.getUser().getId() == null)
1534 res.setUser(dao.getUser(dto.getUser().getUsername()));
1536 res.setUser(dao.getEntityById(User.class, dto.getUser().getId()));
1537 res.setRead(dto.hasRead());
1538 res.setWrite(dto.hasWrite());
1539 res.setModifyACL(dto.hasModifyACL());
1544 * @see gr.ebs.gss.server.ejb.ExternalAPI#getUsersByUserNameLike(java.lang.String)
1547 public List<UserDTO> getUsersByUserNameLike(String username) {
1548 List<User> users = dao.getUsersByUserNameLike(username);
1549 List<UserDTO> result = new ArrayList<UserDTO>();
1550 for (User u : users)
1551 result.add(u.getDTO());
1557 public void addUserToGroup(Long userId, Long groupId, Long userToAddId) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException {
1559 throw new ObjectNotFoundException("No user specified");
1560 if (groupId == null)
1561 throw new ObjectNotFoundException("No group specified");
1562 if (userToAddId == null)
1563 throw new ObjectNotFoundException("No user to add specified");
1564 User user = dao.getEntityById(User.class, userId);
1565 Group group = dao.getEntityById(Group.class, groupId);
1566 if (!group.getOwner().equals(user))
1567 throw new InsufficientPermissionsException();
1568 User userToAdd = dao.getEntityById(User.class, userToAddId);
1569 if (group.contains(userToAdd))
1570 throw new DuplicateNameException("User already exists in group");
1571 group.getMembers().add(userToAdd);
1577 public void invalidateUserToken(Long userId) throws ObjectNotFoundException {
1579 throw new ObjectNotFoundException("No user specified");
1580 User user = dao.getEntityById(User.class, userId);
1581 user.invalidateAuthToken();
1586 public List<FolderDTO> getSharedRootFolders(Long userId) throws ObjectNotFoundException {
1588 throw new ObjectNotFoundException("No user specified");
1589 List<Folder> folders = dao.getSharedRootFolders(userId);
1590 List<FolderDTO> result = new ArrayList<FolderDTO>();
1591 for (Folder f : folders) {
1592 FolderDTO dto = f.getDTO();
1593 dto.setSubfolders(getSharedSubfolders(userId, f.getId()));
1600 public void removeMemberFromGroup(Long userId, Long groupId, Long memberId) throws ObjectNotFoundException, InsufficientPermissionsException {
1602 throw new ObjectNotFoundException("No user specified");
1603 if (groupId == null)
1604 throw new ObjectNotFoundException("No group specified");
1605 if (memberId == null)
1606 throw new ObjectNotFoundException("No member specified");
1607 User owner = dao.getEntityById(User.class, userId);
1608 Group group = dao.getEntityById(Group.class, groupId);
1609 User member = dao.getEntityById(User.class, memberId);
1610 if (!group.getOwner().equals(owner))
1611 throw new InsufficientPermissionsException("User is not the owner of the group");
1612 group.removeMemberFromGroup(member);
1618 public List<UserDTO> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException {
1619 List<User> users = dao.getUsersSharingFoldersForUser(userId);
1620 List<User> usersFiles = dao.getUsersSharingFilesForUser(userId);
1621 List<UserDTO> res = new ArrayList<UserDTO>();
1622 for (User u : users)
1623 res.add(u.getDTO());
1624 for(User fu : usersFiles)
1625 if(!users.contains(fu))
1626 res.add(fu.getDTO());
1631 public Set<PermissionDTO> getFilePermissions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
1633 throw new ObjectNotFoundException("No user specified");
1635 throw new ObjectNotFoundException("No folder specified");
1636 User user = dao.getEntityById(User.class, userId);
1637 FileHeader folder = dao.getEntityById(FileHeader.class, fileId);
1638 if(!folder.hasReadPermission(user))
1639 throw new InsufficientPermissionsException("You don't have the necessary permissions");
1640 Set<Permission> perms = folder.getPermissions();
1641 Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
1642 for (Permission perm : perms)
1643 if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId()))
1644 result.add(perm.getDTO());
1645 for (Permission perm : perms)
1646 if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId())) {
1648 result.add(perm.getDTO());
1653 * Set the provided permissions as the new permissions of the specified
1654 * file. This method sets the modification date/user attributes to the
1655 * current values as a side effect.
1658 * @param permissions
1659 * @throws ObjectNotFoundException
1660 * @throws InsufficientPermissionsException
1662 private void setFilePermissions(FileHeader file,
1663 Set<PermissionDTO> permissions)
1664 throws ObjectNotFoundException, InsufficientPermissionsException {
1665 if (permissions != null && !permissions.isEmpty()) {
1666 PermissionDTO ownerPerm = null;
1667 for (PermissionDTO dto : permissions)
1668 if (dto.getUser() != null && dto.getUser().getId().equals(file.getOwner().getId())) {
1672 if (ownerPerm == null || !ownerPerm.hasRead() || !ownerPerm.hasWrite() || !ownerPerm.hasModifyACL())
1673 throw new InsufficientPermissionsException("Can't remove permissions from owner");
1674 // Delete previous entries.
1675 for (Permission perm: file.getPermissions())
1677 file.getPermissions().clear();
1678 for (PermissionDTO dto : permissions) {
1679 // Skip 'empty' permission entries.
1680 if (!dto.getRead() && !dto.getWrite() && !dto.getModifyACL()) continue;
1681 file.addPermission(getPermission(dto));
1688 public List<FileHeaderDTO> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException {
1690 throw new ObjectNotFoundException("No user specified");
1691 List<FileHeader> files = dao.getSharedFilesNotInSharedFolders(userId);
1692 List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
1693 for (FileHeader f : files)
1694 result.add(f.getDTO());
1699 public List<FileHeaderDTO> getSharedFiles(Long userId) throws ObjectNotFoundException {
1701 throw new ObjectNotFoundException("No user specified");
1702 List<FileHeader> files = dao.getSharedFiles(userId);
1703 List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
1704 for (FileHeader f : files)
1705 result.add(f.getDTO());
1710 public List<FolderDTO> getSharedFolders(Long userId) throws ObjectNotFoundException {
1712 throw new ObjectNotFoundException("No user specified");
1713 List<Folder> folders = dao.getSharedFolders(userId);
1714 List<FolderDTO> result = new ArrayList<FolderDTO>();
1715 for (Folder f : folders)
1716 result.add(f.getDTO());
1721 public List<FileHeaderDTO> getSharedFiles(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
1722 if (ownerId == null)
1723 throw new ObjectNotFoundException("No owner specified");
1724 if (callingUserId == null)
1725 throw new ObjectNotFoundException("No calling user specified");
1726 List<FileHeader> folders = dao.getSharedFiles(ownerId, callingUserId);
1727 List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
1728 for (FileHeader f : folders)
1729 result.add(f.getDTO());
1734 public List<FolderDTO> getSharedRootFolders(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
1735 if (ownerId == null)
1736 throw new ObjectNotFoundException("No owner specified");
1737 if (callingUserId == null)
1738 throw new ObjectNotFoundException("No calling user specified");
1739 List<Folder> folders = dao.getSharedRootFolders(ownerId, callingUserId);
1740 List<FolderDTO> result = new ArrayList<FolderDTO>();
1741 for (Folder f : folders) {
1742 FolderDTO dto = f.getDTO();
1743 dto.setSubfolders(getSharedSubfolders(ownerId, callingUserId, f.getId()));
1751 public List<FolderDTO> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException {
1753 throw new ObjectNotFoundException("No user specified");
1754 if (folderId == null)
1755 throw new ObjectNotFoundException("No folder specified");
1756 User user = dao.getEntityById(User.class, userId);
1757 Folder folder = dao.getEntityById(Folder.class, folderId);
1758 List<FolderDTO> result = new ArrayList<FolderDTO>();
1759 if (folder.isShared(user) || folder.isReadForAll())
1760 for (Folder f : folder.getSubfolders())
1761 if ((f.isShared(user) || f.isReadForAll()) && !f.isDeleted())
1762 result.add(f.getDTO());
1767 public List<FolderDTO> getSharedSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException {
1769 throw new ObjectNotFoundException("No user specified");
1770 if (callingUserId == null)
1771 throw new ObjectNotFoundException("No user specified");
1772 if (folderId == null)
1773 throw new ObjectNotFoundException("No folder specified");
1774 User user = dao.getEntityById(User.class, callingUserId);
1775 Folder folder = dao.getEntityById(Folder.class, folderId);
1776 List<FolderDTO> result = new ArrayList<FolderDTO>();
1777 if (folder.isSharedForOtherUser(user))
1778 for (Folder f : folder.getSubfolders())
1779 if (f.isSharedForOtherUser(user) && !f.isDeleted()){
1780 FolderDTO dto = f.getDTO();
1781 dto.setSubfolders(getSharedSubfolders(userId, callingUserId, dto.getId()));
1789 public List<FileHeader> searchFiles(Long userId, String query) throws ObjectNotFoundException {
1790 long startTime = System.currentTimeMillis();
1792 throw new ObjectNotFoundException("No user specified");
1793 User user = getUser(userId);
1795 throw new ObjectNotFoundException("No query specified");
1796 List<FileHeader> files = search(user.getId(), query);
1798 long stopTime = System.currentTimeMillis();
1799 logger.info("Total time: " + (stopTime - startTime));
1804 * Performs the actuals search on the solr server and returns the results
1808 * @return a List of FileHeader objects
1810 private List<FileHeader> search(Long userId, String query) {
1811 final int maxRows = 100;
1812 List<FileHeader> result = new ArrayList<FileHeader>();
1814 CommonsHttpSolrServer solr = new CommonsHttpSolrServer(getConfiguration().getString("solr.url"));
1815 List<Group> groups = dao.getGroupsContainingUser(userId);
1816 String constructedQuery = escapeCharacters(normalizeSearchQuery(query)) + " AND (public: true OR ureaders: " + userId;
1817 if (!groups.isEmpty()) {
1818 constructedQuery += " OR (";
1819 for (int i=0; i<groups.size(); i++) {
1820 Group g = groups.get(i);
1821 constructedQuery += "greaders :" + g.getId();
1822 if (i < groups.size() - 1)
1823 constructedQuery += " OR ";
1825 constructedQuery += ")";
1827 constructedQuery += ")";
1828 SolrQuery solrQuery = new SolrQuery(constructedQuery);
1829 solrQuery.setRows(maxRows);
1830 long startTime = System.currentTimeMillis();
1831 QueryResponse response = solr.query(solrQuery);
1832 SolrDocumentList results = response.getResults();
1833 if (results.getNumFound() > maxRows) {
1834 solrQuery.setRows(Integer.valueOf((int) results.getNumFound()));
1835 response = solr.query(solrQuery);
1836 results = response.getResults();
1838 long stopTime = System.currentTimeMillis();
1839 logger.info("Search time:" + (stopTime - startTime));
1840 User user = getUser(userId);
1841 startTime = System.currentTimeMillis();
1842 for (SolrDocument d : results) {
1843 Long id = Long.valueOf((String) d.getFieldValue("id"));
1845 FileHeader f = dao.getEntityById(FileHeader.class, id);
1847 } catch (ObjectNotFoundException e) {
1848 logger.warn("Search result id " + id + " cannot be found", e);
1851 stopTime = System.currentTimeMillis();
1852 logger.info("File loads: " + (stopTime - startTime));
1853 } catch (MalformedURLException e) {
1855 throw new EJBException(e);
1856 } catch (SolrServerException e) {
1858 throw new EJBException(e);
1859 } catch (ObjectNotFoundException e) {
1861 throw new EJBException(e);
1867 public void copyFiles(Long userId, List<Long> fileIds, Long destId) throws ObjectNotFoundException, DuplicateNameException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
1868 for(Long l : fileIds){
1869 FileHeader file = dao.getEntityById(FileHeader.class, l);
1870 copyFile(userId, l, destId, file.getName());
1877 public void moveFiles(Long userId, List<Long> fileIds, Long destId) throws InsufficientPermissionsException, ObjectNotFoundException, QuotaExceededException {
1878 for(Long l : fileIds){
1879 FileHeader file = dao.getEntityById(FileHeader.class, l);
1880 moveFile(userId, l, destId, file.getName());
1886 public void deleteFiles(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
1888 throw new ObjectNotFoundException("No user specified");
1889 final User user = dao.getEntityById(User.class, userId);
1890 List<String> filesToRemove = new ArrayList<String>();
1891 //first delete database objects
1892 for(Long fileId : fileIds){
1894 throw new ObjectNotFoundException("No file specified");
1895 final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
1896 final Folder parent = file.getFolder();
1898 throw new ObjectNotFoundException("The specified file has no parent folder");
1899 if (!file.hasDeletePermission(user))
1900 throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
1902 parent.removeFile(file);
1903 for (final FileBody body : file.getBodies())
1904 filesToRemove.add(body.getStoredFilePath());
1906 touchParentFolders(parent, user, new Date());
1908 //then remove physical files if everything is ok
1909 for(String physicalFileName : filesToRemove)
1910 deleteActualFile(physicalFileName);
1911 //then unindex deleted files
1912 for(Long fileId : fileIds)
1913 indexFile(fileId, true);
1918 public void moveFilesToTrash(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
1919 for(Long l : fileIds)
1920 moveFileToTrash(userId, l);
1925 public void removeFilesFromTrash(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
1926 for(Long l : fileIds)
1927 removeFileFromTrash(userId, l);
1932 public Nonce createNonce(Long userId) throws ObjectNotFoundException {
1934 throw new ObjectNotFoundException("No user specified");
1935 User user = dao.getEntityById(User.class, userId);
1936 Nonce nonce = Nonce.createNonce(user.getId());
1942 public Nonce getNonce(String nonce, Long userId) throws ObjectNotFoundException {
1944 throw new ObjectNotFoundException("No user specified");
1946 throw new ObjectNotFoundException("No nonce specified");
1947 return dao.getNonce(nonce, userId);
1951 public void removeNonce(Long id) throws ObjectNotFoundException {
1953 throw new ObjectNotFoundException("No nonce specified");
1954 Nonce nonce = dao.getEntityById(Nonce.class, id);
1959 public void activateUserNonce(Long userId, String nonce, Date nonceExpiryDate) throws ObjectNotFoundException {
1961 throw new ObjectNotFoundException("No user specified");
1962 User user = dao.getEntityById(User.class, userId);
1963 user.setNonce(nonce);
1964 user.setNonceExpiryDate(nonceExpiryDate);
1968 public StatsDTO getUserStatistics(Long userId) throws ObjectNotFoundException {
1970 throw new ObjectNotFoundException("No user specified");
1971 StatsDTO stats = new StatsDTO();
1972 stats.setFileCount(dao.getFileCount(userId));
1973 Long fileSize = dao.getFileSize(userId);
1974 stats.setFileSize(fileSize);
1975 Long quota = getQuota(userId);
1976 Long quotaLeft = quota - fileSize;
1977 stats.setQuotaLeftSize(quotaLeft);
1982 public List<FileBodyDTO> getVersions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
1984 throw new ObjectNotFoundException("No user specified");
1986 throw new ObjectNotFoundException("No file specified");
1987 User user = dao.getEntityById(User.class, userId);
1988 FileHeader header = dao.getEntityById(FileHeader.class, fileId);
1989 if(!header.hasReadPermission(user))
1990 throw new InsufficientPermissionsException("You don't have the necessary permissions");
1991 List<FileBodyDTO> result = new LinkedList<FileBodyDTO>();
1992 for(int i = header.getBodies().size()-1 ; i>=0; i--)
1993 result.add(header.getBodies().get(i).getDTO());
1998 public void removeVersion(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
2000 throw new ObjectNotFoundException("No user specified");
2002 throw new ObjectNotFoundException("No file specified");
2004 throw new ObjectNotFoundException("No body specified");
2005 User user = dao.getEntityById(User.class, userId);
2006 FileHeader header = dao.getEntityById(FileHeader.class, fileId);
2007 if(!header.hasWritePermission(user))
2008 throw new InsufficientPermissionsException("You don't have the necessary permissions");
2009 FileBody body = dao.getEntityById(FileBody.class, bodyId);
2010 if(body.equals(header.getCurrentBody())){
2012 if(header.getBodies().size() == 1)
2013 throw new InsufficientPermissionsException("You cant delete this version, Delete file instead!");
2014 for(FileBody b : header.getBodies())
2015 if(b.getVersion() == body.getVersion()-1)
2016 header.setCurrentBody(b);
2018 deleteActualFile(body.getStoredFilePath());
2019 header.getBodies().remove(body);
2021 Folder parent = header.getFolder();
2022 touchParentFolders(parent, user, new Date());
2027 public void restoreVersion(Long userId, Long fileId, int version) throws ObjectNotFoundException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
2029 throw new ObjectNotFoundException("No user specified");
2031 throw new ObjectNotFoundException("No file specified");
2032 User user = dao.getEntityById(User.class, userId);
2033 FileHeader header = dao.getEntityById(FileHeader.class, fileId);
2034 if(!header.hasWritePermission(user))
2035 throw new InsufficientPermissionsException("You don't have the necessary permissions");
2036 FileBody body = dao.getFileVersion(fileId, version);
2037 final File fileContents = new File(body.getStoredFilePath());
2040 updateFileContents(userId, fileId, body.getMimeType(), new FileInputStream(fileContents) );
2041 } catch (FileNotFoundException e) {
2042 throw new GSSIOException(e);
2048 * @see gr.ebs.gss.server.ejb.ExternalAPI#removeOldVersions(java.lang.Long, java.lang.Long)
2051 public void removeOldVersions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
2053 throw new ObjectNotFoundException("No user specified");
2055 throw new ObjectNotFoundException("No file specified");
2056 User user = dao.getEntityById(User.class, userId);
2057 FileHeader header = dao.getEntityById(FileHeader.class, fileId);
2058 if(!header.hasWritePermission(user))
2059 throw new InsufficientPermissionsException("You don't have the necessary permissions");
2060 Iterator<FileBody> it = header.getBodies().iterator();
2061 while(it.hasNext()){
2062 FileBody body = it.next();
2063 if(!body.equals(header.getCurrentBody())){
2064 deleteActualFile(body.getStoredFilePath());
2069 header.getCurrentBody().setVersion(1);
2071 Folder parent = header.getFolder();
2072 touchParentFolders(parent, user, new Date());
2076 * Gets the quota left for specified user ID.
2078 private Long getQuotaLeft(Long userId) throws ObjectNotFoundException{
2079 Long fileSize = dao.getFileSize(userId);
2080 Long quota = getQuota(userId);
2081 return quota - fileSize;
2085 * Gets the quota for specified user ID.
2087 private Long getQuota(Long userId) throws ObjectNotFoundException{
2088 UserClass uc = getUser(userId).getUserClass();
2090 uc = getDefaultUserClass();
2091 return uc.getQuota();
2095 @TransactionAttribute(TransactionAttributeType.NEVER)
2096 public String rebuildSolrIndex() {
2098 CommonsHttpSolrServer solr = new CommonsHttpSolrServer(getConfiguration().getString("solr.url"));
2099 solr.deleteByQuery("*:*");
2101 logger.info("Deleted everything in solr");
2103 List<Long> fileIds = dao.getAllFileIds();
2104 logger.info("Total of " + fileIds.size() + " will be indexed");
2106 for (Long id : fileIds) {
2107 postFileToSolr(solr, id);
2111 logger.info("Sent commit to solr at file " + i);
2116 logger.info("Finished indexing of " + i + " files");
2117 return "Finished indexing of " + i + " files";
2118 } catch (IOException e) {
2119 throw new EJBException(e);
2120 } catch (SolrServerException e) {
2121 throw new EJBException(e);
2126 @TransactionAttribute(TransactionAttributeType.NEVER)
2127 public String refreshSolrIndex() {
2129 CommonsHttpSolrServer solr = new CommonsHttpSolrServer(getConfiguration().getString("solr.url"));
2131 List<Long> fileIds = dao.getAllFileIds();
2132 logger.info("Total of " + fileIds.size() + " will be indexed");
2134 for (Long id : fileIds) {
2135 postFileToSolr(solr, id);
2140 logger.info("Sent commit to solr at file " + i);
2144 logger.info("Finished indexing of " + i + " files");
2145 return "Finished indexing of " + i + " files";
2146 } catch (IOException e) {
2147 throw new EJBException(e);
2148 } catch (SolrServerException e) {
2149 throw new EJBException(e);
2154 public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, long fileSize, String filePath)
2155 throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
2156 InsufficientPermissionsException, QuotaExceededException {
2159 throw new ObjectNotFoundException("No user specified");
2160 if (folderId == null)
2161 throw new ObjectNotFoundException("No folder specified");
2162 String contentType = mimeType;
2163 if (StringUtils.isEmpty(mimeType))
2164 contentType = DEFAULT_MIME_TYPE;
2165 if (StringUtils.isEmpty(name))
2166 throw new ObjectNotFoundException("No file name specified");
2167 if (dao.existsFolderOrFile(folderId, name))
2168 throw new DuplicateNameException("A folder or file with the name '" + name +
2169 "' already exists at this level");
2171 // Do the actual work.
2172 Folder parent = null;
2174 parent = dao.getEntityById(Folder.class, folderId);
2175 } catch (final ObjectNotFoundException onfe) {
2176 // Supply a more accurate problem description.
2177 throw new ObjectNotFoundException("Parent folder not found");
2179 final User owner = dao.getEntityById(User.class, userId);
2180 if (!parent.hasWritePermission(owner))
2181 throw new InsufficientPermissionsException("You don't have the permissions to write to this folder");
2182 final FileHeader file = new FileHeader();
2184 parent.addFile(file);
2185 // set file owner to folder owner
2186 file.setOwner(parent.getOwner());
2187 //set file's readForAll value according to parent folder readForAll value
2188 file.setReadForAll(parent.isReadForAll());
2190 final Date now = new Date();
2191 final AuditInfo auditInfo = new AuditInfo();
2192 auditInfo.setCreatedBy(owner);
2193 auditInfo.setCreationDate(now);
2194 auditInfo.setModifiedBy(owner);
2195 auditInfo.setModificationDate(now);
2196 file.setAuditInfo(auditInfo);
2197 // TODO set the proper versioning flag on creation
2198 file.setVersioned(false);
2200 for (final Permission p : parent.getPermissions()) {
2201 final Permission permission = new Permission();
2202 permission.setGroup(p.getGroup());
2203 permission.setUser(p.getUser());
2204 permission.setRead(p.getRead());
2205 permission.setWrite(p.getWrite());
2206 permission.setModifyACL(p.getModifyACL());
2207 file.addPermission(permission);
2210 // Create the file body.
2212 createFileBody(name, contentType, fileSize, filePath, file, auditInfo);
2213 } catch (FileNotFoundException e) {
2214 throw new GSSIOException(e);
2216 touchParentFolders(parent, owner, new Date());
2218 indexFile(file.getId(), false);
2220 return file.getDTO();
2224 public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, long fileSize, String filePath) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
2226 throw new ObjectNotFoundException("No user specified");
2228 throw new ObjectNotFoundException("No file specified");
2229 String contentType = mimeType;
2231 FileHeader file = dao.getEntityById(FileHeader.class, fileId);
2233 // if no mime type or the generic mime type is defined by the client, then try to identify it from the filename extension
2234 if (StringUtils.isEmpty(mimeType) || "application/octet-stream".equals(mimeType)
2235 || "application/download".equals(mimeType) || "application/force-download".equals(mimeType)
2236 || "octet/stream".equals(mimeType) || "application/unknown".equals(mimeType))
2237 contentType = identifyMimeType(file.getName());
2239 final User owner = dao.getEntityById(User.class, userId);
2240 if (!file.hasWritePermission(owner))
2241 throw new InsufficientPermissionsException("You don't have the necessary permissions");
2242 final Date now = new Date();
2243 final AuditInfo auditInfo = new AuditInfo();
2244 auditInfo.setCreatedBy(owner);
2245 auditInfo.setCreationDate(now);
2246 auditInfo.setModifiedBy(owner);
2247 auditInfo.setModificationDate(now);
2249 createFileBody(file.getName(), contentType, fileSize, filePath, file, auditInfo);
2250 } catch (FileNotFoundException e) {
2251 throw new GSSIOException(e);
2253 Folder parent = file.getFolder();
2254 touchParentFolders(parent, owner, new Date());
2256 indexFile(fileId, false);
2257 return file.getDTO();
2261 * Helper method for identifying mime type by examining the filename extension
2264 * @return the mime type
2266 private String identifyMimeType(String filename) {
2267 if (filename.indexOf('.') != -1) {
2268 String extension = filename.substring(filename.lastIndexOf('.')).toLowerCase(Locale.ENGLISH);
2269 if (".doc".equals(extension))
2270 return "application/msword";
2271 else if (".xls".equals(extension))
2272 return "application/vnd.ms-excel";
2273 else if (".ppt".equals(extension))
2274 return "application/vnd.ms-powerpoint";
2275 else if (".pdf".equals(extension))
2276 return "application/pdf";
2277 else if (".gif".equals(extension))
2279 else if (".jpg".equals(extension) || ".jpeg".equals(extension) || ".jpe".equals(extension))
2280 return "image/jpeg";
2281 else if (".tiff".equals(extension) || ".tif".equals(extension))
2282 return "image/tiff";
2283 else if (".png".equals(extension))
2285 else if (".bmp".equals(extension))
2288 // when all else fails assign the default mime type
2289 return DEFAULT_MIME_TYPE;
2293 * Helper method to create a new file body and attach it as the current body
2294 * of the provided file header.
2296 * @param name the original file name
2297 * @param mimeType the content type
2298 * @param fileSize the uploaded file size
2299 * @param filePath the uploaded file full path
2300 * @param header the file header that will be associated with the new body
2301 * @param auditInfo the audit info
2302 * @throws FileNotFoundException
2303 * @throws QuotaExceededException
2304 * @throws ObjectNotFoundException if the owner was not found
2306 private void createFileBody(String name, String mimeType, long fileSize, String filePath,
2307 FileHeader header, AuditInfo auditInfo)
2308 throws FileNotFoundException, QuotaExceededException, ObjectNotFoundException {
2310 long currentTotalSize = 0;
2311 if (!header.isVersioned() && header.getCurrentBody() != null && header.getBodies() != null)
2312 currentTotalSize = header.getTotalSize();
2313 Long quotaLeft = getQuotaLeft(header.getOwner().getId());
2314 if(quotaLeft < fileSize-currentTotalSize) {
2315 // quota exceeded -> delete the file
2316 deleteActualFile(filePath);
2317 throw new QuotaExceededException("Not enough free space available");
2320 FileBody body = new FileBody();
2322 // if no mime type or the generic mime type is defined by the client, then try to identify it from the filename extension
2323 if (StringUtils.isEmpty(mimeType) || "application/octet-stream".equals(mimeType)
2324 || "application/download".equals(mimeType) || "application/force-download".equals(mimeType)
2325 || "octet/stream".equals(mimeType) || "application/unknown".equals(mimeType))
2326 body.setMimeType(identifyMimeType(name));
2328 body.setMimeType(mimeType);
2329 body.setAuditInfo(auditInfo);
2330 body.setFileSize(fileSize);
2331 body.setOriginalFilename(name);
2332 body.setStoredFilePath(filePath);
2333 //CLEAR OLD VERSION IF FILE IS NOT VERSIONED AND GETS UPDATED
2334 if(!header.isVersioned() && header.getCurrentBody() != null){
2335 header.setCurrentBody(null);
2336 if (header.getBodies() != null) {
2337 Iterator<FileBody> it = header.getBodies().iterator();
2338 while(it.hasNext()){
2339 FileBody bo = it.next();
2340 deleteActualFile(bo.getStoredFilePath());
2348 header.addBody(body);
2349 header.setAuditInfo(auditInfo);
2356 @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
2357 public File uploadFile(InputStream stream, Long userId) throws IOException, ObjectNotFoundException {
2359 throw new ObjectNotFoundException("No user specified");
2360 User owner = dao.getEntityById(User.class, userId);
2362 throw new ObjectNotFoundException("No user specified");
2363 long start = 0, end = 0;
2364 if (logger.isDebugEnabled())
2365 start = System.currentTimeMillis();
2366 File result = new File(generateRepositoryFilePath());
2368 final FileOutputStream output = new FileOutputStream(result);
2369 final byte[] buffer = new byte[UPLOAD_BUFFER_SIZE];
2372 while (-1 != (n = stream.read(buffer)))
2373 output.write(buffer, 0, n);
2376 } catch (IOException e) {
2377 if (!result.delete())
2378 logger.warn("Could not delete " + result.getPath());
2381 if (logger.isDebugEnabled()) {
2382 end = System.currentTimeMillis();
2383 logger.debug("Time to upload: " + (end - start) + " (msec)");
2390 public void createFileUploadProgress(Long userId, String filename, Long bytesTransfered, Long fileSize) throws ObjectNotFoundException{
2393 throw new ObjectNotFoundException("No user specified");
2394 User user = dao.getEntityById(User.class, userId);
2395 FileUploadStatus status = dao.getFileUploadStatus(userId, filename);
2397 status = new FileUploadStatus();
2398 status.setOwner(user);
2399 status.setFilename(filename);
2400 status.setBytesUploaded(bytesTransfered);
2401 status.setFileSize(fileSize);
2405 status.setBytesUploaded(bytesTransfered);
2406 status.setFileSize(fileSize);
2413 public void removeFileUploadProgress(Long userId, String filename) throws ObjectNotFoundException{
2415 throw new ObjectNotFoundException("No user specified");
2416 FileUploadStatus status = dao.getFileUploadStatus(userId, filename);
2422 public FileUploadStatus getFileUploadStatus(Long userId, String fileName) {
2423 return dao.getFileUploadStatus(userId, fileName);
2427 public FolderDTO getFolderWithSubfolders(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
2429 throw new ObjectNotFoundException("No user specified");
2430 if (folderId == null)
2431 throw new ObjectNotFoundException("No folder specified");
2432 final User user = dao.getEntityById(User.class, userId);
2433 final Folder folder = dao.getEntityById(Folder.class, folderId);
2434 // Check permissions
2435 if (!folder.hasReadPermission(user))
2436 throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
2437 List<FolderDTO> subfolders = new ArrayList<FolderDTO>();
2438 if (folder.hasReadPermission(user))
2439 for (Folder f : folder.getSubfolders())
2440 if (f.hasReadPermission(user) && !f.isDeleted())
2441 subfolders.add(f.getDTO());
2442 FolderDTO result = folder.getDTO();
2443 result.setSubfolders(subfolders);
2444 return folder.getDTO();
2448 public FolderDTO getFolderWithSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
2450 throw new ObjectNotFoundException("No user specified");
2451 if (folderId == null)
2452 throw new ObjectNotFoundException("No folder specified");
2453 User user = dao.getEntityById(User.class, callingUserId);
2454 Folder folder = dao.getEntityById(Folder.class, folderId);
2455 // Check permissions
2456 if (!folder.hasReadPermission(user))
2457 throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
2459 FolderDTO result = folder.getDTO();
2460 result.setSubfolders(getSharedSubfolders(userId, callingUserId, folder.getId()));
2465 public FileBodyDTO getFileVersion(Long userId, Long fileId, int version)
2466 throws ObjectNotFoundException, InsufficientPermissionsException {
2468 throw new ObjectNotFoundException("No user specified");
2470 throw new ObjectNotFoundException("No file specified");
2472 throw new ObjectNotFoundException("No valid version specified");
2473 User user = dao.getEntityById(User.class, userId);
2474 FileHeader file = dao.getEntityById(FileHeader.class, fileId);
2475 if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
2476 throw new InsufficientPermissionsException("You don't have the necessary permissions");
2477 FileBody body = dao.getFileVersion(fileId, version);
2478 return body.getDTO();
2482 public User updateUserPolicyAcceptance(Long userId, boolean isAccepted) throws ObjectNotFoundException {
2484 throw new ObjectNotFoundException("No user specified");
2485 User user = dao.getEntityById(User.class, userId);
2486 user.setAcceptedPolicy(isAccepted);
2491 public void updateAccounting(User user, Date date, long bandwidthDiff) {
2492 dao.updateAccounting(user, date, bandwidthDiff);
2496 public boolean canReadFolder(Long userId, Long folderId) throws ObjectNotFoundException {
2498 throw new ObjectNotFoundException("No user specified");
2499 if (folderId == null)
2500 throw new ObjectNotFoundException("No folder specified");
2501 User user = dao.getEntityById(User.class, userId);
2502 Folder folder = dao.getEntityById(Folder.class, folderId);
2503 // Check permissions
2504 if (!folder.hasReadPermission(user))
2510 public String resetWebDAVPassword(Long userId) throws ObjectNotFoundException {
2512 throw new ObjectNotFoundException("No user specified");
2513 User user = dao.getEntityById(User.class, userId);
2514 user.generateWebDAVPassword();
2515 return user.getWebDAVPassword();
2519 public Invitation findInvite(String code) {
2522 return dao.findInvite(code);
2526 public void createLdapUser(String username, String firstname, String lastname, String email, String password) {
2527 LDAPConnection lc = new LDAPConnection();
2528 LDAPAttributeSet attributeSet = new LDAPAttributeSet();
2529 attributeSet.add(new LDAPAttribute("objectClass", getConfiguration().getStringArray("objectClass")));
2530 attributeSet.add(new LDAPAttribute("uid", username));
2531 attributeSet.add(new LDAPAttribute("cn", new String[]{firstname + " " + lastname}));
2532 attributeSet.add(new LDAPAttribute("sn", lastname));
2533 attributeSet.add(new LDAPAttribute("givenName", firstname));
2534 attributeSet.add(new LDAPAttribute("mail", email));
2535 attributeSet.add(new LDAPAttribute("userPassword", password));
2536 String dn = "uid=" + username + "," + getConfiguration().getString("baseDn");
2537 LDAPEntry newEntry = new LDAPEntry(dn, attributeSet);
2539 lc.connect(getConfiguration().getString("ldapHost"), LDAPConnection.DEFAULT_PORT);
2540 lc.bind(LDAPConnection.LDAP_V3, getConfiguration().getString("bindDn"),
2541 getConfiguration().getString("bindPassword").getBytes("UTF8"));
2543 logger.info("Successfully added LDAP account: " + dn);
2545 } catch(LDAPException e) {
2546 throw new RuntimeException(e);
2547 } catch(UnsupportedEncodingException e) {
2548 throw new RuntimeException(e);
2554 public UserClass upgradeUserClass(String username, String code) throws ObjectNotFoundException, InvitationUsedException {
2555 User user = findUser(username);
2557 throw new ObjectNotFoundException("The user was not found");
2558 Invitation invite = findInvite(code);
2559 if (invite.getUser() != null)
2560 throw new InvitationUsedException("This code has already been used");
2561 invite.setUser(user);
2562 UserClass couponClass = getCouponUserClass();
2563 user.setUserClass(couponClass);
2568 public UserClass getCouponUserClass() {
2569 return dao.findCouponUserClass();
2573 * Mark the folder as modified from the specified user and change it's modification date.
2575 private void touchFolder(Folder f, User _user, Date now){
2576 final AuditInfo auditInfo = f.getAuditInfo();
2577 auditInfo.setModificationDate(now);
2578 auditInfo.setModifiedBy(_user);
2579 f.setAuditInfo(auditInfo);
2583 * Mark the file as modified from the specified user and change it's modification date.
2585 private void touchFile(FileHeader f, User _user, Date now){
2586 final AuditInfo auditInfo = f.getAuditInfo();
2587 auditInfo.setModificationDate(now);
2588 auditInfo.setModifiedBy(_user);
2589 f.setAuditInfo(auditInfo);
2593 * Set the provided readForAll as the new readforAll value of the specified
2594 * folder and sub-folders.
2599 * @throws ObjectNotFoundException
2602 private void setFolderReadForAll(User user, Folder folder, Boolean readForAll){
2603 if (readForAll != null && user.equals(folder.getOwner())){
2604 folder.setReadForAll(readForAll);
2606 for (FileHeader file : folder.getFiles())
2607 file.setReadForAll(readForAll);
2609 //only update subfolders when readforall is true. otherwise all sub-folders stay untouched
2610 for (Folder sub : folder.getSubfolders())
2611 setFolderReadForAll(user, sub, readForAll);
2618 * Update the userLogin with the values from the supplied object.
2621 public void addUserLogin(UserLogin userLogin) {
2622 dao.update(userLogin);
2627 * Retrieves the current session user login and the user's last login
2630 * @return a list of last two user logins
2631 * @throws ObjectNotFoundException
2634 public List<UserLogin> getUserLogins(Long userId) throws ObjectNotFoundException{
2635 List<UserLogin> userLoginResults = new ArrayList<UserLogin>();
2636 userLoginResults = dao.getLoginsForUser(userId);
2637 if(userLoginResults.size() == 0)
2638 throw new ObjectNotFoundException("No userlogin found for the user");
2639 //if the user logins for the first time lastLoginDate = currentLoginDate
2640 if(userLoginResults.size()==1)
2641 userLoginResults.add(userLoginResults.get(0));
2642 return userLoginResults;
2647 public void postFileToSolr(CommonsHttpSolrServer solr, Long id) {
2649 FileHeader file = dao.getFileForIndexing(id);
2650 FileBody body = file.getCurrentBody();
2651 String mime = body.getMimeType();
2652 boolean multipart = true;
2653 if (!mime.equals("application/pdf")
2654 && !mime.equals("text/plain")
2655 && !mime.equals("text/html")
2656 && !mime.endsWith("msword")
2657 && !mime.endsWith("ms-excel")
2658 && !mime.endsWith("powerpoint")
2659 || (body.getFileSize() > getConfiguration().getLong("solrDocumentUploadLimitInKB") * 1024))
2663 sendMetaDataOnly(solr, file);
2665 ContentStreamUpdateRequest solrRequest = new ContentStreamUpdateRequest(getConfiguration().getString("solr.rich.update.path"));
2666 solrRequest.setParam("literal.id", file.getId().toString());
2667 solrRequest.setParam("literal.name", file.getName());
2668 for (FileTag t : file.getFileTags()) {
2669 solrRequest.getParams().add("literal.tag", t.getTag());
2671 for (Permission p : file.getPermissions()) {
2673 if (p.getUser() != null)
2674 solrRequest.setParam("literal.ureaders", p.getUser().getId().toString());
2675 else if (p.getGroup() != null)
2676 solrRequest.setParam("literal.greaders", p.getGroup().getId().toString());
2679 solrRequest.setParam("literal.owner", file.getOwner().getId().toString());
2680 solrRequest.setParam("literal.public", String.valueOf(file.isReadForAll()));
2681 File fsFile = new File(body.getStoredFilePath());
2682 solrRequest.addFile(fsFile);
2684 solr.request(solrRequest);
2686 catch (SolrException e) {
2687 logger.warn("File " + id + " failed with SolrException: " + e.getLocalizedMessage() + ". Retrying without the file");
2688 //Let 's try without the file
2689 sendMetaDataOnly(solr, file);
2691 catch (NullPointerException e) {
2692 logger.warn("File " + id + " failed with NullPointerException: " + e.getLocalizedMessage() + ". Retrying without the file");
2693 //Let 's try without the file
2694 sendMetaDataOnly(solr, file);
2696 catch (SolrServerException e) {
2697 logger.warn("File " + id + " failed with SolrServerException: " + e.getLocalizedMessage() + ". Retrying without the file");
2698 //Let 's try without the file
2699 sendMetaDataOnly(solr, file);
2702 } catch (MalformedURLException e) {
2703 throw new EJBException(e);
2704 } catch (ObjectNotFoundException e) {
2705 logger.error("Indexing of file id " + id + " failed.", e);
2706 } catch (SolrServerException e) {
2707 throw new EJBException(e);
2708 } catch (IOException e) {
2709 throw new EJBException(e);
2713 private void sendMetaDataOnly(CommonsHttpSolrServer solr, FileHeader file) throws SolrServerException, IOException {
2714 SolrInputDocument solrDoc = new SolrInputDocument();
2715 solrDoc.addField("id", file.getId().toString());
2716 solrDoc.addField("name", file.getName());
2717 for (FileTag t : file.getFileTags()) {
2718 solrDoc.addField("tag", t.getTag());
2720 for (Permission p : file.getPermissions()) {
2722 if (p.getUser() != null)
2723 solrDoc.addField("ureaders", p.getUser().getId());
2724 else if (p.getGroup() != null)
2725 solrDoc.addField("greaders", p.getGroup().getId());
2728 solrDoc.addField("owner", file.getOwner().getId());
2729 solrDoc.addField("public", file.isReadForAll());
2733 private String tokenizeFilename(String filename){
2734 StringBuffer result = new StringBuffer();
2735 StringTokenizer tokenizer = new StringTokenizer(filename,"._");
2736 while(tokenizer.hasMoreTokens()){
2737 result.append(tokenizer.nextToken());
2740 result.append(filename);
2741 return result.toString();
2744 private String normalizeSearchQuery(String query) {
2745 if (query.contains("*"))
2746 return query.toLowerCase().replace('ά', 'α').replace('έ', 'ε').replace('ί', 'ι').replace('ή', 'η').replace('ύ', 'υ')
2747 .replace('ό', 'ο').replace('ς', 'σ').replace('ώ', 'ω').replace('ϊ', 'ι').replace('ϋ', 'υ');
2752 private String escapeCharacters(String text) {
2753 return text.replaceAll(":", "\\\\:");