2 * Copyright 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 gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
22 import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
23 import gr.ebs.gss.server.domain.AccountingInfo;
24 import gr.ebs.gss.server.domain.AuditInfo;
25 import gr.ebs.gss.server.domain.FileBody;
26 import gr.ebs.gss.server.domain.FileHeader;
27 import gr.ebs.gss.server.domain.FileUploadStatus;
28 import gr.ebs.gss.server.domain.Folder;
29 import gr.ebs.gss.server.domain.Group;
30 import gr.ebs.gss.server.domain.Permission;
31 import gr.ebs.gss.server.domain.User;
32 import gr.ebs.gss.server.domain.UserClass;
33 import gr.ebs.gss.server.domain.UserLogin;
34 import gr.ebs.gss.server.domain.dto.FileBodyDTO;
35 import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
36 import gr.ebs.gss.server.domain.dto.FolderDTO;
37 import gr.ebs.gss.server.domain.dto.GroupDTO;
38 import gr.ebs.gss.server.domain.dto.PermissionDTO;
39 import gr.ebs.gss.server.domain.dto.StatsDTO;
40 import gr.ebs.gss.server.domain.dto.SystemStatsDTO;
41 import gr.ebs.gss.server.domain.dto.UserClassDTO;
42 import gr.ebs.gss.server.domain.dto.UserDTO;
44 import java.util.ArrayList;
45 import java.util.Calendar;
46 import java.util.Date;
47 import java.util.Iterator;
48 import java.util.LinkedHashSet;
49 import java.util.LinkedList;
50 import java.util.List;
52 import java.util.StringTokenizer;
55 import javax.ejb.Stateless;
56 import javax.jms.Connection;
57 import javax.jms.ConnectionFactory;
58 import javax.jms.JMSException;
59 import javax.jms.MapMessage;
60 import javax.jms.MessageProducer;
61 import javax.jms.Queue;
62 import javax.jms.QueueConnectionFactory;
63 import javax.jms.Session;
64 import javax.naming.Context;
65 import javax.naming.InitialContext;
66 import javax.naming.NamingException;
68 import org.apache.commons.lang.StringUtils;
69 import org.apache.commons.logging.Log;
70 import org.apache.commons.logging.LogFactory;
76 public class AdminAPIBean implements AdminAPI {
78 * Injected reference to the ExternalAPI service.
81 private ExternalAPI api;
86 private static Log logger = LogFactory.getLog(AdminAPIBean.class);
88 * Injected reference to the GSSDAO data access facade.
94 public FileHeaderDTO getFile(String uri) throws ObjectNotFoundException {
96 throw new ObjectNotFoundException("No uri specified");
98 List<String> pathElements = new ArrayList<String>();
99 StringTokenizer st = new StringTokenizer(uri, "/");
100 String username = st.nextToken();
102 while (st.hasMoreTokens())
103 pathElements.add(st.nextToken());
104 if (pathElements.size() < 1)
105 throw new ObjectNotFoundException("No file found");
106 User owner = dao.getUser(username);
107 // Store the last element, since it requires special handling.
108 String lastElement = pathElements.remove(pathElements.size() - 1);
109 FolderDTO cursor = api.getRootFolder(owner.getId());
110 // Traverse and verify the specified folder path.
111 for (String pathElement : pathElements) {
112 cursor = getFolder(cursor.getId(), pathElement);
113 if (cursor.isDeleted())
114 throw new ObjectNotFoundException("Folder " + cursor.getPath() + " not found");
116 FileHeaderDTO file = getFile(cursor.getId(), lastElement);
121 public List<FileHeaderDTO> getFiles(String uri) throws ObjectNotFoundException, InsufficientPermissionsException {
123 throw new ObjectNotFoundException("No uri specified");
124 List<FileHeaderDTO> res = new ArrayList<FileHeaderDTO>();
125 List<String> pathElements = new ArrayList<String>();
126 StringTokenizer st = new StringTokenizer(uri, "/");
127 if(st.countTokens()<2)
129 String username = st.nextToken();
131 User owner = dao.getUser(username);
132 while (st.hasMoreTokens())
133 pathElements.add(st.nextToken());
134 if (pathElements.size() < 1){
136 FolderDTO folder = api.getRootFolder(owner.getId());
137 res.addAll(api.getFiles(folder.getOwner().getId(), folder.getId(), false));
141 // Store the last element, since it requires special handling.
142 String lastElement = pathElements.remove(pathElements.size() - 1);
143 FolderDTO cursor = api.getRootFolder(owner.getId());
144 // Traverse and verify the specified folder path.
145 for (String pathElement : pathElements) {
146 cursor = getFolder(cursor.getId(), pathElement);
147 if (cursor.isDeleted())
148 throw new ObjectNotFoundException("Folder " + cursor.getPath() + " not found");
151 FileHeaderDTO file = getFile(cursor.getId(), lastElement);
153 } catch (ObjectNotFoundException e) {
154 // Perhaps the requested resource is not a file, so
155 // check for folders as well.
156 FolderDTO folder = getFolder(cursor.getId(), lastElement);
157 res.addAll(api.getFiles(folder.getOwner().getId(), folder.getId(), false));
164 private FolderDTO getFolder(Long parentId, String name) throws ObjectNotFoundException {
165 if (parentId == null)
166 throw new ObjectNotFoundException("No parent folder specified");
167 if (StringUtils.isEmpty(name))
168 throw new ObjectNotFoundException("No folder specified");
170 Folder folder = dao.getFolder(parentId, name);
171 return folder.getDTO();
174 private FileHeaderDTO getFile(Long folderId, String name) throws ObjectNotFoundException {
175 if (folderId == null)
176 throw new ObjectNotFoundException("No parent folder specified");
177 if (StringUtils.isEmpty(name))
178 throw new ObjectNotFoundException("No file specified");
180 FileHeader file = dao.getFile(folderId, name);
181 FileHeaderDTO dto = file.getDTO();
182 Set<Permission> perms = file.getPermissions();
183 Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
184 for (Permission perm : perms)
185 if (perm.getUser() != null && perm.getUser().getId().equals(file.getOwner().getId()))
186 result.add(perm.getDTO());
187 for (Permission perm : perms)
188 if (perm.getUser() != null && perm.getUser().getId().equals(file.getOwner().getId())) {
190 result.add(perm.getDTO());
191 dto.setPermissions(result);
195 public FileHeaderDTO getFile(Long fileId) throws ObjectNotFoundException {
196 FileHeader file = dao.getEntityById(FileHeader.class, fileId);
197 FileHeaderDTO dto = file.getDTO();
198 Set<Permission> perms = file.getPermissions();
199 Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
200 for (Permission perm : perms)
201 if (perm.getUser() != null && perm.getUser().getId().equals(file.getOwner().getId()))
202 result.add(perm.getDTO());
203 for (Permission perm : perms)
204 if (perm.getUser() != null && perm.getUser().getId().equals(file.getOwner().getId())) {
206 result.add(perm.getDTO());
207 dto.setPermissions(result);
212 public UserDTO getUser(Long userId) throws ObjectNotFoundException {
213 return api.getUserDTO(userId);
217 public StatsDTO getUserStatistics(Long userId) throws ObjectNotFoundException {
218 StatsDTO stats = api.getUserStatistics(userId);
219 User user = dao.getEntityById(User.class, userId);
220 AccountingInfo info = dao.getAccountingInfo(user, new Date());
221 stats.setBandwithQuotaUsed(info.getBandwidthUsed());
226 public List<UserDTO> searchUsers(String query) throws ObjectNotFoundException {
227 List<User> users = dao.getUsersByUserNameOrEmailLike(query);
228 List<UserDTO> result = new ArrayList<UserDTO>();
229 for (User u : users){
230 UserDTO tempDTO = u.getDTO();
231 List<UserLogin> userLogins = api.getLastUserLogins(u.getId());
232 tempDTO.setCurrentLoginDate(userLogins.get(0).getLoginDate());
233 tempDTO.setLastLoginDate(userLogins.get(1).getLoginDate());
240 public UserDTO getUser(String username) throws ObjectNotFoundException{
241 User u = dao.getUser(username);
243 UserDTO tempDTO = u.getDTO();
244 List<UserLogin> userLogins = api.getLastUserLogins(u.getId());
245 tempDTO.setCurrentLoginDate(userLogins.get(0).getLoginDate());
246 tempDTO.setLastLoginDate(userLogins.get(1).getLoginDate());
253 public void toggleActiveUser(Long userId) throws ObjectNotFoundException {
254 User user = dao.getEntityById(User.class, userId);
255 user.setActive(!user.isActive());
260 public void setFilePermissions(String uri, Set<PermissionDTO> permissions)
261 throws ObjectNotFoundException {
262 FileHeaderDTO filedto = getFile(uri);
263 FileHeader file = dao.getEntityById(FileHeader.class, filedto.getId());
264 if (permissions != null && !permissions.isEmpty()) {
265 // Send e-mails to the users that are granted new permissions on the file
266 // Delete previous entries.
267 for (Permission perm: file.getPermissions())
269 file.getPermissions().clear();
270 for (PermissionDTO dto : permissions) {
271 //if (dto.getUser()!=null && dto.getUser().getId().equals(file.getOwner().getId()) && (!dto.hasRead() || !dto.hasWrite() || !dto.hasModifyACL()))
272 //throw new InsufficientPermissionsException("Can't remove permissions from owner");
273 // Don't include 'empty' permission.
274 if (!dto.getRead() && !dto.getWrite() && !dto.getModifyACL()) continue;
275 file.addPermission(getPermission(dto));
281 private Permission getPermission(PermissionDTO dto) throws ObjectNotFoundException {
282 Permission res = new Permission();
283 if (dto.getGroup() != null)
284 res.setGroup(dao.getEntityById(Group.class, dto.getGroup().getId()));
285 else if (dto.getUser() != null)
286 if (dto.getUser().getId() == null)
287 res.setUser(dao.getUser(dto.getUser().getUsername()));
289 res.setUser(dao.getEntityById(User.class, dto.getUser().getId()));
290 res.setRead(dto.hasRead());
291 res.setWrite(dto.hasWrite());
292 res.setModifyACL(dto.hasModifyACL());
297 public SystemStatsDTO getSystemStatistics() {
298 SystemStatsDTO statistics = new SystemStatsDTO();
299 List<UserClass> uclasses = dao.getUserClasses();
300 for (UserClass u : uclasses){
301 UserClassDTO dto = u.getDTOWithoutUsers();
302 SystemStatsDTO stats = new SystemStatsDTO();
303 stats.setFileCount(dao.getFileCount(u));
304 stats.setFileSize(dao.getFileSize(u));
305 stats.setUserCount(dao.getUserCount(u));
306 stats.setBandwithUsed(dao.getBandwithUsed(u, new Date()));
307 dto.setStatistics(stats);
308 statistics.getUserClasses().add(dto);
311 Calendar now = Calendar.getInstance();
312 now.add(Calendar.DAY_OF_MONTH, -7);
313 Date week = now.getTime();
314 now=Calendar.getInstance();
315 now.add(Calendar.MONTH, -1);
316 Date month = now.getTime();
317 statistics.setLastMonthUsers(dao.getCountUsersByLastLogin(month));
318 statistics.setLastWeekUsers(dao.getCountUsersByLastLogin(week));
319 statistics.setFileCount(dao.getFileCount((UserClass)null));
320 statistics.setFileSize(dao.getFileSize((UserClass)null));
321 statistics.setUserCount(dao.getUserCount((UserClass)null));
322 statistics.setBandwithUsed(dao.getBandwithUsed(null, new Date()));
327 public List<UserDTO> getLastLoggedInUsers(Date lastLoginDate) {
328 List<User> users = dao.getUsersByLastLogin(lastLoginDate);
329 List<UserDTO> result = new ArrayList<UserDTO>();
330 for (User u : users){
331 UserDTO tempDTO = u.getDTO();
332 List<UserLogin> userLogins = dao.getLoginsForUser(u.getId());
333 tempDTO.setCurrentLoginDate(userLogins.get(0).getLoginDate());
334 tempDTO.setLastLoginDate(userLogins.get(1).getLoginDate());
341 public List<FileBodyDTO> getVersions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
343 throw new ObjectNotFoundException("No user specified");
345 throw new ObjectNotFoundException("No file specified");
346 User user = dao.getEntityById(User.class, userId);
347 FileHeader header = dao.getEntityById(FileHeader.class, fileId);
348 List<FileBodyDTO> result = new LinkedList<FileBodyDTO>();
349 for(int i = header.getBodies().size()-1 ; i>=0; i--)
350 result.add(header.getBodies().get(i).getDTO());
354 public List<UserDTO> getUsersWaitingActivation(){
355 List<User> users = dao.getInactiveUsers();
356 List<UserDTO> result = new ArrayList<UserDTO>();
358 UserDTO tempDTO = u.getDTO();
359 List<UserLogin> userLogins = dao.getLoginsForUser(u.getId());
360 tempDTO.setCurrentLoginDate(userLogins.get(0).getLoginDate());
361 tempDTO.setLastLoginDate(userLogins.get(1).getLoginDate());
369 public void changeUserClass(Long userId, Long userClassId) throws ObjectNotFoundException{
370 User user = dao.getEntityById(User.class, userId);
371 UserClass userClass = dao.getEntityById(UserClass.class, userClassId);
372 user.setUserClass(userClass);
377 public List<UserClassDTO> getUserClasses(){
378 List<UserClassDTO> result = new ArrayList<UserClassDTO>();
379 for(UserClass c : dao.getUserClasses())
380 result.add(c.getDTOWithoutUsers());
385 public void saveOrUpdateUserClass(UserClassDTO dto) throws ObjectNotFoundException{
387 if(dto.getId()!=null)
388 uclass = dao.getEntityById(UserClass.class, dto.getId());
390 uclass = new UserClass();
391 uclass.setName(dto.getName());
392 uclass.setQuota(dto.getQuota());
393 if(dto.getId()!=null)
402 public void removeUserClass(UserClassDTO dto) throws ObjectNotFoundException{
403 UserClass uclass = dao.getEntityById(UserClass.class, dto.getId());
405 throw new ObjectNotFoundException("User Class not found");
410 public List<FileHeaderDTO> searchFileByFilename(String fileName){
411 List<FileHeader> files = dao.searchFileByFilename(fileName);
412 List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
413 for(FileHeader h : files)
414 result.add(h.getDTO());
419 public void removeUser(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException{
420 User user = api.getUser(userId);
422 FolderDTO folder = api.getRootFolder(userId);
423 deleteFolder(userId, folder.getId());
424 List<GroupDTO> groups = api.getGroups(userId);
425 for(GroupDTO group : groups)
426 api.deleteGroup(userId, group.getId());
428 catch(ObjectNotFoundException e){}
429 List<Folder> otherFolders = dao.getSharingFoldersForUser(userId);
430 for(Folder f : otherFolders){
431 Iterator<Permission> pit = f.getPermissions().iterator();
432 while(pit.hasNext()){
433 Permission p = pit.next();
434 if(p.getUser()!=null&&p.getUser().getId().equals(userId)){
441 List<FileHeader> otherFiles = dao.getSharingFilesForUser(userId);
442 for(FileHeader f : otherFiles){
443 Iterator<Permission> pit = f.getPermissions().iterator();
444 while(pit.hasNext()){
445 Permission p = pit.next();
446 if(p.getUser()!=null&&p.getUser().getId().equals(userId)){
453 List<Group> otherGroups = dao.getGroupsContainingUser(userId);
454 for(Group g : otherGroups){
455 Iterator<User> uit = g.getMembers().iterator();
456 while(uit.hasNext()){
458 if(u.getId().equals(userId)){
464 List<AccountingInfo> infos = dao.getAccountingInfo(user);
465 Iterator<AccountingInfo> it = infos.iterator();
467 AccountingInfo a = it.next();
470 List<FileUploadStatus> sts = dao.getUploadStatus(userId);
471 for(FileUploadStatus s : sts)
473 int deleteCount=dao.deletePermissionsNotCorrespondingToFilesAndFolders(userId);
475 List<UserLogin> allUserLogins = dao.getAllLoginsForUser(userId);
476 for(UserLogin ul : allUserLogins)
483 * Deletes the given folder and all its subfolders and files
484 * Only the permissions for top folder are checked
486 * @see gr.ebs.gss.server.ejb.ExternalAPI#deleteFolder(java.lang.Long,
489 public void deleteFolder(final Long userId, final Long folderId) throws ObjectNotFoundException {
492 throw new ObjectNotFoundException("No user specified");
493 if (folderId == null)
494 throw new ObjectNotFoundException("No folder specified");
496 // Do the actual work.
497 final Folder folder = dao.getEntityById(Folder.class, folderId);
498 final Folder parent = folder.getParent();
499 final User user = dao.getEntityById(User.class, userId);
501 removeSubfolderFiles(folder);
503 parent.removeSubfolder(folder);
506 touchParentFolders(parent, user, new Date());
509 private void removeSubfolderFiles(Folder folder) {
510 //remove files for all subfolders
511 for (Folder subfolder:folder.getSubfolders())
512 removeSubfolderFiles(subfolder);
513 //remove this folder's file bodies (actual files)
514 for (FileHeader file:folder.getFiles()) {
515 for (FileBody body:file.getBodies())
516 api.deleteActualFile(body.getStoredFilePath());
517 indexFile(file.getId(), true);
521 private void touchParentFolders(Folder folder, User modifiedBy, Date modificationDate) {
524 AuditInfo ai = f.getAuditInfo();
525 ai.setModifiedBy(modifiedBy);
526 ai.setModificationDate(modificationDate);
532 public void indexFile(Long fileId, boolean delete) {
533 Connection qConn = null;
534 Session session = null;
535 MessageProducer sender = null;
537 Context jndiCtx = new InitialContext();
538 ConnectionFactory factory = (QueueConnectionFactory) jndiCtx.lookup("java:/JmsXA");
539 Queue queue = (Queue) jndiCtx.lookup("queue/gss-indexingQueue");
540 qConn = factory.createConnection();
541 session = qConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
542 sender = session.createProducer(queue);
544 MapMessage map = session.createMapMessage();
545 map.setObject("id", fileId);
546 map.setBoolean("delete", delete);
549 catch (NamingException e) {
550 logger.error("Index was not updated: ", e);
552 catch (JMSException e) {
553 logger.error("Index was not updated: ", e);
564 catch (JMSException e) {