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.ObjectNotFoundException;
23 import gr.ebs.gss.server.domain.AccountingInfo;
24 import gr.ebs.gss.server.domain.FileBody;
25 import gr.ebs.gss.server.domain.FileHeader;
26 import gr.ebs.gss.server.domain.FileUploadStatus;
27 import gr.ebs.gss.server.domain.Folder;
28 import gr.ebs.gss.server.domain.Group;
29 import gr.ebs.gss.server.domain.Invitation;
30 import gr.ebs.gss.server.domain.Nonce;
31 import gr.ebs.gss.server.domain.User;
32 import gr.ebs.gss.server.domain.UserClass;
34 import java.util.ArrayList;
35 import java.util.Calendar;
36 import java.util.Date;
37 import java.util.GregorianCalendar;
38 import java.util.HashSet;
39 import java.util.List;
42 import javax.ejb.Stateless;
43 import javax.persistence.EntityManager;
44 import javax.persistence.NoResultException;
45 import javax.persistence.PersistenceContext;
47 import org.apache.commons.lang.StringUtils;
50 * The implementation of the GSSDAO interface.
53 public class GSSDAOBean implements GSSDAO {
55 private static final int BANDWIDTH_TIME_PERIOD_FIELD = Calendar.MONTH;
56 private static final int BANDWIDTH_TIME_PERIOD_AMOUNT = 1;
59 * The entity manager for the persistence unit
61 @PersistenceContext(unitName = "gss")
62 private EntityManager manager;
65 public Folder getRootFolder(final Long userId) throws ObjectNotFoundException {
68 throw new ObjectNotFoundException("No user specified");
69 return (Folder) manager .createQuery("select f from Folder f where f.owner.id=:ownerId and f.parent is null")
70 .setParameter("ownerId", userId)
72 } catch (final NoResultException e) {
73 throw new ObjectNotFoundException("Root folder not found for user with id=" + userId);
78 public User getUser(final String username) throws ObjectNotFoundException {
81 throw new ObjectNotFoundException("No user specified");
82 return (User) manager .createQuery("select f from User f where f.username=:username")
83 .setParameter("username", username)
85 } catch (final NoResultException e) {
86 throw new ObjectNotFoundException("No User found for username=" + username);
91 public void create(final Object obj) {
93 throw new IllegalArgumentException("No object speficied");
98 public void refresh(final Object obj) {
100 throw new IllegalArgumentException("No object speficied");
101 manager.refresh(obj);
105 public void update(final Object obj) {
107 throw new IllegalArgumentException("No object speficied");
112 public void delete(final Object entity) {
114 throw new IllegalArgumentException("No object speficied");
115 manager.remove(entity);
119 public <T> T getEntityById(final Class<T> _class, final Object _id) throws ObjectNotFoundException {
121 throw new ObjectNotFoundException("No " + _class.getSimpleName() + " specified");
123 final T entity = manager.find(_class, _id);
125 throw new ObjectNotFoundException(_class.getSimpleName() + " with id=" + _id + " was not found");
131 @SuppressWarnings("unchecked")
132 public List<Group> getGroups(final Long userId) throws ObjectNotFoundException {
134 throw new ObjectNotFoundException("No user specified");
136 return manager.createQuery("select g from Group g where g.owner.id=:userId").setParameter("userId", userId).getResultList();
140 @SuppressWarnings("unchecked")
141 public List<FileHeader> getFiles(final Long folderId, Long userId, boolean ignoreDeleted) throws ObjectNotFoundException {
142 if (folderId == null)
143 throw new ObjectNotFoundException("No folder specified");
145 throw new ObjectNotFoundException("No user specified");
146 User user = getEntityById(User.class, userId);
149 query = "select f from FileHeader f where f.folder.id=:folderId and f.deleted=false";
151 query = "select f from FileHeader f where f.folder.id=:folderId";
152 List<FileHeader> tempList = manager.createQuery(query).setParameter("folderId", folderId).getResultList();
153 List<FileHeader> retv = new ArrayList<FileHeader>();
154 for (FileHeader f: tempList)
155 if (f.hasReadPermission(user)) retv.add(f);
161 @SuppressWarnings("unchecked")
162 public List<User> getUsers(final Long groupId) throws ObjectNotFoundException {
164 throw new ObjectNotFoundException("No group specified");
165 return manager.createQuery("select u from User u join u.groupsMember g where g.id=:groupId").
166 setParameter("groupId", groupId).getResultList();
170 public boolean existsFolderOrFile(Long parentId, String name) throws ObjectNotFoundException {
171 if (parentId == null)
172 throw new ObjectNotFoundException("No parent folder specified");
173 if (StringUtils.isEmpty(name))
174 throw new IllegalArgumentException("No folder name specified");
177 manager .createQuery("select f from Folder f " +
178 "where f.parent.id=:parentId and f.name=:name")
179 .setParameter("parentId", parentId)
180 .setParameter("name", name)
183 } catch (NoResultException e) {
185 manager .createQuery("select f from FileHeader f " +
186 "where f.folder.id=:parentId and f.name=:name")
187 .setParameter("parentId", parentId)
188 .setParameter("name", name)
191 } catch (NoResultException e1) {
198 public boolean existsGroup(final Long userId, final String name) throws ObjectNotFoundException {
200 throw new ObjectNotFoundException("No user specified");
201 if (StringUtils.isEmpty(name))
202 throw new ObjectNotFoundException("No group name specified");
204 manager .createQuery("select g from Group g where g.owner.id=:userId and g.name=:name")
205 .setParameter("userId", userId)
206 .setParameter("name", name)
209 } catch (final NoResultException e) {
215 public Set<String> getUserTags(final Long userId) throws ObjectNotFoundException {
217 throw new ObjectNotFoundException("No user specified");
218 return new HashSet(manager.createQuery("select t.tag from FileTag t where t.user.id=:userId order by t.tag")
219 .setParameter("userId", userId)
224 public void flush() {
229 public FileHeader getFile(Long folderId, String name) throws ObjectNotFoundException {
230 if (folderId == null)
231 throw new ObjectNotFoundException("No parent folder specified");
232 if (StringUtils.isEmpty(name))
233 throw new IllegalArgumentException("No file name specified");
236 return (FileHeader) manager.createQuery("select f from FileHeader f where f.folder.id=:parentId and f.name=:name")
237 .setParameter("parentId", folderId)
238 .setParameter("name", name)
240 } catch (final NoResultException e1) {
241 throw new ObjectNotFoundException("File not found");
246 public Folder getFolder(Long parentId, String name) throws ObjectNotFoundException {
247 if (parentId == null)
248 throw new ObjectNotFoundException("No parent folder specified");
249 if (StringUtils.isEmpty(name))
250 throw new IllegalArgumentException("No folder name specified");
253 return (Folder) manager.createQuery("select f from Folder f where f.parent.id=:parentId and f.name=:name")
254 .setParameter("parentId", parentId)
255 .setParameter("name", name)
257 } catch (NoResultException e) {
258 throw new ObjectNotFoundException("Folder not found");
263 public List<FileHeader> getDeletedFiles(Long userId) throws ObjectNotFoundException {
265 throw new ObjectNotFoundException("No User specified");
266 User user = getEntityById(User.class, userId);
268 List<FileHeader> tempList = manager.createQuery("select f from FileHeader f where f.owner.id=:userId and " +
269 "f.deleted=true and f.folder.deleted=false").
270 setParameter("userId", userId).getResultList();
271 List<FileHeader> retv = new ArrayList<FileHeader>();
272 for (FileHeader f: tempList)
273 if (f.hasReadPermission(user)) retv.add(f);
279 public List<Folder> getDeletedRootFolders(Long userId) throws ObjectNotFoundException {
281 throw new ObjectNotFoundException("No User specified");
282 return manager.createQuery("select f from Folder f where f.owner.id=:userId and " +
283 "f.deleted=true and f.parent.deleted=false").
284 setParameter("userId", userId).getResultList();
288 public User findUser(String username) {
289 if (username == null)
291 List<User> results = manager.createQuery("select u from User u where u.username=:username").
292 setParameter("username", username).getResultList();
293 if (results.isEmpty()) return null;
294 return results.get(0);
298 public User findUserByEmail(String email) {
301 List<User> results = manager.createQuery("select u from User u where u.email=:email").
302 setParameter("email", email).getResultList();
303 if (results.isEmpty()) return null;
304 return results.get(0);
308 public List<User> getUsersByUserNameLike(String username) {
309 return manager.createQuery("select u from User u where u.username like :username").
310 setParameter("username", username+"%").getResultList();
314 public List<Folder> getSharedRootFolders(Long userId) {
315 List<Folder> folders = manager.createQuery("select distinct f from Folder f " +
316 "LEFT JOIN f.permissions p where f.owner.id=:userId and f.deleted=false " +
317 "and (p.group.id != null or p.user.id != f.owner.id or f.readForAll=true) ").
318 setParameter("userId", userId).getResultList();
319 List<Folder> result = new ArrayList<Folder>();
320 for(Folder f : folders)
321 if(!folders.contains(f.getParent()))
327 public List<Folder> getFoldersPermittedForGroup(Long userId, Long groupId) {
328 return manager.createQuery("select distinct f from Folder f LEFT JOIN f.permissions p " +
329 "where f.owner.id=:userId and f.deleted = false and p.group.id=:groupId ").
330 setParameter("userId", userId).setParameter("groupId", groupId).getResultList();
334 public List<User> getUsersSharingFoldersForUser(Long userId) {
335 return manager.createQuery("select distinct f.owner from Folder f " +
336 "LEFT JOIN f.permissions p where f.owner.id != :userId and f.deleted=false " +
337 "and (p.user.id=:userId or p.group.id in (select distinct gg.id " +
338 "from Group gg join gg.members memb where memb.id=:userId))) ").
339 setParameter("userId", userId).getResultList();
343 public List<User> getUsersSharingFilesForUser(Long userId) {
344 List<User> users = manager.createQuery("select distinct f.owner from FileHeader f " +
345 "LEFT JOIN f.permissions p where f.owner.id != :userId and f.deleted=false " +
346 "and (p.user.id=:userId or p.group.id in (select distinct gg.id from Group gg " +
347 "join gg.members memb where memb.id=:userId)))").
348 setParameter("userId", userId).getResultList();
354 public List<FileHeader> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException {
356 throw new ObjectNotFoundException("No user specified");
357 User user = getEntityById(User.class, userId);
358 List<FileHeader> tempList = manager.createQuery("select distinct f from FileHeader f " +
359 "LEFT JOIN f.permissions p where f.owner.id=:userId and f.deleted=false " +
360 "and (f.readForAll=true or p.group.id != null or p.user.id != f.owner.id)" +
361 " and f.folder.id not in (select distinct fo.id from Folder fo LEFT JOIN " +
362 "fo.permissions po where fo.owner.id=:userId and fo.deleted=false and " +
363 "(po.group.id != null or po.user.id != fo.owner.id or fo.readForAll = true))").
364 setParameter("userId", userId).getResultList();
365 List<FileHeader> retv = new ArrayList<FileHeader>();
366 for (FileHeader f: tempList)
367 if (f.hasReadPermission(user)) retv.add(f);
373 public List<FileHeader> getSharedFiles(Long userId) throws ObjectNotFoundException {
375 throw new ObjectNotFoundException("No user specified");
376 User user = getEntityById(User.class, userId);
377 List<FileHeader> tempList = manager.createQuery("select distinct f from FileHeader f " +
378 "LEFT JOIN f.permissions p where f.owner.id=:userId and f.deleted=false " +
379 "and (p.group.id != null or p.user.id != f.owner.id)").
380 setParameter("userId", userId).getResultList();
381 List<FileHeader> retv = new ArrayList<FileHeader>();
382 for (FileHeader f: tempList)
383 if (f.hasReadPermission(user)) retv.add(f);
389 public List<Folder> getSharedFolders(Long userId) {
390 List<Folder> folders = manager.createQuery("select distinct f from Folder f " +
391 "LEFT JOIN f.permissions p where f.owner.id=:userId and f.deleted=false " +
392 "and (p.group.id != null or p.user.id != f.owner.id)").
393 setParameter("userId", userId).getResultList();
398 public List<FileHeader> getSharedFiles(Long userId, Long callingUserId) throws ObjectNotFoundException {
400 throw new ObjectNotFoundException("No user specified");
401 User user = getEntityById(User.class, userId);
402 List<FileHeader> tempList = manager.createQuery("select distinct f from FileHeader f " +
403 "LEFT JOIN f.permissions p where f.owner.id=:userId and f.deleted=false " +
404 "and p.read=true and (p.user.id=:cuserId or p.group.id in " +
405 "(select distinct gg.id from Group gg join gg.members memb " +
406 "where memb.id=:cuserId)) and f.folder.id not in (select distinct fo.id " +
407 "from Folder fo LEFT JOIN fo.permissions po where fo.owner.id = :userId " +
408 "and fo.deleted=false and po.read=true and (po.user.id=:cuserId " +
409 "or po.group.id in (select distinct ggo.id from Group ggo " +
410 "join ggo.members membo where membo.id=:cuserId)))").
411 setParameter("userId", userId).setParameter("cuserId", callingUserId).getResultList();
412 List<FileHeader> retv = new ArrayList<FileHeader>();
413 for (FileHeader f: tempList)
414 if (f.hasReadPermission(user)) retv.add(f);
420 public List<Folder> getSharedRootFolders(Long userId, Long callingUserId) {
421 List<Folder> folders = manager.createQuery("select distinct f from Folder f " +
422 "LEFT JOIN f.permissions p where f.owner.id = :userId and f.deleted=false " +
423 "and p.read=true and (p.user.id=:cuserId or p.group.id in " +
424 "(select distinct gg.id from Group gg join gg.members memb " +
425 "where memb.id=:cuserId))) ").
426 setParameter("userId", userId).
427 setParameter("cuserId", callingUserId).
429 List<Folder> result = new ArrayList<Folder>();
430 for(Folder f : folders)
431 if(!folders.contains(f.getParent()))
438 public List<FileHeader> searchFiles(Long userId, String query) {
439 return manager.createQuery("select f from FileHeader f where f.owner.id=:userId and f.name like :query").
440 setParameter("query", "%"+query+"%").setParameter("userId",userId).getResultList();
444 public Nonce getNonce(String nonce, Long userId) throws ObjectNotFoundException {
445 List<Nonce> results = manager.createQuery("select n from Nonce n where n.userId=:userId and n.encodedNonce=:nonce").
446 setParameter("userId", userId).setParameter("nonce", nonce).getResultList();
447 if (results.isEmpty())
448 throw new ObjectNotFoundException("No nonce found");
449 return results.get(0);
453 public Long getFileCount(Long userId) {
454 Long singleResult = (Long) manager.createQuery("select count(f) from FileHeader f where f.owner.id=:ownerId")
455 .setParameter("ownerId", userId)
461 public Long getFileSize(Long userId) {
462 Long singleResult = (Long) manager.createQuery("select sum(f.fileSize) from FileBody f where f.header.owner.id=:ownerId")
463 .setParameter("ownerId", userId)
465 if(singleResult == null)
466 singleResult = new Long(0L);
472 public List<Long> getAllFileIds() {
473 List<Long> ids = manager.createQuery("select f.id from FileHeader f").getResultList();
478 public FileUploadStatus getFileUploadStatus(Long userId, String fileName) {
479 List<FileUploadStatus> res = manager.createQuery(" select f from FileUploadStatus f where f.owner.id=:userId and f.filename=:filename").setParameter("userId", userId).setParameter("filename", fileName).getResultList();
486 public FileBody getFileVersion(Long fileId, int version) throws ObjectNotFoundException {
488 return (FileBody) manager.createQuery("select f from FileBody f " +
489 "where f.header.id=:fileId and f.version=:version")
490 .setParameter("fileId", fileId).setParameter("version", version)
492 } catch (NoResultException e) {
493 throw new ObjectNotFoundException("No version " + version + " found for file #" + fileId);
498 public void updateAccounting(User user, Date date, long bandwidthDiff) {
499 AccountingInfo ai = null;
501 ai = (AccountingInfo) manager.createQuery("select ai from AccountingInfo ai " +
502 "where ai.user=:user and ai.dateFrom<=:date and ai.dateTo>:date")
503 .setParameter("user", user)
504 .setParameter("date", date)
507 catch (NoResultException e) {
512 // The right entry does not exist; must be created.
513 // This is where we set the initial time period.
514 // We now start from the user's creation, we can change this to something else.
515 Calendar creationDate = new GregorianCalendar();
516 creationDate.setTime(user.getAuditInfo().getCreationDate());
520 long timeInMillis = date.getTime();
522 dateFrom = (Calendar) creationDate.clone();
523 dateFrom.add(BANDWIDTH_TIME_PERIOD_FIELD, offset);
524 dateTo = (Calendar) dateFrom.clone();
525 dateTo.add(BANDWIDTH_TIME_PERIOD_FIELD, 1);
526 offset += BANDWIDTH_TIME_PERIOD_AMOUNT;
528 while (!(dateFrom.getTimeInMillis()<=timeInMillis && dateTo.getTimeInMillis()>timeInMillis));
530 ai = new AccountingInfo(user, dateFrom.getTime(), dateTo.getTime());
535 ai.updateBandwidth(bandwidthDiff);
539 public List<UserClass> getUserClasses() {
540 // Ordering by quota is important here.
541 List<UserClass> ids = manager.createQuery("select uc from UserClass uc order by uc.quota").getResultList();
546 public List<User> getUsersByUserNameOrEmailLike(String query) {
547 return manager.createQuery("select u from User u where " +
548 " upper(u.username) like :query or upper(u.email) like :query order by u.username").
549 setParameter("query", query.toUpperCase()+"%").getResultList();
553 public Invitation findInvite(String code) {
556 List<Invitation> results = manager.createQuery("select i from Invitation i where i.code=:code").
557 setParameter("code", code).getResultList();
558 if (results.isEmpty()) return null;
559 return results.get(0);
563 public UserClass findCouponUserClass() {
564 List<UserClass> results = manager.createQuery("select uc from UserClass uc where uc.name=:name").
565 setParameter("name", getConfiguration().getString("couponQuota")).getResultList();
566 if (results.isEmpty()) {
567 // Create the coupon user class on first use.
568 UserClass couponClass = new UserClass();
569 couponClass.setName("coupon");
570 Long couponQuota = getConfiguration().getLong("couponQuota", new Long(52428800L));
571 couponClass.setQuota(couponQuota);
574 results.add(couponClass);
576 return results.get(0);
580 public Long getFileCount(UserClass userClass) {
583 result=(Long) manager.createQuery("select count(f) from FileHeader f").getSingleResult();
584 else result= (Long) manager.createQuery("select count(f) from FileHeader f where f.owner.userClass.id=:id").setParameter("id", userClass.getId()).getSingleResult();
591 public Long getFileSize(UserClass userClass) {
594 result=(Long) manager.createQuery("select sum(f.currentBody.fileSize) from FileHeader f").getSingleResult();
595 else result=(Long) manager.createQuery("select sum(f.currentBody.fileSize) from FileHeader f where f.owner.userClass.id=:id").setParameter("id", userClass.getId()).getSingleResult();
602 public Long getUserCount(UserClass userClass) {
605 result = (Long) manager.createQuery("select count(u) from User u").getSingleResult();
606 else result = (Long) manager.createQuery("select count(u) from User u where u.userClass.id=:id").setParameter("id", userClass.getId()).getSingleResult();
613 public Long getCountUsersByLastLogin(Date lastLoginDate) {
614 return (Long) manager.createQuery("select count(u) from User u where " +
615 " u.lastLogin >= :ldate ").setParameter("ldate", lastLoginDate).getSingleResult();
619 public List<User> getUsersByLastLogin(Date lastLoginDate) {
620 return manager.createQuery("select u from User u where " +
621 " u.lastLogin >= :ldate order by u.lastLogin desc").
622 setParameter("ldate", lastLoginDate).getResultList();
626 public List<User> getUsersByLastLogin(Date lastLoginDate, int firstResult, int maxResult) {
627 return manager.createQuery("select u from User u where " +
628 " u.lastLogin >= :ldate order by u.lastLogin desc").
629 setParameter("ldate", lastLoginDate).setFirstResult(firstResult).setMaxResults(maxResult).getResultList();
633 public List<User> getInactiveUsers() {
634 return manager.createQuery("select u from User u where u.active=:active").setParameter("active", false).getResultList();
638 public List<FileHeader> searchFileByFilename(String filename) {
639 return manager.createQuery("select f from FileHeader f where f.name=:name").setParameter("name", filename).getResultList();
643 public Long getBandwithUsed(UserClass userClass, Date date) {
645 if (userClass == null)
646 result = (Long) manager.createQuery("select sum(ai.bandwidthUsed)" +
647 " from AccountingInfo ai where ai.dateFrom<=:date and " +
649 setParameter("date", date).
652 result = (Long) manager.createQuery("select sum(ai.bandwidthUsed)" +
653 " from AccountingInfo ai where ai.user.userClass.id=:id " +
654 "and ai.dateFrom<=:date and ai.dateTo>:date").
655 setParameter("date", date).
656 setParameter("id", userClass.getId()).
664 public List<AccountingInfo> getAccountingInfo(User user) {
665 List<AccountingInfo> ai = new ArrayList<AccountingInfo>();
667 ai = manager.createQuery("select ai from AccountingInfo ai " +
668 "where ai.user=:user")
669 .setParameter("user", user)
672 catch (NoResultException e) {}
677 public AccountingInfo getAccountingInfo(User user, Date date) {
678 AccountingInfo ai = null;
680 ai = (AccountingInfo) manager.createQuery("select ai from AccountingInfo ai " +
681 "where ai.user=:user and ai.dateFrom<=:date and ai.dateTo>:date")
682 .setParameter("user", user)
683 .setParameter("date", date)
686 catch (NoResultException e) {
687 // If not found, that means that there is no accounting info noted
688 // for given time. So return a 0 as an answer.
689 ai = new AccountingInfo(user, date, date);
695 public List<FileHeader> getFilesPermittedForGroup(Long userId, Long groupId) {
696 return manager.createQuery("select distinct f from FileHeader f LEFT JOIN f.permissions p " +
697 "where f.owner.id=:userId and f.deleted = false and p.group.id=:groupId ").
698 setParameter("userId", userId).setParameter("groupId", groupId).getResultList();