Statistics
| Branch: | Tag: | Revision:

root / src / gr / ebs / gss / server / ejb / ExternalAPIBean.java @ 01a30cd0

History | View | Annotate | Download (100.9 kB)

1 14ad7326 pastith
/*
2 14ad7326 pastith
 * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
3 14ad7326 pastith
 *
4 14ad7326 pastith
 * This file is part of GSS.
5 14ad7326 pastith
 *
6 14ad7326 pastith
 * GSS is free software: you can redistribute it and/or modify
7 14ad7326 pastith
 * it under the terms of the GNU General Public License as published by
8 14ad7326 pastith
 * the Free Software Foundation, either version 3 of the License, or
9 14ad7326 pastith
 * (at your option) any later version.
10 14ad7326 pastith
 *
11 14ad7326 pastith
 * GSS is distributed in the hope that it will be useful,
12 14ad7326 pastith
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 14ad7326 pastith
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 14ad7326 pastith
 * GNU General Public License for more details.
15 14ad7326 pastith
 *
16 14ad7326 pastith
 * You should have received a copy of the GNU General Public License
17 14ad7326 pastith
 * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18 14ad7326 pastith
 */
19 14ad7326 pastith
package gr.ebs.gss.server.ejb;
20 14ad7326 pastith
21 bde4eafb pastith
import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
22 14ad7326 pastith
import gr.ebs.gss.client.exceptions.DuplicateNameException;
23 14ad7326 pastith
import gr.ebs.gss.client.exceptions.GSSIOException;
24 14ad7326 pastith
import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
25 01a30cd0 Panagiotis Astithas
import gr.ebs.gss.client.exceptions.InvitationUsedException;
26 14ad7326 pastith
import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
27 14ad7326 pastith
import gr.ebs.gss.client.exceptions.QuotaExceededException;
28 14ad7326 pastith
import gr.ebs.gss.server.domain.AuditInfo;
29 14ad7326 pastith
import gr.ebs.gss.server.domain.FileBody;
30 14ad7326 pastith
import gr.ebs.gss.server.domain.FileHeader;
31 14ad7326 pastith
import gr.ebs.gss.server.domain.FileTag;
32 14ad7326 pastith
import gr.ebs.gss.server.domain.FileUploadStatus;
33 14ad7326 pastith
import gr.ebs.gss.server.domain.Folder;
34 14ad7326 pastith
import gr.ebs.gss.server.domain.Group;
35 2f551abc Panagiotis Astithas
import gr.ebs.gss.server.domain.Invitation;
36 14ad7326 pastith
import gr.ebs.gss.server.domain.Nonce;
37 14ad7326 pastith
import gr.ebs.gss.server.domain.Permission;
38 14ad7326 pastith
import gr.ebs.gss.server.domain.User;
39 01a30cd0 Panagiotis Astithas
import gr.ebs.gss.server.domain.UserClass;
40 2f2da9c7 pastith
import gr.ebs.gss.server.domain.dto.FileBodyDTO;
41 2f2da9c7 pastith
import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
42 2f2da9c7 pastith
import gr.ebs.gss.server.domain.dto.FolderDTO;
43 2f2da9c7 pastith
import gr.ebs.gss.server.domain.dto.GroupDTO;
44 2f2da9c7 pastith
import gr.ebs.gss.server.domain.dto.PermissionDTO;
45 2f2da9c7 pastith
import gr.ebs.gss.server.domain.dto.StatsDTO;
46 2f2da9c7 pastith
import gr.ebs.gss.server.domain.dto.UserDTO;
47 14ad7326 pastith
48 14ad7326 pastith
import java.io.File;
49 14ad7326 pastith
import java.io.FileInputStream;
50 14ad7326 pastith
import java.io.FileNotFoundException;
51 14ad7326 pastith
import java.io.FileOutputStream;
52 14ad7326 pastith
import java.io.IOException;
53 14ad7326 pastith
import java.io.InputStream;
54 14ad7326 pastith
import java.io.StringWriter;
55 14ad7326 pastith
import java.io.UnsupportedEncodingException;
56 14ad7326 pastith
import java.util.ArrayList;
57 14ad7326 pastith
import java.util.Date;
58 14ad7326 pastith
import java.util.Iterator;
59 14ad7326 pastith
import java.util.LinkedHashSet;
60 14ad7326 pastith
import java.util.LinkedList;
61 14ad7326 pastith
import java.util.List;
62 f3f7bdf3 Fotis Stamatelopoulos
import java.util.Locale;
63 14ad7326 pastith
import java.util.Random;
64 14ad7326 pastith
import java.util.Set;
65 14ad7326 pastith
import java.util.StringTokenizer;
66 14ad7326 pastith
67 14ad7326 pastith
import javax.ejb.EJB;
68 14ad7326 pastith
import javax.ejb.EJBException;
69 65e0a745 Dimitris Routsis
import javax.ejb.EJBTransactionRolledbackException;
70 14ad7326 pastith
import javax.ejb.Stateless;
71 14ad7326 pastith
import javax.ejb.TransactionAttribute;
72 14ad7326 pastith
import javax.ejb.TransactionAttributeType;
73 14ad7326 pastith
import javax.jms.Connection;
74 14ad7326 pastith
import javax.jms.ConnectionFactory;
75 14ad7326 pastith
import javax.jms.JMSException;
76 14ad7326 pastith
import javax.jms.MapMessage;
77 14ad7326 pastith
import javax.jms.MessageProducer;
78 14ad7326 pastith
import javax.jms.Queue;
79 14ad7326 pastith
import javax.jms.QueueConnectionFactory;
80 14ad7326 pastith
import javax.jms.Session;
81 14ad7326 pastith
import javax.naming.Context;
82 14ad7326 pastith
import javax.naming.InitialContext;
83 14ad7326 pastith
import javax.naming.NamingException;
84 65e0a745 Dimitris Routsis
import javax.persistence.PersistenceException;
85 14ad7326 pastith
import javax.xml.parsers.DocumentBuilder;
86 14ad7326 pastith
import javax.xml.parsers.DocumentBuilderFactory;
87 14ad7326 pastith
import javax.xml.parsers.ParserConfigurationException;
88 14ad7326 pastith
import javax.xml.transform.OutputKeys;
89 14ad7326 pastith
import javax.xml.transform.Transformer;
90 14ad7326 pastith
import javax.xml.transform.TransformerConfigurationException;
91 14ad7326 pastith
import javax.xml.transform.TransformerException;
92 14ad7326 pastith
import javax.xml.transform.TransformerFactory;
93 14ad7326 pastith
import javax.xml.transform.dom.DOMSource;
94 14ad7326 pastith
import javax.xml.transform.stream.StreamResult;
95 14ad7326 pastith
96 14ad7326 pastith
import org.apache.commons.httpclient.HttpClient;
97 14ad7326 pastith
import org.apache.commons.httpclient.HttpException;
98 14ad7326 pastith
import org.apache.commons.httpclient.NameValuePair;
99 14ad7326 pastith
import org.apache.commons.httpclient.methods.GetMethod;
100 14ad7326 pastith
import org.apache.commons.httpclient.methods.PostMethod;
101 14ad7326 pastith
import org.apache.commons.httpclient.methods.StringRequestEntity;
102 14ad7326 pastith
import org.apache.commons.lang.StringUtils;
103 14ad7326 pastith
import org.apache.commons.logging.Log;
104 14ad7326 pastith
import org.apache.commons.logging.LogFactory;
105 65e0a745 Dimitris Routsis
import org.hibernate.exception.ConstraintViolationException;
106 14ad7326 pastith
import org.w3c.dom.DOMException;
107 14ad7326 pastith
import org.w3c.dom.Document;
108 14ad7326 pastith
import org.w3c.dom.Node;
109 14ad7326 pastith
import org.w3c.dom.NodeList;
110 14ad7326 pastith
import org.xml.sax.SAXException;
111 14ad7326 pastith
112 3f6fd106 Panagiotis Astithas
import com.novell.ldap.LDAPAttribute;
113 3f6fd106 Panagiotis Astithas
import com.novell.ldap.LDAPAttributeSet;
114 3f6fd106 Panagiotis Astithas
import com.novell.ldap.LDAPConnection;
115 3f6fd106 Panagiotis Astithas
import com.novell.ldap.LDAPEntry;
116 3f6fd106 Panagiotis Astithas
import com.novell.ldap.LDAPException;
117 3f6fd106 Panagiotis Astithas
118 14ad7326 pastith
/**
119 14ad7326 pastith
 * The concrete implementation of the ExternalAPI interface.
120 14ad7326 pastith
 *
121 14ad7326 pastith
 * @author past
122 14ad7326 pastith
 */
123 14ad7326 pastith
@Stateless
124 14ad7326 pastith
public class ExternalAPIBean implements ExternalAPI, ExternalAPIRemote {
125 14ad7326 pastith
        /**
126 14ad7326 pastith
         * The default MIME type for files without an explicit one.
127 14ad7326 pastith
         */
128 14ad7326 pastith
        private static final String DEFAULT_MIME_TYPE = "application/octet-stream";
129 14ad7326 pastith
130 14ad7326 pastith
        /**
131 14ad7326 pastith
         * The size of the buffer that is used to temporarily store chunks of
132 14ad7326 pastith
         * uploaded files, while storing them to the file repository.
133 14ad7326 pastith
         */
134 14ad7326 pastith
        private static final int UPLOAD_BUFFER_SIZE = 1024 * 4;
135 14ad7326 pastith
136 14ad7326 pastith
        /**
137 14ad7326 pastith
         * The logger.
138 14ad7326 pastith
         */
139 14ad7326 pastith
        private static Log logger = LogFactory.getLog(ExternalAPIBean.class);
140 14ad7326 pastith
141 14ad7326 pastith
        /**
142 14ad7326 pastith
         * Injected reference to the GSSDAO data access facade.
143 14ad7326 pastith
         */
144 14ad7326 pastith
        @EJB
145 14ad7326 pastith
        private GSSDAO dao;
146 14ad7326 pastith
147 09051786 droutsis
148 14ad7326 pastith
        /**
149 14ad7326 pastith
         * A cached random number generator for creating unique filenames.
150 14ad7326 pastith
         */
151 14ad7326 pastith
        private static Random random = new Random();
152 14ad7326 pastith
153 f1052f48 Panagiotis Astithas
        /**
154 f1052f48 Panagiotis Astithas
         * Mark the folder and all of its parent folders as modified from the specified user.
155 f1052f48 Panagiotis Astithas
         */
156 f1052f48 Panagiotis Astithas
        private void touchParentFolders(Folder folder, User user, Date date) {
157 f22e4d5d Dimitris Routsis
                Folder f = folder;
158 f1052f48 Panagiotis Astithas
                while (f != null) {
159 f22e4d5d Dimitris Routsis
                        AuditInfo ai = f.getAuditInfo();
160 f1052f48 Panagiotis Astithas
                        ai.setModifiedBy(user);
161 f1052f48 Panagiotis Astithas
                        ai.setModificationDate(date);
162 f22e4d5d Dimitris Routsis
                        f.setAuditInfo(ai);
163 f22e4d5d Dimitris Routsis
                        f = f.getParent();
164 f22e4d5d Dimitris Routsis
                }
165 f22e4d5d Dimitris Routsis
        }
166 f22e4d5d Dimitris Routsis
167 68410d59 pastith
        @Override
168 68410d59 pastith
        public FolderDTO getRootFolder(Long userId) throws ObjectNotFoundException {
169 14ad7326 pastith
                if (userId == null)
170 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
171 68410d59 pastith
                Folder folder = dao.getRootFolder(userId);
172 14ad7326 pastith
                return folder.getDTO();
173 14ad7326 pastith
        }
174 14ad7326 pastith
175 f1052f48 Panagiotis Astithas
        @Override
176 14ad7326 pastith
        public FolderDTO getFolder(final Long userId, final Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
177 14ad7326 pastith
                if (userId == null)
178 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
179 14ad7326 pastith
                if (folderId == null)
180 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
181 14ad7326 pastith
                final User user = dao.getEntityById(User.class, userId);
182 14ad7326 pastith
                final Folder folder = dao.getEntityById(Folder.class, folderId);
183 14ad7326 pastith
                // Check permissions
184 14ad7326 pastith
                if (!folder.hasReadPermission(user))
185 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
186 14ad7326 pastith
                return folder.getDTO();
187 14ad7326 pastith
        }
188 14ad7326 pastith
189 14ad7326 pastith
        /* (non-Javadoc)
190 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getUser(java.lang.Long)
191 14ad7326 pastith
         */
192 14ad7326 pastith
        public User getUser(Long userId) throws ObjectNotFoundException {
193 14ad7326 pastith
                if (userId == null)
194 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
195 14ad7326 pastith
                return dao.getEntityById(User.class, userId);
196 14ad7326 pastith
        }
197 14ad7326 pastith
198 14ad7326 pastith
        /* (non-Javadoc)
199 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getUserDTO(java.lang.Long)
200 14ad7326 pastith
         */
201 14ad7326 pastith
        public UserDTO getUserDTO(final Long userId) throws ObjectNotFoundException {
202 14ad7326 pastith
                return getUser(userId).getDTO();
203 14ad7326 pastith
        }
204 14ad7326 pastith
205 14ad7326 pastith
        /*
206 14ad7326 pastith
         * (non-Javadoc)
207 14ad7326 pastith
         *
208 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getGroup(java.lang.Long)
209 14ad7326 pastith
         */
210 14ad7326 pastith
        public GroupDTO getGroup(final Long groupId) throws ObjectNotFoundException {
211 14ad7326 pastith
                if (groupId == null)
212 14ad7326 pastith
                        throw new ObjectNotFoundException("No group specified");
213 14ad7326 pastith
                final Group group = dao.getEntityById(Group.class, groupId);
214 14ad7326 pastith
                return group.getDTO();
215 14ad7326 pastith
        }
216 14ad7326 pastith
217 14ad7326 pastith
        @Override
218 14ad7326 pastith
        public GroupDTO getGroup(Long userId, String name) throws ObjectNotFoundException {
219 14ad7326 pastith
                if (userId == null)
220 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
221 14ad7326 pastith
                if (name == null)
222 14ad7326 pastith
                        throw new ObjectNotFoundException("No group specified");
223 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
224 14ad7326 pastith
                List<Group> groups = user.getGroupsSpecified();
225 14ad7326 pastith
                for (Group group: groups)
226 14ad7326 pastith
                        if (group.getName().equals(name))
227 14ad7326 pastith
                                return group.getDTO();
228 14ad7326 pastith
                throw new ObjectNotFoundException("Group " + name + " not found");
229 14ad7326 pastith
        }
230 14ad7326 pastith
231 14ad7326 pastith
        /*
232 14ad7326 pastith
         * (non-Javadoc)
233 14ad7326 pastith
         *
234 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getGroups(java.lang.Long)
235 14ad7326 pastith
         */
236 14ad7326 pastith
        public List<GroupDTO> getGroups(final Long userId) throws ObjectNotFoundException {
237 14ad7326 pastith
                if (userId == null)
238 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
239 14ad7326 pastith
                final List<Group> groups = dao.getGroups(userId);
240 14ad7326 pastith
                final List<GroupDTO> result = new ArrayList<GroupDTO>();
241 14ad7326 pastith
                for (final Group g : groups)
242 14ad7326 pastith
                        result.add(g.getDTO());
243 14ad7326 pastith
                return result;
244 14ad7326 pastith
        }
245 14ad7326 pastith
246 14ad7326 pastith
        @Override
247 3d1b9329 koutsoub
        public List<FileHeaderDTO> getFiles(Long userId, Long folderId, boolean ignoreDeleted)
248 14ad7326 pastith
                        throws ObjectNotFoundException, InsufficientPermissionsException {
249 14ad7326 pastith
                // Validate.
250 14ad7326 pastith
                if (userId == null)
251 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
252 14ad7326 pastith
                if (folderId == null)
253 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
254 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
255 14ad7326 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
256 14ad7326 pastith
                if (!folder.hasReadPermission(user))
257 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
258 14ad7326 pastith
                // Do the actual work.
259 14ad7326 pastith
                List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
260 cc154eca droutsis
                List<FileHeader> files = dao.getFiles(folderId, userId, ignoreDeleted);
261 14ad7326 pastith
                for (FileHeader f : files)
262 14ad7326 pastith
                        result.add(f.getDTO());
263 14ad7326 pastith
                return result;
264 14ad7326 pastith
        }
265 14ad7326 pastith
266 14ad7326 pastith
        /*
267 14ad7326 pastith
         * (non-Javadoc)
268 14ad7326 pastith
         *
269 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getUsers(java.lang.Long,
270 14ad7326 pastith
         *      java.lang.Long)
271 14ad7326 pastith
         */
272 14ad7326 pastith
        public List<UserDTO> getUsers(final Long userId, final Long groupId) throws ObjectNotFoundException {
273 14ad7326 pastith
                // Validate.
274 14ad7326 pastith
                if (userId == null)
275 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
276 14ad7326 pastith
                if (groupId == null)
277 14ad7326 pastith
                        throw new ObjectNotFoundException("No group specified");
278 14ad7326 pastith
279 14ad7326 pastith
                // Do the actual work.
280 14ad7326 pastith
                final List<User> users = dao.getUsers(groupId);
281 14ad7326 pastith
                final List<UserDTO> result = new ArrayList<UserDTO>();
282 14ad7326 pastith
                for (final User u : users)
283 14ad7326 pastith
                        result.add(u.getDTO());
284 14ad7326 pastith
                return result;
285 14ad7326 pastith
        }
286 14ad7326 pastith
287 14ad7326 pastith
        @Override
288 a0dde818 Panagiotis Astithas
        public FolderDTO createFolder(Long userId, Long parentId, String name)
289 14ad7326 pastith
                        throws DuplicateNameException, ObjectNotFoundException, InsufficientPermissionsException {
290 14ad7326 pastith
                // Validate.
291 14ad7326 pastith
                if (userId == null)
292 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
293 14ad7326 pastith
                if (StringUtils.isEmpty(name))
294 14ad7326 pastith
                        throw new ObjectNotFoundException("New folder name is empty");
295 14ad7326 pastith
                if (parentId == null)
296 14ad7326 pastith
                        throw new ObjectNotFoundException("No parent specified");
297 14ad7326 pastith
                if (dao.existsFolderOrFile(parentId, name))
298 14ad7326 pastith
                        throw new DuplicateNameException("A folder or file with the name '" +
299 14ad7326 pastith
                                                name + "' already exists at this level");
300 14ad7326 pastith
301 14ad7326 pastith
                User creator = dao.getEntityById(User.class, userId);
302 14ad7326 pastith
303 14ad7326 pastith
                Folder parent = null;
304 14ad7326 pastith
                try {
305 14ad7326 pastith
                        parent = dao.getEntityById(Folder.class, parentId);
306 14ad7326 pastith
                } catch (ObjectNotFoundException onfe) {
307 14ad7326 pastith
                        // Supply a more accurate problem description.
308 14ad7326 pastith
                        throw new ObjectNotFoundException("Parent folder not found");
309 14ad7326 pastith
                }
310 14ad7326 pastith
                if (!parent.hasWritePermission(creator))
311 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the permissions" +
312 14ad7326 pastith
                                        " to write to this folder");
313 14ad7326 pastith
314 14ad7326 pastith
                // Do the actual work.
315 a0dde818 Panagiotis Astithas
                return createFolder(name, parent, creator);
316 14ad7326 pastith
        }
317 14ad7326 pastith
318 14ad7326 pastith
        /**
319 14ad7326 pastith
         * Create a new folder with the provided name, parent and owner.
320 14ad7326 pastith
         *
321 14ad7326 pastith
         * @param name
322 14ad7326 pastith
         * @param parent
323 14ad7326 pastith
         * @param creator
324 a0dde818 Panagiotis Astithas
         * @return the new folder
325 14ad7326 pastith
         */
326 a0dde818 Panagiotis Astithas
        private FolderDTO createFolder(String name, Folder parent, User creator) {
327 14ad7326 pastith
                Folder folder = new Folder();
328 14ad7326 pastith
                folder.setName(name);
329 14ad7326 pastith
                if (parent != null) {
330 14ad7326 pastith
                        parent.addSubfolder(folder);
331 14ad7326 pastith
                        folder.setOwner(parent.getOwner());
332 14ad7326 pastith
                } else
333 14ad7326 pastith
                        folder.setOwner(creator);
334 14ad7326 pastith
335 14ad7326 pastith
                Date now = new Date();
336 14ad7326 pastith
                AuditInfo auditInfo = new AuditInfo();
337 14ad7326 pastith
                auditInfo.setCreatedBy(creator);
338 14ad7326 pastith
                auditInfo.setCreationDate(now);
339 14ad7326 pastith
                auditInfo.setModifiedBy(creator);
340 14ad7326 pastith
                auditInfo.setModificationDate(now);
341 14ad7326 pastith
                folder.setAuditInfo(auditInfo);
342 f22e4d5d Dimitris Routsis
                touchParentFolders(folder, auditInfo.getModifiedBy(), auditInfo.getModificationDate());
343 14ad7326 pastith
344 14ad7326 pastith
                if (parent != null)
345 14ad7326 pastith
                        for (Permission p : parent.getPermissions()) {
346 14ad7326 pastith
                                Permission permission = new Permission();
347 14ad7326 pastith
                                permission.setGroup(p.getGroup());
348 14ad7326 pastith
                                permission.setUser(p.getUser());
349 14ad7326 pastith
                                permission.setRead(p.getRead());
350 14ad7326 pastith
                                permission.setWrite(p.getWrite());
351 14ad7326 pastith
                                permission.setModifyACL(p.getModifyACL());
352 14ad7326 pastith
                                folder.addPermission(permission);
353 14ad7326 pastith
                        }
354 14ad7326 pastith
                else {
355 14ad7326 pastith
                        Permission permission = new Permission();
356 14ad7326 pastith
                        permission.setUser(creator);
357 14ad7326 pastith
                        permission.setRead(true);
358 14ad7326 pastith
                        permission.setWrite(true);
359 14ad7326 pastith
                        permission.setModifyACL(true);
360 14ad7326 pastith
                        folder.addPermission(permission);
361 14ad7326 pastith
                }
362 14ad7326 pastith
                dao.create(folder);
363 a0dde818 Panagiotis Astithas
                return folder.getDTO();
364 14ad7326 pastith
        }
365 14ad7326 pastith
366 14ad7326 pastith
        /*
367 4d737770 Fotis Stamatelopoulos
         * Deletes the given folder and all its subfolders and files
368 4d737770 Fotis Stamatelopoulos
         * Only the permissions for top folder are checked
369 14ad7326 pastith
         *
370 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#deleteFolder(java.lang.Long,
371 14ad7326 pastith
         *      java.lang.Long)
372 14ad7326 pastith
         */
373 14ad7326 pastith
        public void deleteFolder(final Long userId, final Long folderId) throws InsufficientPermissionsException, ObjectNotFoundException {
374 14ad7326 pastith
                // Validate.
375 14ad7326 pastith
                if (userId == null)
376 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
377 14ad7326 pastith
                if (folderId == null)
378 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
379 14ad7326 pastith
380 14ad7326 pastith
                // Do the actual work.
381 14ad7326 pastith
                final Folder folder = dao.getEntityById(Folder.class, folderId);
382 14ad7326 pastith
                final Folder parent = folder.getParent();
383 14ad7326 pastith
                if (parent == null)
384 14ad7326 pastith
                        throw new ObjectNotFoundException("Deleting the root folder is not allowed");
385 14ad7326 pastith
                final User user = dao.getEntityById(User.class, userId);
386 14ad7326 pastith
                if (!folder.hasDeletePermission(user)) {
387 14ad7326 pastith
                        logger.info("User " + user.getId() + " cannot delete folder " + folder.getName() + "(" + folder.getId() + ")");
388 14ad7326 pastith
                        throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete folder " + folder.getName() + "(" + folder.getId() + ")");
389 14ad7326 pastith
                }
390 4d737770 Fotis Stamatelopoulos
                removeSubfolderFiles(folder);
391 14ad7326 pastith
                parent.removeSubfolder(folder);
392 14ad7326 pastith
                dao.delete(folder);
393 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, user, new Date());
394 14ad7326 pastith
        }
395 14ad7326 pastith
396 4d737770 Fotis Stamatelopoulos
        /**
397 4d737770 Fotis Stamatelopoulos
         * Traverses the folder and deletes all actual files (file system)
398 4d737770 Fotis Stamatelopoulos
         * regardless of permissions
399 4d737770 Fotis Stamatelopoulos
         *
400 4d737770 Fotis Stamatelopoulos
         * @param folder
401 4d737770 Fotis Stamatelopoulos
         */
402 4d737770 Fotis Stamatelopoulos
        private void removeSubfolderFiles(Folder folder) {
403 4d737770 Fotis Stamatelopoulos
                //remove files for all subfolders
404 4d737770 Fotis Stamatelopoulos
                for (Folder subfolder:folder.getSubfolders())
405 4d737770 Fotis Stamatelopoulos
                        removeSubfolderFiles(subfolder);
406 4d737770 Fotis Stamatelopoulos
                //remove this folder's file bodies (actual files)
407 4d737770 Fotis Stamatelopoulos
                for (FileHeader file:folder.getFiles()) {
408 4d737770 Fotis Stamatelopoulos
                        for (FileBody body:file.getBodies())
409 4d737770 Fotis Stamatelopoulos
                                deleteActualFile(body.getStoredFilePath());
410 4d737770 Fotis Stamatelopoulos
                        indexFile(file.getId(), true);
411 4d737770 Fotis Stamatelopoulos
                }
412 4d737770 Fotis Stamatelopoulos
        }
413 4d737770 Fotis Stamatelopoulos
414 14ad7326 pastith
        @SuppressWarnings("unchecked")
415 68410d59 pastith
        public List<FolderDTO> getSubfolders(Long userId, Long folderId)
416 68410d59 pastith
                        throws ObjectNotFoundException, InsufficientPermissionsException {
417 14ad7326 pastith
                if (userId == null)
418 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
419 14ad7326 pastith
                if (folderId == null)
420 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
421 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
422 14ad7326 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
423 14ad7326 pastith
                if (!folder.hasReadPermission(user))
424 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
425 14ad7326 pastith
                List<FolderDTO> result = new ArrayList<FolderDTO>();
426 14ad7326 pastith
                if (folder.hasReadPermission(user))
427 14ad7326 pastith
                        for (Folder f : folder.getSubfolders())
428 14ad7326 pastith
                                if (f.hasReadPermission(user) && !f.isDeleted())
429 14ad7326 pastith
                                        result.add(f.getDTO());
430 14ad7326 pastith
                return result;
431 14ad7326 pastith
        }
432 14ad7326 pastith
433 afdfbc24 pastith
        @Override
434 ba5f9575 Panagiotis Astithas
        public FolderDTO updateFolder(Long userId, Long folderId, String folderName,
435 ba5f9575 Panagiotis Astithas
                                Set<PermissionDTO> permissions)
436 ba5f9575 Panagiotis Astithas
                        throws InsufficientPermissionsException, ObjectNotFoundException,
437 ba5f9575 Panagiotis Astithas
                        DuplicateNameException {
438 14ad7326 pastith
439 14ad7326 pastith
                // Validate.
440 14ad7326 pastith
                if (userId == null)
441 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
442 14ad7326 pastith
                if (folderId == null)
443 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
444 afdfbc24 pastith
445 afdfbc24 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
446 afdfbc24 pastith
                User user = dao.getEntityById(User.class, userId);
447 ba5f9575 Panagiotis Astithas
                if (folderName != null && !folder.hasWritePermission(user))
448 ba5f9575 Panagiotis Astithas
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
449 ba5f9575 Panagiotis Astithas
                if(permissions != null && !permissions.isEmpty() && !folder.hasModifyACLPermission(user))
450 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
451 afdfbc24 pastith
452 afdfbc24 pastith
                Folder parent = folder.getParent();
453 ba5f9575 Panagiotis Astithas
                if (folderName != null) {
454 ba5f9575 Panagiotis Astithas
                        if (parent != null)
455 ba5f9575 Panagiotis Astithas
                                if (!folder.getName().equals(folderName) && dao.existsFolderOrFile(parent.getId(), folderName))
456 ba5f9575 Panagiotis Astithas
                                        throw new DuplicateNameException("A folder or file with the name '" + folderName + "' already exists at this level");
457 ba5f9575 Panagiotis Astithas
458 ba5f9575 Panagiotis Astithas
                        // Do the actual modification.
459 ba5f9575 Panagiotis Astithas
                        folder.setName(folderName);
460 ba5f9575 Panagiotis Astithas
                }
461 ba5f9575 Panagiotis Astithas
                if (permissions != null)
462 ba5f9575 Panagiotis Astithas
                        setFolderPermissions(user, folder, permissions);
463 14ad7326 pastith
464 ba5f9575 Panagiotis Astithas
                folder.getAuditInfo().setModificationDate(new Date());
465 ba5f9575 Panagiotis Astithas
                folder.getAuditInfo().setModifiedBy(user);
466 14ad7326 pastith
                dao.update(folder);
467 f22e4d5d Dimitris Routsis
                touchParentFolders(folder, user, new Date());
468 77dcb3f1 Panagiotis Astithas
                return folder.getDTO();
469 14ad7326 pastith
        }
470 14ad7326 pastith
471 14ad7326 pastith
        /*
472 14ad7326 pastith
         * (non-Javadoc)
473 14ad7326 pastith
         *
474 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#createGroup(java.lang.Long,
475 14ad7326 pastith
         *      java.lang.String)
476 14ad7326 pastith
         */
477 14ad7326 pastith
        public void createGroup(final Long userId, final String name) throws ObjectNotFoundException, DuplicateNameException {
478 14ad7326 pastith
                // Validate.
479 14ad7326 pastith
                if (userId == null)
480 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
481 14ad7326 pastith
                if (StringUtils.isEmpty(name))
482 14ad7326 pastith
                        throw new ObjectNotFoundException("New group name is empty");
483 c25c6507 Dimitris Routsis
                if (name.indexOf('/')>=0)
484 c25c6507 Dimitris Routsis
                        throw new IllegalArgumentException("Character '/' is not allowed in group name");
485 14ad7326 pastith
                if (dao.existsGroup(userId, name))
486 14ad7326 pastith
                        throw new DuplicateNameException("A group with the name '" + name + "' already exists");
487 14ad7326 pastith
488 14ad7326 pastith
                // TODO: Check permissions
489 14ad7326 pastith
490 14ad7326 pastith
                final User owner = dao.getEntityById(User.class, userId);
491 14ad7326 pastith
492 14ad7326 pastith
                // Do the actual work.
493 14ad7326 pastith
                owner.createGroup(name);
494 14ad7326 pastith
        }
495 14ad7326 pastith
496 14ad7326 pastith
        /*
497 14ad7326 pastith
         * (non-Javadoc)
498 14ad7326 pastith
         *
499 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#deleteGroup(java.lang.Long,
500 14ad7326 pastith
         *      java.lang.Long)
501 14ad7326 pastith
         */
502 14ad7326 pastith
        public void deleteGroup(final Long userId, final Long groupId) throws ObjectNotFoundException, InsufficientPermissionsException {
503 14ad7326 pastith
                // Validate.
504 14ad7326 pastith
                if (userId == null)
505 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
506 14ad7326 pastith
                if (groupId == null)
507 14ad7326 pastith
                        throw new ObjectNotFoundException("No group specified");
508 14ad7326 pastith
509 14ad7326 pastith
                // Do the actual work.
510 14ad7326 pastith
                final User owner = dao.getEntityById(User.class, userId);
511 14ad7326 pastith
                final Group group = dao.getEntityById(Group.class, groupId);
512 14ad7326 pastith
                // Only delete the group if actually owned by the user.
513 14ad7326 pastith
                if (group.getOwner().equals(owner)) {
514 14ad7326 pastith
                        List<Folder> folders = dao.getFoldersPermittedForGroup(userId, groupId);
515 14ad7326 pastith
                        for (Folder f : folders){
516 14ad7326 pastith
                                f.getPermissions().removeAll(group.getPermissions());
517 14ad7326 pastith
                                for(FileHeader file : f.getFiles())
518 14ad7326 pastith
                                        file.getPermissions().removeAll(group.getPermissions());
519 14ad7326 pastith
                        }
520 14ad7326 pastith
                        List<FileHeader> files = dao.getSharedFilesNotInSharedFolders(userId);
521 14ad7326 pastith
                        for(FileHeader h : files)
522 14ad7326 pastith
                                h.getPermissions().removeAll(group.getPermissions());
523 14ad7326 pastith
                        owner.removeSpecifiedGroup(group);
524 14ad7326 pastith
                        dao.delete(group);
525 14ad7326 pastith
                }
526 14ad7326 pastith
                else throw new InsufficientPermissionsException("You are not the owner of this group");
527 14ad7326 pastith
        }
528 14ad7326 pastith
529 14ad7326 pastith
        @Override
530 8f128261 droutsis
        public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
531 14ad7326 pastith
                        throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
532 14ad7326 pastith
                        InsufficientPermissionsException, QuotaExceededException {
533 14ad7326 pastith
                File file = null;
534 14ad7326 pastith
                try {
535 14ad7326 pastith
                        file = uploadFile(stream, userId);
536 14ad7326 pastith
                } catch ( IOException ioe) {
537 14ad7326 pastith
                        // Supply a more accurate problem description.
538 14ad7326 pastith
                        throw new GSSIOException("Problem creating file",ioe);
539 14ad7326 pastith
                }
540 4d737770 Fotis Stamatelopoulos
                return createFile(userId, folderId, name, mimeType, file.length(), file.getAbsolutePath());
541 14ad7326 pastith
        }
542 14ad7326 pastith
543 14ad7326 pastith
        /* (non-Javadoc)
544 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPIRemote#indexFile(java.lang.Long, boolean)
545 14ad7326 pastith
         */
546 14ad7326 pastith
        public void indexFile(Long fileId, boolean delete) {
547 14ad7326 pastith
                Connection qConn = null;
548 14ad7326 pastith
                Session session = null;
549 14ad7326 pastith
                MessageProducer sender = null;
550 14ad7326 pastith
                try {
551 14ad7326 pastith
                        Context jndiCtx = new InitialContext();
552 14ad7326 pastith
                        ConnectionFactory factory = (QueueConnectionFactory) jndiCtx.lookup("java:/JmsXA");
553 14ad7326 pastith
                        Queue queue = (Queue) jndiCtx.lookup("queue/gss-indexingQueue");
554 14ad7326 pastith
                        qConn = factory.createConnection();
555 14ad7326 pastith
                        session = qConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
556 14ad7326 pastith
                        sender = session.createProducer(queue);
557 14ad7326 pastith
558 14ad7326 pastith
                        MapMessage map = session.createMapMessage();
559 14ad7326 pastith
                        map.setObject("id", fileId);
560 14ad7326 pastith
                        map.setBoolean("delete", delete);
561 14ad7326 pastith
                        sender.send(map);
562 14ad7326 pastith
                }
563 14ad7326 pastith
                catch (NamingException e) {
564 14ad7326 pastith
                        logger.error("Index was not updated: ", e);
565 14ad7326 pastith
                }
566 14ad7326 pastith
                catch (JMSException e) {
567 14ad7326 pastith
                        logger.error("Index was not updated: ", e);
568 14ad7326 pastith
                }
569 14ad7326 pastith
                finally {
570 14ad7326 pastith
                        try {
571 14ad7326 pastith
                                if (sender != null)
572 14ad7326 pastith
                                        sender.close();
573 14ad7326 pastith
                                if (session != null)
574 14ad7326 pastith
                                        session.close();
575 14ad7326 pastith
                                if (qConn != null)
576 14ad7326 pastith
                                        qConn.close();
577 14ad7326 pastith
                        }
578 14ad7326 pastith
                        catch (JMSException e) {
579 14ad7326 pastith
                                logger.warn(e);
580 14ad7326 pastith
                        }
581 14ad7326 pastith
                }
582 14ad7326 pastith
        }
583 14ad7326 pastith
584 14ad7326 pastith
585 14ad7326 pastith
586 14ad7326 pastith
        /**
587 14ad7326 pastith
         * A helper method that generates a unique file path for a stored file. The
588 14ad7326 pastith
         * files are stored using random hash names that are distributed evenly in
589 14ad7326 pastith
         * a 2-level tree of subdirectories named after the first two hex characters
590 14ad7326 pastith
         * in the name. For example, file ab1234cd5769f will be stored in the path
591 14ad7326 pastith
         * /file-repository-root/a/b/ab1234cd5769f. The directories will be created
592 14ad7326 pastith
         * if they don't already exist.
593 14ad7326 pastith
         *
594 14ad7326 pastith
         * @return a unique new file path
595 14ad7326 pastith
         */
596 14ad7326 pastith
        private String generateRepositoryFilePath() {
597 14ad7326 pastith
                String filename = Long.toHexString(random.nextLong());
598 bde4eafb pastith
                String fileRepositoryPath = getConfiguration().getString("fileRepositoryPath","/tmp");
599 14ad7326 pastith
                File root = new File(fileRepositoryPath);
600 14ad7326 pastith
                if (!root.exists())
601 14ad7326 pastith
                        root.mkdirs();
602 14ad7326 pastith
                File firstFolder = new File(root + File.separator + filename.substring(0, 1));
603 14ad7326 pastith
                if (!firstFolder.exists())
604 14ad7326 pastith
                        firstFolder.mkdir();
605 14ad7326 pastith
                File secondFolder = new File(firstFolder + File.separator + filename.substring(1, 2));
606 14ad7326 pastith
                if (!secondFolder.exists())
607 14ad7326 pastith
                        secondFolder.mkdir();
608 14ad7326 pastith
                return secondFolder + File.separator + filename;
609 14ad7326 pastith
        }
610 14ad7326 pastith
611 14ad7326 pastith
        /*
612 14ad7326 pastith
         * (non-Javadoc)
613 14ad7326 pastith
         *
614 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#deleteFile(java.lang.Long,
615 14ad7326 pastith
         *      java.lang.Long)
616 14ad7326 pastith
         */
617 14ad7326 pastith
        public void deleteFile(final Long userId, final Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
618 14ad7326 pastith
                // Validate.
619 14ad7326 pastith
                if (userId == null)
620 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
621 14ad7326 pastith
                if (fileId == null)
622 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
623 14ad7326 pastith
624 14ad7326 pastith
                // Do the actual work.
625 14ad7326 pastith
                final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
626 14ad7326 pastith
                final Folder parent = file.getFolder();
627 14ad7326 pastith
                if (parent == null)
628 14ad7326 pastith
                        throw new ObjectNotFoundException("The specified file has no parent folder");
629 14ad7326 pastith
                final User user = dao.getEntityById(User.class, userId);
630 14ad7326 pastith
                if (!file.hasDeletePermission(user))
631 14ad7326 pastith
                        throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
632 4d737770 Fotis Stamatelopoulos
                for (final FileBody body : file.getBodies())
633 4d737770 Fotis Stamatelopoulos
                        deleteActualFile(body.getStoredFilePath());
634 14ad7326 pastith
                dao.delete(file);
635 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, user, new Date());
636 14ad7326 pastith
                indexFile(fileId, true);
637 14ad7326 pastith
        }
638 14ad7326 pastith
639 4d737770 Fotis Stamatelopoulos
        private void deleteActualFile(String filePath) {
640 4d737770 Fotis Stamatelopoulos
                if (filePath == null)
641 4d737770 Fotis Stamatelopoulos
                        return;
642 4d737770 Fotis Stamatelopoulos
                File file = new File(filePath);
643 4d737770 Fotis Stamatelopoulos
                if (!file.delete())
644 4d737770 Fotis Stamatelopoulos
                        logger.error("Could not delete file " + filePath);
645 4d737770 Fotis Stamatelopoulos
        }
646 4d737770 Fotis Stamatelopoulos
647 14ad7326 pastith
        public void createTag(final Long userId, final Long fileHeaderId, final String tag) throws ObjectNotFoundException {
648 14ad7326 pastith
                if (userId == null)
649 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
650 14ad7326 pastith
                if (fileHeaderId == null)
651 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
652 14ad7326 pastith
                if (StringUtils.isEmpty(tag))
653 14ad7326 pastith
                        throw new ObjectNotFoundException("Tag is empty");
654 14ad7326 pastith
655 14ad7326 pastith
                final User user = dao.getEntityById(User.class, userId);
656 14ad7326 pastith
                final FileHeader fh = dao.getEntityById(FileHeader.class, fileHeaderId);
657 f22e4d5d Dimitris Routsis
                final Folder parent = fh.getFolder();
658 f22e4d5d Dimitris Routsis
                if (parent == null)
659 f22e4d5d Dimitris Routsis
                        throw new ObjectNotFoundException("The specified file has no parent folder");
660 14ad7326 pastith
                user.addTag(fh, tag);
661 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, user, new Date());
662 14ad7326 pastith
        }
663 14ad7326 pastith
664 14ad7326 pastith
        public Set<String> getUserTags(final Long userId) throws ObjectNotFoundException {
665 14ad7326 pastith
                return dao.getUserTags(userId);
666 14ad7326 pastith
        }
667 14ad7326 pastith
668 d114cfe2 Panagiotis Astithas
        public void updateFile(Long userId, Long fileId, String name,
669 d74c0270 Panagiotis Astithas
                                String tagSet, Date modificationDate, Boolean versioned,
670 d74c0270 Panagiotis Astithas
                                Boolean readForAll,        Set<PermissionDTO> permissions)
671 65e0a745 Dimitris Routsis
                        throws DuplicateNameException, ObjectNotFoundException,        InsufficientPermissionsException {
672 14ad7326 pastith
                if (userId == null)
673 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
674 14ad7326 pastith
                if (fileId == null)
675 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
676 14ad7326 pastith
                FileHeader file = dao.getEntityById(FileHeader.class, fileId);
677 f22e4d5d Dimitris Routsis
                final Folder parent = file.getFolder();
678 f22e4d5d Dimitris Routsis
                if (parent == null)
679 f22e4d5d Dimitris Routsis
                        throw new ObjectNotFoundException("The specified file has no parent folder");
680 f22e4d5d Dimitris Routsis
681 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
682 d74c0270 Panagiotis Astithas
                // Check permissions for modifying the file metadata.
683 d74c0270 Panagiotis Astithas
                if ((name != null || tagSet != null || modificationDate != null || versioned != null) && !file.hasWritePermission(user))
684 d74c0270 Panagiotis Astithas
                        throw new InsufficientPermissionsException("User " + user.getId() +        " cannot update file " + file.getName() + "(" +        file.getId() + ")");
685 d74c0270 Panagiotis Astithas
                // Check permissions for making file public.
686 d74c0270 Panagiotis Astithas
                if (readForAll != null && !user.equals(file.getOwner()))
687 d74c0270 Panagiotis Astithas
                                throw new InsufficientPermissionsException("Only the owner can make a file public or not public");
688 d74c0270 Panagiotis Astithas
                // Check permissions for modifying the ACL.
689 d74c0270 Panagiotis Astithas
                if(permissions != null && !permissions.isEmpty() &&        !file.hasModifyACLPermission(user))
690 d74c0270 Panagiotis Astithas
                        throw new InsufficientPermissionsException("User " + user.getId() +        " cannot update the permissions on file " +        file.getName() + "(" + file.getId() + ")");
691 14ad7326 pastith
692 d1a50647 Dimitris Routsis
                if (name != null) {
693 65e0a745 Dimitris Routsis
                        // Do plain check for file already exists.
694 65e0a745 Dimitris Routsis
                        // Extreme concurrency case should be caught by constraint violation later.
695 65e0a745 Dimitris Routsis
                        if (dao.existsFolderOrFile(parent.getId(), name)) throw new DuplicateNameException("A file or folder with the name '" + name + "' already exists");
696 14ad7326 pastith
                        file.setName(name);
697 d1a50647 Dimitris Routsis
                }
698 d74c0270 Panagiotis Astithas
699 d74c0270 Panagiotis Astithas
                if (modificationDate != null)
700 d114cfe2 Panagiotis Astithas
                        file.getAuditInfo().setModificationDate(modificationDate);
701 d74c0270 Panagiotis Astithas
                else
702 d74c0270 Panagiotis Astithas
                        file.getAuditInfo().setModificationDate(new Date());
703 d74c0270 Panagiotis Astithas
                file.getAuditInfo().setModifiedBy(user);
704 14ad7326 pastith
705 d74c0270 Panagiotis Astithas
                List<FileTag> tags = file.getFileTags();
706 14ad7326 pastith
                if (tagSet != null) {
707 14ad7326 pastith
                        Iterator<FileTag> i = tags.iterator();
708 14ad7326 pastith
                        while (i.hasNext()) {
709 14ad7326 pastith
                                FileTag tag = i.next();
710 14ad7326 pastith
                                i.remove();
711 14ad7326 pastith
                                tag.setFile(null);
712 14ad7326 pastith
                                user.removeTag(tag);
713 14ad7326 pastith
                                dao.delete(tag);
714 14ad7326 pastith
                        }
715 14ad7326 pastith
                        dao.flush();
716 14ad7326 pastith
                        StringTokenizer st = new StringTokenizer(tagSet, ",");
717 14ad7326 pastith
                        while (st.hasMoreTokens())
718 14ad7326 pastith
                                new FileTag(user, file, st.nextToken().trim());
719 14ad7326 pastith
                }
720 d74c0270 Panagiotis Astithas
                if (versioned != null && !file.isVersioned() == versioned) {
721 d74c0270 Panagiotis Astithas
                        if (file.isVersioned())
722 d74c0270 Panagiotis Astithas
                                removeOldVersions(userId, fileId);
723 d74c0270 Panagiotis Astithas
                        file.setVersioned(versioned);
724 d74c0270 Panagiotis Astithas
                }
725 d74c0270 Panagiotis Astithas
                if (readForAll != null && user.equals(file.getOwner()))
726 d74c0270 Panagiotis Astithas
                        file.setReadForAll(readForAll);
727 ba5f9575 Panagiotis Astithas
                if (permissions != null && !permissions.isEmpty())
728 ba5f9575 Panagiotis Astithas
                        setFilePermissions(file, permissions);
729 65e0a745 Dimitris Routsis
730 65e0a745 Dimitris Routsis
                /*
731 65e0a745 Dimitris Routsis
                 * Force constraint violation to manifest itself here.
732 65e0a745 Dimitris Routsis
                 * This should cover extreme concurrency cases that the simple check
733 65e0a745 Dimitris Routsis
                 * above hasn't caught.
734 65e0a745 Dimitris Routsis
                 */
735 65e0a745 Dimitris Routsis
                try {
736 65e0a745 Dimitris Routsis
                        dao.flush();
737 65e0a745 Dimitris Routsis
                }
738 65e0a745 Dimitris Routsis
                catch (EJBTransactionRolledbackException e) {
739 65e0a745 Dimitris Routsis
                        Throwable cause = e.getCause();
740 65e0a745 Dimitris Routsis
                        if (cause instanceof PersistenceException && cause.getCause() instanceof ConstraintViolationException)
741 65e0a745 Dimitris Routsis
                                throw new DuplicateNameException("A file or folder with the name '" + name + "' already exists");
742 65e0a745 Dimitris Routsis
                        throw e;
743 65e0a745 Dimitris Routsis
                }
744 65e0a745 Dimitris Routsis
745 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, user, new Date());
746 14ad7326 pastith
747 14ad7326 pastith
                // Re-index the file if it was modified.
748 14ad7326 pastith
                if (name != null || tagSet != null)
749 14ad7326 pastith
                        indexFile(fileId, false);
750 14ad7326 pastith
        }
751 14ad7326 pastith
752 14ad7326 pastith
        @Override
753 14ad7326 pastith
        public InputStream getFileContents(Long userId, Long fileId)
754 14ad7326 pastith
                        throws ObjectNotFoundException, InsufficientPermissionsException {
755 14ad7326 pastith
                if (userId == null)
756 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
757 14ad7326 pastith
                if (fileId == null)
758 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
759 14ad7326 pastith
760 14ad7326 pastith
                FileHeader header = dao.getEntityById(FileHeader.class, fileId);
761 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
762 14ad7326 pastith
                if (!header.hasReadPermission(user)) {
763 14ad7326 pastith
                        logger.info("User " + user.getId() + " cannot read file " + header.getName() + "(" + fileId + ")");
764 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
765 14ad7326 pastith
                }
766 14ad7326 pastith
767 14ad7326 pastith
                File f = new File(header.getCurrentBody().getStoredFilePath());
768 14ad7326 pastith
                try {
769 14ad7326 pastith
                        return new FileInputStream(f);
770 14ad7326 pastith
                } catch (FileNotFoundException e) {
771 14ad7326 pastith
                        logger.error("Could not locate the contents of file " + f.getAbsolutePath());
772 14ad7326 pastith
                        throw new ObjectNotFoundException("The file contents could not be located");
773 14ad7326 pastith
                }
774 14ad7326 pastith
        }
775 14ad7326 pastith
776 14ad7326 pastith
        /* (non-Javadoc)
777 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getFileContents(java.lang.Long, java.lang.Long, java.lang.Long)
778 14ad7326 pastith
         */
779 14ad7326 pastith
        public InputStream getFileContents(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
780 14ad7326 pastith
                if (userId == null)
781 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
782 14ad7326 pastith
                if (fileId == null)
783 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
784 14ad7326 pastith
                if (bodyId == null)
785 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
786 14ad7326 pastith
787 14ad7326 pastith
                final FileHeader header = dao.getEntityById(FileHeader.class, fileId);
788 14ad7326 pastith
                final FileBody body = dao.getEntityById(FileBody.class, bodyId);
789 14ad7326 pastith
                final User user = dao.getEntityById(User.class, userId);
790 14ad7326 pastith
                if (!header.hasReadPermission(user)) {
791 14ad7326 pastith
                        logger.info("User " + user.getId() + " cannot read file " + header.getName() + "(" + fileId + ")");
792 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
793 14ad7326 pastith
                }
794 14ad7326 pastith
795 14ad7326 pastith
                File f = new File(body.getStoredFilePath());
796 14ad7326 pastith
                try {
797 14ad7326 pastith
                        return new FileInputStream(f);
798 14ad7326 pastith
                } catch (FileNotFoundException e) {
799 14ad7326 pastith
                        logger.error("Could not locate the contents of file " + f.getAbsolutePath());
800 14ad7326 pastith
                        throw new ObjectNotFoundException("The file contents could not be located");
801 14ad7326 pastith
                }
802 14ad7326 pastith
        }
803 14ad7326 pastith
804 01a30cd0 Panagiotis Astithas
        @Override
805 14ad7326 pastith
        public FileHeaderDTO getFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
806 14ad7326 pastith
                if (userId == null)
807 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
808 14ad7326 pastith
                if (fileId == null)
809 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
810 14ad7326 pastith
                final User user = dao.getEntityById(User.class, userId);
811 14ad7326 pastith
                final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
812 14ad7326 pastith
                if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
813 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
814 14ad7326 pastith
                return file.getDTO();
815 14ad7326 pastith
        }
816 14ad7326 pastith
817 14ad7326 pastith
        @Override
818 14ad7326 pastith
        public FileBodyDTO getFileBody(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
819 14ad7326 pastith
                if (userId == null)
820 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
821 14ad7326 pastith
                if (fileId == null)
822 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
823 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
824 14ad7326 pastith
                FileHeader file = dao.getEntityById(FileHeader.class, fileId);
825 14ad7326 pastith
                if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
826 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
827 14ad7326 pastith
                FileBody body = dao.getEntityById(FileBody.class, bodyId);
828 14ad7326 pastith
                return body.getDTO();
829 14ad7326 pastith
        }
830 14ad7326 pastith
831 14ad7326 pastith
        @Override
832 68410d59 pastith
        public Object getResourceAtPath(Long ownerId, String path, boolean ignoreDeleted)
833 68410d59 pastith
                        throws ObjectNotFoundException {
834 14ad7326 pastith
                if (ownerId == null)
835 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
836 14ad7326 pastith
                if (StringUtils.isEmpty(path))
837 14ad7326 pastith
                        throw new ObjectNotFoundException("No path specified");
838 14ad7326 pastith
839 14ad7326 pastith
                User owner = dao.getEntityById(User.class, ownerId);
840 14ad7326 pastith
                List<String> pathElements = new ArrayList<String>();
841 14ad7326 pastith
                StringTokenizer st = new StringTokenizer(path, "/");
842 14ad7326 pastith
                while (st.hasMoreTokens())
843 14ad7326 pastith
                        pathElements.add(st.nextToken());
844 14ad7326 pastith
                if (pathElements.size() < 1)
845 14ad7326 pastith
                        return getRootFolder(owner.getId());
846 14ad7326 pastith
                // Store the last element, since it requires special handling.
847 14ad7326 pastith
                String lastElement = pathElements.remove(pathElements.size() - 1);
848 14ad7326 pastith
                FolderDTO cursor = getRootFolder(owner.getId());
849 14ad7326 pastith
                // Traverse and verify the specified folder path.
850 68410d59 pastith
                for (String pathElement : pathElements) {
851 14ad7326 pastith
                        cursor = getFolder(cursor.getId(), pathElement);
852 68410d59 pastith
                        if (cursor.isDeleted())
853 68410d59 pastith
                                throw new ObjectNotFoundException("Folder " + cursor.getPath() + " not found");
854 68410d59 pastith
                }
855 14ad7326 pastith
856 14ad7326 pastith
                // Use the lastElement to retrieve the actual resource.
857 14ad7326 pastith
                Object resource = null;
858 14ad7326 pastith
                try {
859 14ad7326 pastith
                        FileHeaderDTO file = getFile(cursor.getId(), lastElement);
860 68410d59 pastith
                        if (ignoreDeleted && file.isDeleted())
861 14ad7326 pastith
                                throw new ObjectNotFoundException("Resource not found");
862 14ad7326 pastith
                        resource = file;
863 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
864 14ad7326 pastith
                        // Perhaps the requested resource is not a file, so
865 14ad7326 pastith
                        // check for folders as well.
866 14ad7326 pastith
                        FolderDTO folder = getFolder(cursor.getId(), lastElement);
867 68410d59 pastith
                        if (ignoreDeleted && folder.isDeleted())
868 14ad7326 pastith
                                throw new ObjectNotFoundException("Resource not found");
869 14ad7326 pastith
                        resource = folder;
870 14ad7326 pastith
                }
871 14ad7326 pastith
                return resource;
872 14ad7326 pastith
        }
873 14ad7326 pastith
874 14ad7326 pastith
        /**
875 14ad7326 pastith
         * Retrieve a file for the specified user that has the specified name and
876 14ad7326 pastith
         * its parent folder has id equal to folderId.
877 14ad7326 pastith
         *
878 14ad7326 pastith
         * @param userId the ID of the current user
879 14ad7326 pastith
         * @param folderId the ID of the parent folder
880 14ad7326 pastith
         * @param name the name of the requested file
881 14ad7326 pastith
         * @return the file found
882 14ad7326 pastith
         * @throws ObjectNotFoundException if the specified folder or file was not
883 14ad7326 pastith
         *             found, with the exception message mentioning the precise
884 14ad7326 pastith
         *             problem
885 14ad7326 pastith
         */
886 14ad7326 pastith
        private FileHeaderDTO getFile(Long folderId, String name) throws ObjectNotFoundException {
887 14ad7326 pastith
                if (folderId == null)
888 14ad7326 pastith
                        throw new ObjectNotFoundException("No parent folder specified");
889 14ad7326 pastith
                if (StringUtils.isEmpty(name))
890 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
891 14ad7326 pastith
892 14ad7326 pastith
                FileHeader file = dao.getFile(folderId, name);
893 14ad7326 pastith
                return file.getDTO();
894 14ad7326 pastith
        }
895 14ad7326 pastith
896 14ad7326 pastith
        /**
897 14ad7326 pastith
         * Retrieve a folder for the specified user that has the specified name and
898 14ad7326 pastith
         * its parent folder has id equal to parentId.
899 14ad7326 pastith
         *
900 14ad7326 pastith
         * @param parentId the ID of the parent folder
901 14ad7326 pastith
         * @param name the name of the requested folder
902 14ad7326 pastith
         * @return the folder found
903 14ad7326 pastith
         * @throws ObjectNotFoundException if the specified folder or parent was not
904 14ad7326 pastith
         *             found, with the exception message mentioning the precise
905 14ad7326 pastith
         *             problem
906 14ad7326 pastith
         */
907 14ad7326 pastith
        private FolderDTO getFolder(Long parentId, String name) throws ObjectNotFoundException {
908 14ad7326 pastith
                if (parentId == null)
909 14ad7326 pastith
                        throw new ObjectNotFoundException("No parent folder specified");
910 14ad7326 pastith
                if (StringUtils.isEmpty(name))
911 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
912 14ad7326 pastith
913 14ad7326 pastith
                Folder folder = dao.getFolder(parentId, name);
914 14ad7326 pastith
                return folder.getDTO();
915 14ad7326 pastith
        }
916 14ad7326 pastith
917 b13aae04 pastith
        private FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
918 14ad7326 pastith
                File file = null;
919 14ad7326 pastith
                try {
920 14ad7326 pastith
                        file = uploadFile(resourceInputStream, userId);
921 14ad7326 pastith
                } catch ( IOException ioe) {
922 14ad7326 pastith
                        // Supply a more accurate problem description.
923 14ad7326 pastith
                        throw new GSSIOException("Problem creating file",ioe);
924 14ad7326 pastith
                }
925 4d737770 Fotis Stamatelopoulos
                return updateFileContents(userId, fileId, mimeType, file.length(), file.getAbsolutePath());
926 14ad7326 pastith
        }
927 14ad7326 pastith
928 14ad7326 pastith
        @Override
929 14ad7326 pastith
        public void copyFile(Long userId, Long fileId, String dest) throws ObjectNotFoundException, DuplicateNameException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
930 14ad7326 pastith
                if (userId == null)
931 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
932 14ad7326 pastith
                if (fileId == null)
933 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
934 14ad7326 pastith
                if (StringUtils.isEmpty(dest))
935 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
936 14ad7326 pastith
937 68410d59 pastith
                Object destination = getResourceAtPath(userId, getParentPath(dest), true);
938 14ad7326 pastith
                if (!(destination instanceof FolderDTO))
939 14ad7326 pastith
                        throw new ObjectNotFoundException("Destination parent folder not found");
940 14ad7326 pastith
                FolderDTO parent = (FolderDTO) destination;
941 14ad7326 pastith
                copyFile(userId, fileId, parent.getId(), getLastElement(dest));
942 14ad7326 pastith
        }
943 14ad7326 pastith
944 14ad7326 pastith
        @Override
945 14ad7326 pastith
        public void copyFileToPath(Long userId, Long ownerId, Long fileId, String dest) throws ObjectNotFoundException, DuplicateNameException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
946 14ad7326 pastith
                if (userId == null)
947 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
948 14ad7326 pastith
                if (ownerId == null)
949 14ad7326 pastith
                        throw new ObjectNotFoundException("No owner specified");
950 14ad7326 pastith
                if (fileId == null)
951 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
952 14ad7326 pastith
                if (StringUtils.isEmpty(dest))
953 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
954 14ad7326 pastith
955 68410d59 pastith
                Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
956 14ad7326 pastith
                if (!(destination instanceof FolderDTO))
957 14ad7326 pastith
                        throw new ObjectNotFoundException("Destination parent folder not found");
958 14ad7326 pastith
                FolderDTO parent = (FolderDTO) destination;
959 14ad7326 pastith
                copyFile(userId, fileId, parent.getId(), getLastElement(dest));
960 14ad7326 pastith
        }
961 14ad7326 pastith
962 14ad7326 pastith
        @Override
963 14ad7326 pastith
        public void copyFile(Long userId, Long fileId, Long destId, String destName) throws ObjectNotFoundException, DuplicateNameException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
964 14ad7326 pastith
                if (userId == null)
965 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
966 14ad7326 pastith
                if (fileId == null)
967 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
968 14ad7326 pastith
                if (destId == null)
969 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
970 14ad7326 pastith
                if (StringUtils.isEmpty(destName))
971 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination file name specified");
972 14ad7326 pastith
973 14ad7326 pastith
                FileHeader file = dao.getEntityById(FileHeader.class, fileId);
974 14ad7326 pastith
                Folder destination = dao.getEntityById(Folder.class, destId);
975 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
976 14ad7326 pastith
                if (!file.hasReadPermission(user) || !destination.hasWritePermission(user))
977 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
978 2be5f35d Dimitris Routsis
                boolean versioned = file.isVersioned();
979 14ad7326 pastith
                int versionsNumber = file.getBodies().size();
980 14ad7326 pastith
                FileBody oldestBody = file.getBodies().get(0);
981 14ad7326 pastith
                assert oldestBody != null;
982 14ad7326 pastith
                File contents = new File(oldestBody.getStoredFilePath());
983 14ad7326 pastith
                try {
984 14ad7326 pastith
                        createFile(user.getId(), destination.getId(), destName, oldestBody.getMimeType(), new FileInputStream(contents));
985 14ad7326 pastith
                        FileHeader copiedFile = dao.getFile(destination.getId(), destName);
986 2be5f35d Dimitris Routsis
                        copiedFile.setVersioned(versioned);
987 14ad7326 pastith
                        dao.flush();
988 14ad7326 pastith
                        if (versionsNumber > 1)
989 14ad7326 pastith
                                for (int i = 1; i < versionsNumber; i++) {
990 14ad7326 pastith
                                        FileBody body = file.getBodies().get(i);
991 14ad7326 pastith
                                        assert body != null;
992 14ad7326 pastith
                                        contents = new File(body.getStoredFilePath());
993 14ad7326 pastith
                                        updateFileContents(user.getId(), copiedFile.getId(), body.getMimeType(), new FileInputStream(contents));
994 14ad7326 pastith
                                }
995 14ad7326 pastith
                        List<FileTag> tags = file.getFileTags();
996 14ad7326 pastith
                        for (FileTag tag : tags)
997 14ad7326 pastith
                                createTag(userId, copiedFile.getId(), tag.getTag());
998 14ad7326 pastith
999 14ad7326 pastith
                } catch (FileNotFoundException e) {
1000 14ad7326 pastith
                        throw new ObjectNotFoundException("File contents not found for file " + contents.getAbsolutePath());
1001 14ad7326 pastith
                }
1002 14ad7326 pastith
1003 14ad7326 pastith
        }
1004 14ad7326 pastith
1005 14ad7326 pastith
        @Override
1006 14ad7326 pastith
        public void copyFolder(Long userId, Long folderId, String dest) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException {
1007 14ad7326 pastith
                if (userId == null)
1008 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1009 14ad7326 pastith
                if (folderId == null)
1010 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1011 14ad7326 pastith
                if (StringUtils.isEmpty(dest))
1012 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
1013 14ad7326 pastith
1014 68410d59 pastith
                Object destination = getResourceAtPath(userId, getParentPath(dest), true);
1015 14ad7326 pastith
                if (!(destination instanceof FolderDTO))
1016 14ad7326 pastith
                        throw new ObjectNotFoundException("Destination folder not found");
1017 14ad7326 pastith
                FolderDTO parent = (FolderDTO) destination;
1018 14ad7326 pastith
                copyFolder(userId, folderId, parent.getId(), getLastElement(dest));
1019 14ad7326 pastith
        }
1020 14ad7326 pastith
1021 14ad7326 pastith
        @Override
1022 14ad7326 pastith
        public void copyFolder(Long userId, Long folderId, Long destId, String destName) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException {
1023 14ad7326 pastith
                if (userId == null)
1024 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1025 14ad7326 pastith
                if (folderId == null)
1026 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1027 14ad7326 pastith
                if (destId == null)
1028 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
1029 14ad7326 pastith
                if (StringUtils.isEmpty(destName))
1030 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination folder name specified");
1031 14ad7326 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
1032 14ad7326 pastith
                Folder destination = dao.getEntityById(Folder.class, destId);
1033 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1034 14ad7326 pastith
                if (!destination.hasWritePermission(user) || !folder.hasReadPermission(user))
1035 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
1036 14ad7326 pastith
                createFolder(user.getId(), destination.getId(), destName);
1037 14ad7326 pastith
        }
1038 14ad7326 pastith
1039 14ad7326 pastith
        @Override
1040 14ad7326 pastith
        public void copyFolderStructureToPath(Long userId, Long ownerId, Long folderId, String dest) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
1041 14ad7326 pastith
                if (userId == null)
1042 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1043 14ad7326 pastith
                if (ownerId == null)
1044 14ad7326 pastith
                        throw new ObjectNotFoundException("No owner specified");
1045 14ad7326 pastith
                if (folderId == null)
1046 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1047 14ad7326 pastith
                if (StringUtils.isEmpty(dest))
1048 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
1049 14ad7326 pastith
1050 68410d59 pastith
                Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
1051 14ad7326 pastith
                if (!(destination instanceof FolderDTO))
1052 14ad7326 pastith
                        throw new ObjectNotFoundException("Destination folder not found");
1053 14ad7326 pastith
                FolderDTO parent = (FolderDTO) destination;
1054 14ad7326 pastith
                copyFolderStructure(userId, folderId, parent.getId(), getLastElement(dest));
1055 14ad7326 pastith
        }
1056 14ad7326 pastith
1057 14ad7326 pastith
        @Override
1058 14ad7326 pastith
        public void copyFolderStructure(Long userId, Long folderId, Long destId, String destName) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException, GSSIOException, QuotaExceededException {
1059 14ad7326 pastith
                if (userId == null)
1060 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1061 14ad7326 pastith
                if (folderId == null)
1062 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1063 14ad7326 pastith
                if (destId == null)
1064 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
1065 14ad7326 pastith
                if (StringUtils.isEmpty(destName))
1066 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination folder name specified");
1067 14ad7326 pastith
1068 14ad7326 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
1069 14ad7326 pastith
                Folder destination = dao.getEntityById(Folder.class, destId);
1070 14ad7326 pastith
                final User user = dao.getEntityById(User.class, userId);
1071 14ad7326 pastith
                // XXX: quick fix need to copy only visible items to user (Source
1072 14ad7326 pastith
                // for bugs)
1073 14ad7326 pastith
                if (!folder.getOwner().getId().equals(userId) && !folder.hasReadPermission(user))
1074 14ad7326 pastith
                        return;
1075 14ad7326 pastith
                if(folder.isDeleted())//do not copy trashed folder and contents
1076 14ad7326 pastith
                        return;
1077 14ad7326 pastith
                if (!destination.hasWritePermission(user) || !folder.hasReadPermission(user))
1078 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
1079 14ad7326 pastith
                createFolder(user.getId(), destination.getId(), destName);
1080 14ad7326 pastith
                Folder createdFolder = dao.getFolder(destination.getId(), destName);
1081 14ad7326 pastith
                List<FileHeader> files = folder.getFiles();
1082 14ad7326 pastith
                if (files != null)
1083 14ad7326 pastith
                        for (FileHeader file : files)
1084 14ad7326 pastith
                                if(!file.isDeleted())
1085 14ad7326 pastith
                                        copyFile(userId, file.getId(), createdFolder.getId(), file.getName());
1086 14ad7326 pastith
                List<Folder> subFolders = folder.getSubfolders();
1087 14ad7326 pastith
                if (subFolders != null)
1088 14ad7326 pastith
                        for (Folder sub : subFolders)
1089 15ad8af3 koutsoub
                                if(!sub.getId().equals(createdFolder.getId()))
1090 15ad8af3 koutsoub
                                        copyFolderStructure(userId, sub.getId(), createdFolder.getId(), sub.getName());
1091 14ad7326 pastith
1092 14ad7326 pastith
        }
1093 14ad7326 pastith
1094 14ad7326 pastith
        /**
1095 14ad7326 pastith
         * For a provided path, remove the last element and return the rest, that is
1096 14ad7326 pastith
         * the path of the parent folder.
1097 14ad7326 pastith
         *
1098 14ad7326 pastith
         * @param path the specified path
1099 14ad7326 pastith
         * @return the path of the parent folder
1100 14ad7326 pastith
         * @throws ObjectNotFoundException if the provided string contains no path
1101 14ad7326 pastith
         *             delimiters
1102 14ad7326 pastith
         */
1103 14ad7326 pastith
        private String getParentPath(String path) throws ObjectNotFoundException {
1104 14ad7326 pastith
                int lastDelimiter = path.lastIndexOf('/');
1105 14ad7326 pastith
                if (lastDelimiter == 0)
1106 14ad7326 pastith
                        return "/";
1107 14ad7326 pastith
                if (lastDelimiter == -1)
1108 14ad7326 pastith
                        // No path found.
1109 14ad7326 pastith
                        throw new ObjectNotFoundException("There is no parent in the path: " + path);
1110 14ad7326 pastith
                else if (lastDelimiter < path.length() - 1)
1111 14ad7326 pastith
                        // Return the part before the delimiter.
1112 14ad7326 pastith
                        return path.substring(0, lastDelimiter);
1113 14ad7326 pastith
                else {
1114 14ad7326 pastith
                        // Remove the trailing delimiter and then recurse.
1115 14ad7326 pastith
                        String strippedTrail = path.substring(0, lastDelimiter);
1116 14ad7326 pastith
                        return getParentPath(strippedTrail);
1117 14ad7326 pastith
                }
1118 14ad7326 pastith
        }
1119 14ad7326 pastith
1120 14ad7326 pastith
        /**
1121 14ad7326 pastith
         * Get the last element in a path that denotes the file or folder name.
1122 14ad7326 pastith
         *
1123 14ad7326 pastith
         * @param path the provided path
1124 14ad7326 pastith
         * @return the last element in the path
1125 14ad7326 pastith
         */
1126 14ad7326 pastith
        private String getLastElement(String path) {
1127 14ad7326 pastith
                int lastDelimiter = path.lastIndexOf('/');
1128 14ad7326 pastith
                if (lastDelimiter == -1)
1129 14ad7326 pastith
                        // No path found.
1130 14ad7326 pastith
                        return path;
1131 14ad7326 pastith
                else if (lastDelimiter < path.length() - 1)
1132 14ad7326 pastith
                        // Return the part after the delimiter.
1133 14ad7326 pastith
                        return path.substring(lastDelimiter + 1);
1134 14ad7326 pastith
                else {
1135 14ad7326 pastith
                        // Remove the trailing delimiter and then recurse.
1136 14ad7326 pastith
                        String strippedTrail = path.substring(0, lastDelimiter);
1137 14ad7326 pastith
                        return getLastElement(strippedTrail);
1138 14ad7326 pastith
                }
1139 14ad7326 pastith
        }
1140 14ad7326 pastith
1141 14ad7326 pastith
        @Override
1142 14ad7326 pastith
        public void moveFileToTrash(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
1143 14ad7326 pastith
                if (userId == null)
1144 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1145 14ad7326 pastith
                if (fileId == null)
1146 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
1147 14ad7326 pastith
1148 14ad7326 pastith
                // Do the actual work.
1149 14ad7326 pastith
                FileHeader file = dao.getEntityById(FileHeader.class, fileId);
1150 14ad7326 pastith
                Folder parent = file.getFolder();
1151 14ad7326 pastith
                if (parent == null)
1152 14ad7326 pastith
                        throw new ObjectNotFoundException("The specified file has no parent folder");
1153 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1154 14ad7326 pastith
                if (!file.hasDeletePermission(user))
1155 14ad7326 pastith
                        throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
1156 14ad7326 pastith
1157 14ad7326 pastith
                file.setDeleted(true);
1158 14ad7326 pastith
                dao.update(file);
1159 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, user, new Date());
1160 14ad7326 pastith
        }
1161 14ad7326 pastith
1162 14ad7326 pastith
        @Override
1163 4684df80 Fotis Stamatelopoulos
        public void moveFileToPath(Long userId, Long ownerId, Long fileId, String dest) throws ObjectNotFoundException, InsufficientPermissionsException, QuotaExceededException {
1164 14ad7326 pastith
                if (userId == null)
1165 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1166 14ad7326 pastith
                if (ownerId == null)
1167 14ad7326 pastith
                        throw new ObjectNotFoundException("No owner specified");
1168 14ad7326 pastith
                if (fileId == null)
1169 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
1170 14ad7326 pastith
                if (StringUtils.isEmpty(dest))
1171 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
1172 14ad7326 pastith
1173 68410d59 pastith
                Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
1174 14ad7326 pastith
                if (!(destination instanceof FolderDTO))
1175 14ad7326 pastith
                        throw new ObjectNotFoundException("Destination parent folder not found");
1176 14ad7326 pastith
                FolderDTO parent = (FolderDTO) destination;
1177 14ad7326 pastith
                moveFile(userId, fileId, parent.getId(), getLastElement(dest));
1178 14ad7326 pastith
        }
1179 14ad7326 pastith
1180 14ad7326 pastith
        @Override
1181 4d737770 Fotis Stamatelopoulos
        public void moveFile(Long userId, Long fileId, Long destId, String destName) throws InsufficientPermissionsException, ObjectNotFoundException, QuotaExceededException {
1182 14ad7326 pastith
                if (userId == null)
1183 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1184 14ad7326 pastith
                if (fileId == null)
1185 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
1186 14ad7326 pastith
                if (destId == null)
1187 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
1188 14ad7326 pastith
                if (StringUtils.isEmpty(destName))
1189 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination file name specified");
1190 14ad7326 pastith
1191 14ad7326 pastith
                FileHeader file = dao.getEntityById(FileHeader.class, fileId);
1192 f22e4d5d Dimitris Routsis
                Folder source = file.getFolder();
1193 14ad7326 pastith
                Folder destination = dao.getEntityById(Folder.class, destId);
1194 14ad7326 pastith
1195 14ad7326 pastith
                User owner = dao.getEntityById(User.class, userId);
1196 14ad7326 pastith
                if (!file.hasDeletePermission(owner) || !destination.hasWritePermission(owner))
1197 14ad7326 pastith
                        throw new InsufficientPermissionsException("User " + owner.getId() + " cannot move file " + file.getName() + "(" + file.getId() + ")");
1198 14ad7326 pastith
1199 4d737770 Fotis Stamatelopoulos
                // if the destination folder belongs to another user:
1200 4d737770 Fotis Stamatelopoulos
                if (!file.getOwner().equals(destination.getOwner())) {
1201 4d737770 Fotis Stamatelopoulos
                        // (a) check if the destination quota allows the move
1202 4d737770 Fotis Stamatelopoulos
                        if(getQuotaLeft(destination.getOwner().getId()) < file.getTotalSize())
1203 4d737770 Fotis Stamatelopoulos
                                throw new QuotaExceededException("Not enough free space available");
1204 4d737770 Fotis Stamatelopoulos
                        User newOwner = destination.getOwner();
1205 4d737770 Fotis Stamatelopoulos
                        // (b) if quota OK, change the owner of the file
1206 4d737770 Fotis Stamatelopoulos
                        file.setOwner(newOwner);
1207 4d737770 Fotis Stamatelopoulos
                        // if the file has no permission for the new owner, add it
1208 4d737770 Fotis Stamatelopoulos
                        Permission ownerPermission = null;
1209 4d737770 Fotis Stamatelopoulos
                        for (final Permission p : file.getPermissions())
1210 4d737770 Fotis Stamatelopoulos
                                if (p.getUser() != null)
1211 4d737770 Fotis Stamatelopoulos
                                        if (p.getUser().equals(newOwner)) {
1212 4d737770 Fotis Stamatelopoulos
                                                ownerPermission = p;
1213 4d737770 Fotis Stamatelopoulos
                                                break;
1214 4d737770 Fotis Stamatelopoulos
                                        }
1215 4d737770 Fotis Stamatelopoulos
                        if (ownerPermission == null) {
1216 4d737770 Fotis Stamatelopoulos
                                ownerPermission = new Permission();
1217 4d737770 Fotis Stamatelopoulos
                                ownerPermission.setUser(newOwner);
1218 4d737770 Fotis Stamatelopoulos
                                file.addPermission(ownerPermission);
1219 4d737770 Fotis Stamatelopoulos
                        }
1220 4d737770 Fotis Stamatelopoulos
                        ownerPermission.setRead(true);
1221 4d737770 Fotis Stamatelopoulos
                        ownerPermission.setWrite(true);
1222 4d737770 Fotis Stamatelopoulos
                        ownerPermission.setModifyACL(true);
1223 4d737770 Fotis Stamatelopoulos
                }
1224 4d737770 Fotis Stamatelopoulos
                // move the file to the destination folder
1225 4d737770 Fotis Stamatelopoulos
                file.setFolder(destination);
1226 f22e4d5d Dimitris Routsis
                touchParentFolders(source, owner, new Date());
1227 f22e4d5d Dimitris Routsis
                touchParentFolders(destination, owner, new Date());
1228 14ad7326 pastith
        }
1229 14ad7326 pastith
1230 14ad7326 pastith
        @Override
1231 82248972 Panagiotis Astithas
        public void moveFolderToPath(Long userId, Long ownerId, Long folderId, String dest) throws ObjectNotFoundException, InsufficientPermissionsException, QuotaExceededException {
1232 14ad7326 pastith
                if (userId == null)
1233 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1234 14ad7326 pastith
                if (ownerId == null)
1235 14ad7326 pastith
                        throw new ObjectNotFoundException("No owner specified");
1236 14ad7326 pastith
                if (folderId == null)
1237 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1238 14ad7326 pastith
                if (StringUtils.isEmpty(dest))
1239 14ad7326 pastith
                        throw new ObjectNotFoundException("No destination specified");
1240 14ad7326 pastith
1241 68410d59 pastith
                Object destination = getResourceAtPath(ownerId, getParentPath(dest), true);
1242 14ad7326 pastith
                if (!(destination instanceof FolderDTO))
1243 14ad7326 pastith
                        throw new ObjectNotFoundException("Destination parent folder not found");
1244 14ad7326 pastith
                FolderDTO parent = (FolderDTO) destination;
1245 14ad7326 pastith
                moveFolder(userId, folderId, parent.getId(), getLastElement(dest));
1246 14ad7326 pastith
        }
1247 14ad7326 pastith
1248 14ad7326 pastith
        @Override
1249 f1052f48 Panagiotis Astithas
        public void moveFolder(Long userId, Long folderId, Long destId, String destName)
1250 f1052f48 Panagiotis Astithas
                        throws ObjectNotFoundException, InsufficientPermissionsException,
1251 f1052f48 Panagiotis Astithas
                        QuotaExceededException {
1252 f1052f48 Panagiotis Astithas
                Folder source = dao.getEntityById(Folder.class, folderId);
1253 f1052f48 Panagiotis Astithas
                Folder destination = dao.getEntityById(Folder.class, destId);
1254 f1052f48 Panagiotis Astithas
                User user = dao.getEntityById(User.class, userId);
1255 f1052f48 Panagiotis Astithas
                User sourceOwner = source.getOwner();
1256 f1052f48 Panagiotis Astithas
                User destinationOwner = destination.getOwner();
1257 f1052f48 Panagiotis Astithas
                // Do not move trashed folders and contents.
1258 f1052f48 Panagiotis Astithas
                if (source.isDeleted())
1259 f1052f48 Panagiotis Astithas
                        return;
1260 f1052f48 Panagiotis Astithas
                // Check permissions.
1261 f1052f48 Panagiotis Astithas
                if (!destination.hasWritePermission(user)
1262 f1052f48 Panagiotis Astithas
                                || !source.hasReadPermission(user)
1263 f1052f48 Panagiotis Astithas
                                || !source.hasWritePermission(user))
1264 f1052f48 Panagiotis Astithas
                        throw new InsufficientPermissionsException("You don't have the " +
1265 f1052f48 Panagiotis Astithas
                                        "necessary permissions");
1266 f1052f48 Panagiotis Astithas
                // Use the same timestamp for all subsequent modifications to make
1267 f1052f48 Panagiotis Astithas
                // changes appear simultaneous.
1268 f1052f48 Panagiotis Astithas
                Date now = new Date();
1269 f1052f48 Panagiotis Astithas
                // If source and destination are not in the same user's namespace,
1270 f1052f48 Panagiotis Astithas
                // change owners and check quota.
1271 f1052f48 Panagiotis Astithas
                if (!sourceOwner.equals(destinationOwner)) {
1272 f1052f48 Panagiotis Astithas
                        changeOwner(source, destinationOwner, user, now);
1273 f1052f48 Panagiotis Astithas
                        if (getQuotaLeft(destinationOwner.getId()) < 0)
1274 f1052f48 Panagiotis Astithas
                                throw new QuotaExceededException("Not enough free space " +
1275 f1052f48 Panagiotis Astithas
                                                "available in destination folder");
1276 f1052f48 Panagiotis Astithas
                }
1277 f1052f48 Panagiotis Astithas
                // Perform the move.
1278 f1052f48 Panagiotis Astithas
                Folder oldParent = source.getParent();
1279 f1052f48 Panagiotis Astithas
                oldParent.removeSubfolder(source);
1280 f1052f48 Panagiotis Astithas
                destination.addSubfolder(source);
1281 f1052f48 Panagiotis Astithas
                // Mark the former parent and destination trees upwards as modified.
1282 f1052f48 Panagiotis Astithas
                touchParentFolders(oldParent, user, now);
1283 f1052f48 Panagiotis Astithas
                touchParentFolders(source, user, now);
1284 14ad7326 pastith
        }
1285 14ad7326 pastith
1286 f1052f48 Panagiotis Astithas
        /**
1287 f1052f48 Panagiotis Astithas
         * Recursively change the owner of the specified folder and all of its
1288 f1052f48 Panagiotis Astithas
         * contents to the specified owner. Also mark them all as modified with the
1289 f1052f48 Panagiotis Astithas
         * specified modifier and modificationDate.
1290 14ad7326 pastith
         */
1291 f1052f48 Panagiotis Astithas
        private void changeOwner(Folder folder, User owner, User modifier, Date modificationDate) {
1292 f1052f48 Panagiotis Astithas
                for (FileHeader file: folder.getFiles()) {
1293 f1052f48 Panagiotis Astithas
                        file.setOwner(owner);
1294 f1052f48 Panagiotis Astithas
                        file.getAuditInfo().setModificationDate(modificationDate);
1295 f1052f48 Panagiotis Astithas
                        file.getAuditInfo().setModifiedBy(modifier);
1296 f1052f48 Panagiotis Astithas
                }
1297 f1052f48 Panagiotis Astithas
                for (Folder sub: folder.getSubfolders())
1298 f1052f48 Panagiotis Astithas
                        changeOwner(sub, owner, modifier, modificationDate);
1299 f1052f48 Panagiotis Astithas
                folder.setOwner(owner);
1300 f1052f48 Panagiotis Astithas
                folder.getAuditInfo().setModificationDate(modificationDate);
1301 f1052f48 Panagiotis Astithas
                folder.getAuditInfo().setModifiedBy(modifier);
1302 f1052f48 Panagiotis Astithas
        }
1303 f1052f48 Panagiotis Astithas
1304 f1052f48 Panagiotis Astithas
        @Override
1305 14ad7326 pastith
        public List<FileHeaderDTO> getDeletedFiles(Long userId) throws ObjectNotFoundException {
1306 14ad7326 pastith
                // Validate.
1307 14ad7326 pastith
                if (userId == null)
1308 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1309 14ad7326 pastith
1310 14ad7326 pastith
                // Do the actual work.
1311 14ad7326 pastith
                final List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
1312 14ad7326 pastith
                final List<FileHeader> files = dao.getDeletedFiles(userId);
1313 14ad7326 pastith
                for (final FileHeader f : files)
1314 14ad7326 pastith
                        result.add(f.getDTO());
1315 14ad7326 pastith
                return result;
1316 14ad7326 pastith
        }
1317 14ad7326 pastith
1318 14ad7326 pastith
        @Override
1319 14ad7326 pastith
        public void removeFileFromTrash(Long userId, Long fileId)
1320 14ad7326 pastith
                        throws ObjectNotFoundException, InsufficientPermissionsException {
1321 14ad7326 pastith
                if (userId == null)
1322 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1323 14ad7326 pastith
                if (fileId == null)
1324 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
1325 14ad7326 pastith
1326 14ad7326 pastith
                // Do the actual work.
1327 14ad7326 pastith
                FileHeader file = dao.getEntityById(FileHeader.class, fileId);
1328 14ad7326 pastith
                Folder parent = file.getFolder();
1329 14ad7326 pastith
                if (parent == null)
1330 14ad7326 pastith
                        throw new ObjectNotFoundException("The specified file has no parent folder");
1331 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1332 14ad7326 pastith
                if (!file.hasDeletePermission(user))
1333 14ad7326 pastith
                        throw new InsufficientPermissionsException("User " + user.getUsername() +
1334 14ad7326 pastith
                                                " cannot restore file " + file.getName());
1335 14ad7326 pastith
1336 14ad7326 pastith
                file.setDeleted(false);
1337 14ad7326 pastith
                dao.update(file);
1338 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, user, new Date());
1339 14ad7326 pastith
        }
1340 14ad7326 pastith
1341 14ad7326 pastith
        @Override
1342 14ad7326 pastith
        public void moveFolderToTrash(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
1343 14ad7326 pastith
                if (userId == null)
1344 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1345 14ad7326 pastith
                if (folderId == null)
1346 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1347 14ad7326 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
1348 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1349 14ad7326 pastith
                if (!folder.hasDeletePermission(user))
1350 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
1351 14ad7326 pastith
                folder.setDeleted(true);
1352 14ad7326 pastith
                dao.update(folder);
1353 f22e4d5d Dimitris Routsis
                touchParentFolders(folder, user, new Date());
1354 14ad7326 pastith
                for (FileHeader file : folder.getFiles())
1355 14ad7326 pastith
                        moveFileToTrash(userId, file.getId());
1356 14ad7326 pastith
                for (Folder subFolder : folder.getSubfolders())
1357 14ad7326 pastith
                        moveFolderToTrash(userId, subFolder.getId());
1358 14ad7326 pastith
1359 14ad7326 pastith
        }
1360 14ad7326 pastith
1361 14ad7326 pastith
        @Override
1362 14ad7326 pastith
        public void removeFolderFromTrash(Long userId, Long folderId)
1363 14ad7326 pastith
                        throws ObjectNotFoundException, InsufficientPermissionsException {
1364 14ad7326 pastith
                if (userId == null)
1365 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1366 14ad7326 pastith
                if (folderId == null)
1367 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1368 14ad7326 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
1369 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1370 14ad7326 pastith
                if (!folder.hasDeletePermission(user))
1371 14ad7326 pastith
                        throw new InsufficientPermissionsException("User " + user.getUsername() +
1372 14ad7326 pastith
                                                " cannot restore folder " + folder.getName());
1373 14ad7326 pastith
                folder.setDeleted(false);
1374 14ad7326 pastith
                for (FileHeader file : folder.getFiles())
1375 14ad7326 pastith
                        removeFileFromTrash(userId, file.getId());
1376 14ad7326 pastith
                for (Folder subFolder : folder.getSubfolders())
1377 14ad7326 pastith
                        removeFolderFromTrash(userId, subFolder.getId());
1378 14ad7326 pastith
                dao.update(folder);
1379 f22e4d5d Dimitris Routsis
                touchParentFolders(folder, user, new Date());
1380 14ad7326 pastith
        }
1381 14ad7326 pastith
1382 14ad7326 pastith
        @Override
1383 14ad7326 pastith
        public List<FolderDTO> getDeletedRootFolders(Long userId) throws ObjectNotFoundException {
1384 14ad7326 pastith
                List<Folder> folders = dao.getDeletedRootFolders(userId);
1385 14ad7326 pastith
                List<FolderDTO> result = new ArrayList<FolderDTO>();
1386 14ad7326 pastith
                for (Folder folder : folders)
1387 68410d59 pastith
                        result.add(folder.getDTO());
1388 14ad7326 pastith
                return result;
1389 14ad7326 pastith
        }
1390 14ad7326 pastith
1391 68410d59 pastith
        @Override
1392 14ad7326 pastith
        public void emptyTrash(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException {
1393 14ad7326 pastith
                List<FolderDTO> deletedRootFolders = getDeletedRootFolders(userId);
1394 14ad7326 pastith
                for (FolderDTO fdto : deletedRootFolders)
1395 14ad7326 pastith
                        deleteFolder(userId, fdto.getId());
1396 14ad7326 pastith
                List<FileHeaderDTO> deletedFiles = getDeletedFiles(userId);
1397 14ad7326 pastith
                for (FileHeaderDTO filedto : deletedFiles)
1398 14ad7326 pastith
                        deleteFile(userId, filedto.getId());
1399 14ad7326 pastith
        }
1400 14ad7326 pastith
1401 14ad7326 pastith
        @Override
1402 14ad7326 pastith
        public void restoreTrash(Long userId) throws ObjectNotFoundException, InsufficientPermissionsException {
1403 14ad7326 pastith
                List<FolderDTO> deletedRootFolders = getDeletedRootFolders(userId);
1404 14ad7326 pastith
                for (FolderDTO fdto : deletedRootFolders)
1405 14ad7326 pastith
                        removeFolderFromTrash(userId, fdto.getId());
1406 14ad7326 pastith
                List<FileHeaderDTO> deletedFiles = getDeletedFiles(userId);
1407 14ad7326 pastith
                for (FileHeaderDTO filedto : deletedFiles)
1408 14ad7326 pastith
                        removeFileFromTrash(userId, filedto.getId());
1409 14ad7326 pastith
        }
1410 14ad7326 pastith
1411 14ad7326 pastith
        @Override
1412 533ade50 Panagiotis Astithas
        public User createUser(String username, String name, String mail,
1413 c35f359f Panagiotis Astithas
                                String idp, String idpid) throws ObjectNotFoundException {
1414 14ad7326 pastith
                if (username == null)
1415 14ad7326 pastith
                        throw new ObjectNotFoundException("No username specified");
1416 14ad7326 pastith
                if (name == null)
1417 14ad7326 pastith
                        throw new ObjectNotFoundException("No name specified");
1418 14ad7326 pastith
1419 14ad7326 pastith
                User user = new User();
1420 14ad7326 pastith
                user.setUsername(username);
1421 14ad7326 pastith
                user.setName(name);
1422 14ad7326 pastith
                user.setEmail(mail);
1423 c35f359f Panagiotis Astithas
                user.setIdentityProvider(idp);
1424 c35f359f Panagiotis Astithas
                user.setIdentityProviderId(idpid);
1425 14ad7326 pastith
                Date now = new Date();
1426 14ad7326 pastith
                AuditInfo auditInfo = new AuditInfo();
1427 14ad7326 pastith
                auditInfo.setCreationDate(now);
1428 14ad7326 pastith
                auditInfo.setModificationDate(now);
1429 14ad7326 pastith
                user.setAuditInfo(auditInfo);
1430 14ad7326 pastith
                user.generateAuthToken();
1431 3ef7b691 Dimitris Routsis
                user.generateWebDAVPassword();
1432 01a30cd0 Panagiotis Astithas
                // Set the default user class to the one with the lowest quota.
1433 01a30cd0 Panagiotis Astithas
                user.setUserClass(getUserClasses().get(0));
1434 14ad7326 pastith
                dao.create(user);
1435 14ad7326 pastith
                // Make sure we get an ID in the user object.
1436 14ad7326 pastith
                dao.flush();
1437 14ad7326 pastith
                // Create the root folder for the user.
1438 14ad7326 pastith
                createFolder(user.getName(), null, user);
1439 14ad7326 pastith
                return user;
1440 14ad7326 pastith
        }
1441 14ad7326 pastith
1442 14ad7326 pastith
        @Override
1443 01a30cd0 Panagiotis Astithas
        public List<UserClass> getUserClasses() {
1444 01a30cd0 Panagiotis Astithas
                List<UserClass> classes = dao.getUserClasses();
1445 01a30cd0 Panagiotis Astithas
                // Create a default user class for first-time use. Afterwards, the
1446 01a30cd0 Panagiotis Astithas
                // admin should modify or add to the userclass table.
1447 01a30cd0 Panagiotis Astithas
                if (classes.size() == 0) {
1448 01a30cd0 Panagiotis Astithas
                        UserClass defaultClass = new UserClass();
1449 01a30cd0 Panagiotis Astithas
                        defaultClass.setName("default");
1450 01a30cd0 Panagiotis Astithas
                        Long defaultQuota = getConfiguration().getLong("quota", new Long(52428800L));
1451 01a30cd0 Panagiotis Astithas
                        defaultClass.setQuota(defaultQuota);
1452 01a30cd0 Panagiotis Astithas
                        dao.create(defaultClass);
1453 01a30cd0 Panagiotis Astithas
                        classes.add(defaultClass);
1454 01a30cd0 Panagiotis Astithas
                }
1455 01a30cd0 Panagiotis Astithas
                return classes;
1456 01a30cd0 Panagiotis Astithas
        }
1457 01a30cd0 Panagiotis Astithas
1458 01a30cd0 Panagiotis Astithas
        @Override
1459 3eaf782f pastith
        public User findUserByEmail(String email) {
1460 3eaf782f pastith
                return dao.findUserByEmail(email);
1461 3eaf782f pastith
        }
1462 3eaf782f pastith
1463 3eaf782f pastith
        @Override
1464 3eaf782f pastith
        public void updateUser(User user) {
1465 3eaf782f pastith
                dao.update(user);
1466 3eaf782f pastith
        }
1467 3eaf782f pastith
1468 3eaf782f pastith
        @Override
1469 14ad7326 pastith
        public User findUser(String username) {
1470 14ad7326 pastith
                if (username == null)
1471 14ad7326 pastith
                        return null;
1472 14ad7326 pastith
                return dao.findUser(username);
1473 14ad7326 pastith
        }
1474 14ad7326 pastith
1475 14ad7326 pastith
        @Override
1476 14ad7326 pastith
        public User updateUserToken(Long userId) throws ObjectNotFoundException {
1477 14ad7326 pastith
                if (userId == null)
1478 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1479 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1480 14ad7326 pastith
                user.generateAuthToken();
1481 14ad7326 pastith
                return user;
1482 14ad7326 pastith
        }
1483 14ad7326 pastith
1484 14ad7326 pastith
        @Override
1485 14ad7326 pastith
        public Set<PermissionDTO> getFolderPermissions(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
1486 14ad7326 pastith
                if (userId == null)
1487 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1488 14ad7326 pastith
                if (folderId == null)
1489 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1490 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1491 14ad7326 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
1492 14ad7326 pastith
                if(!folder.hasReadPermission(user))
1493 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
1494 14ad7326 pastith
                Set<Permission> perms = folder.getPermissions();
1495 14ad7326 pastith
                Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
1496 14ad7326 pastith
                for (Permission perm : perms)
1497 14ad7326 pastith
                        if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId()))
1498 14ad7326 pastith
                                result.add(perm.getDTO());
1499 14ad7326 pastith
                for (Permission perm : perms)
1500 14ad7326 pastith
                        if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId())) {
1501 14ad7326 pastith
                        } else
1502 14ad7326 pastith
                                result.add(perm.getDTO());
1503 14ad7326 pastith
                return result;
1504 14ad7326 pastith
1505 14ad7326 pastith
        }
1506 14ad7326 pastith
1507 ba5f9575 Panagiotis Astithas
        /**
1508 ba5f9575 Panagiotis Astithas
         * Set the provided permissions as the new permissions of the specified
1509 ba5f9575 Panagiotis Astithas
         * folder.
1510 ba5f9575 Panagiotis Astithas
         *
1511 ba5f9575 Panagiotis Astithas
         * @param user
1512 ba5f9575 Panagiotis Astithas
         * @param folder
1513 ba5f9575 Panagiotis Astithas
         * @param permissions
1514 ba5f9575 Panagiotis Astithas
         * @throws ObjectNotFoundException
1515 ba5f9575 Panagiotis Astithas
         * @throws InsufficientPermissionsException
1516 14ad7326 pastith
         */
1517 ba5f9575 Panagiotis Astithas
        private void setFolderPermissions(User user, Folder folder, Set<PermissionDTO> permissions) throws ObjectNotFoundException, InsufficientPermissionsException {
1518 7a1c02de Panagiotis Astithas
                if (permissions != null && !permissions.isEmpty()) {
1519 7a1c02de Panagiotis Astithas
                        User owner = folder.getOwner();
1520 7a1c02de Panagiotis Astithas
                        PermissionDTO ownerPerm = null;
1521 7a1c02de Panagiotis Astithas
                        for (PermissionDTO dto : permissions)
1522 7a1c02de Panagiotis Astithas
                                if (dto.getUser() != null && dto.getUser().getId().equals(owner.getId())) {
1523 7a1c02de Panagiotis Astithas
                                        ownerPerm = dto;
1524 7a1c02de Panagiotis Astithas
                                        break;
1525 7a1c02de Panagiotis Astithas
                                }
1526 7a1c02de Panagiotis Astithas
                        if (ownerPerm == null || !ownerPerm.hasRead() || !ownerPerm.hasWrite() || !ownerPerm.hasModifyACL())
1527 7a1c02de Panagiotis Astithas
                                throw new InsufficientPermissionsException("Can't remove permissions from owner");
1528 7a1c02de Panagiotis Astithas
                        // Delete previous entries
1529 7a1c02de Panagiotis Astithas
                        for (Permission perm: folder.getPermissions())
1530 7a1c02de Panagiotis Astithas
                                dao.delete(perm);
1531 7a1c02de Panagiotis Astithas
                        folder.getPermissions().clear();
1532 7a1c02de Panagiotis Astithas
                        for (PermissionDTO dto : permissions) {
1533 7a1c02de Panagiotis Astithas
                                // Skip 'empty' permission entries.
1534 7a1c02de Panagiotis Astithas
                                if (!dto.getRead() && !dto.getWrite() && !dto.getModifyACL()) continue;
1535 7a1c02de Panagiotis Astithas
                                folder.addPermission(getPermission(dto));
1536 7a1c02de Panagiotis Astithas
                        }
1537 7a1c02de Panagiotis Astithas
                        dao.update(folder);
1538 7a1c02de Panagiotis Astithas
                        for (FileHeader file : folder.getFiles()) {
1539 7a1c02de Panagiotis Astithas
                                setFilePermissions(file, permissions);
1540 7a1c02de Panagiotis Astithas
                                Date now = new Date();
1541 7a1c02de Panagiotis Astithas
                                file.getAuditInfo().setModificationDate(now);
1542 7a1c02de Panagiotis Astithas
                                file.getAuditInfo().setModifiedBy(user);
1543 7a1c02de Panagiotis Astithas
                        }
1544 7a1c02de Panagiotis Astithas
                        for (Folder sub : folder.getSubfolders())
1545 7a1c02de Panagiotis Astithas
                                setFolderPermissions(user, sub, permissions);
1546 ba5f9575 Panagiotis Astithas
                }
1547 14ad7326 pastith
        }
1548 14ad7326 pastith
1549 14ad7326 pastith
        private Permission getPermission(PermissionDTO dto) throws ObjectNotFoundException {
1550 14ad7326 pastith
                Permission res = new Permission();
1551 14ad7326 pastith
                if (dto.getGroup() != null)
1552 14ad7326 pastith
                        res.setGroup(dao.getEntityById(Group.class, dto.getGroup().getId()));
1553 14ad7326 pastith
                else if (dto.getUser() != null)
1554 14ad7326 pastith
                        if (dto.getUser().getId() == null)
1555 14ad7326 pastith
                                res.setUser(dao.getUser(dto.getUser().getUsername()));
1556 14ad7326 pastith
                        else
1557 14ad7326 pastith
                                res.setUser(dao.getEntityById(User.class, dto.getUser().getId()));
1558 14ad7326 pastith
                res.setRead(dto.hasRead());
1559 14ad7326 pastith
                res.setWrite(dto.hasWrite());
1560 14ad7326 pastith
                res.setModifyACL(dto.hasModifyACL());
1561 14ad7326 pastith
                return res;
1562 14ad7326 pastith
        }
1563 14ad7326 pastith
1564 14ad7326 pastith
        /* (non-Javadoc)
1565 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getUsersByUserNameLike(java.lang.String)
1566 14ad7326 pastith
         */
1567 14ad7326 pastith
        @Override
1568 14ad7326 pastith
        public List<UserDTO> getUsersByUserNameLike(String username) {
1569 14ad7326 pastith
                List<User> users = dao.getUsersByUserNameLike(username);
1570 14ad7326 pastith
                List<UserDTO> result = new ArrayList<UserDTO>();
1571 14ad7326 pastith
                for (User u : users)
1572 14ad7326 pastith
                        result.add(u.getDTO());
1573 14ad7326 pastith
                return result;
1574 14ad7326 pastith
1575 14ad7326 pastith
        }
1576 14ad7326 pastith
1577 14ad7326 pastith
        /* (non-Javadoc)
1578 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#addUserToGroup(java.lang.Long, java.lang.Long, java.lang.Long)
1579 14ad7326 pastith
         */
1580 14ad7326 pastith
        @Override
1581 14ad7326 pastith
        public void addUserToGroup(Long userId, Long groupId, Long userToAddId) throws ObjectNotFoundException, DuplicateNameException, InsufficientPermissionsException {
1582 14ad7326 pastith
                if (userId == null)
1583 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1584 14ad7326 pastith
                if (groupId == null)
1585 14ad7326 pastith
                        throw new ObjectNotFoundException("No group specified");
1586 14ad7326 pastith
                if (userToAddId == null)
1587 14ad7326 pastith
                        throw new ObjectNotFoundException("No user to add specified");
1588 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1589 14ad7326 pastith
                Group group = dao.getEntityById(Group.class, groupId);
1590 14ad7326 pastith
                if (!group.getOwner().equals(user))
1591 14ad7326 pastith
                        throw new InsufficientPermissionsException();
1592 14ad7326 pastith
                User userToAdd = dao.getEntityById(User.class, userToAddId);
1593 14ad7326 pastith
                if (group.contains(userToAdd))
1594 14ad7326 pastith
                        throw new DuplicateNameException("User already exists in group");
1595 14ad7326 pastith
                group.getMembers().add(userToAdd);
1596 14ad7326 pastith
                dao.update(group);
1597 14ad7326 pastith
1598 14ad7326 pastith
        }
1599 14ad7326 pastith
1600 14ad7326 pastith
        @Override
1601 14ad7326 pastith
        public void invalidateUserToken(Long userId) throws ObjectNotFoundException {
1602 14ad7326 pastith
                if (userId == null)
1603 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1604 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1605 14ad7326 pastith
                user.invalidateAuthToken();
1606 14ad7326 pastith
                return;
1607 14ad7326 pastith
        }
1608 14ad7326 pastith
1609 14ad7326 pastith
        @Override
1610 14ad7326 pastith
        public List<FolderDTO> getSharedRootFolders(Long userId) throws ObjectNotFoundException {
1611 14ad7326 pastith
                if (userId == null)
1612 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1613 14ad7326 pastith
                List<Folder> folders = dao.getSharedRootFolders(userId);
1614 14ad7326 pastith
                List<FolderDTO> result = new ArrayList<FolderDTO>();
1615 68410d59 pastith
                for (Folder f : folders) {
1616 68410d59 pastith
                        FolderDTO dto = f.getDTO();
1617 68410d59 pastith
                        dto.setSubfolders(getSharedSubfolders(userId, f.getId()));
1618 68410d59 pastith
                        result.add(dto);
1619 68410d59 pastith
                }
1620 14ad7326 pastith
                return result;
1621 14ad7326 pastith
        }
1622 14ad7326 pastith
1623 14ad7326 pastith
        /* (non-Javadoc)
1624 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#removeMemberFromGroup(java.lang.Long, java.lang.Long, java.lang.Long)
1625 14ad7326 pastith
         */
1626 14ad7326 pastith
        @Override
1627 14ad7326 pastith
        public void removeMemberFromGroup(Long userId, Long groupId, Long memberId) throws ObjectNotFoundException, InsufficientPermissionsException {
1628 14ad7326 pastith
                if (userId == null)
1629 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1630 14ad7326 pastith
                if (groupId == null)
1631 14ad7326 pastith
                        throw new ObjectNotFoundException("No group specified");
1632 14ad7326 pastith
                if (memberId == null)
1633 14ad7326 pastith
                        throw new ObjectNotFoundException("No member specified");
1634 14ad7326 pastith
                User owner = dao.getEntityById(User.class, userId);
1635 14ad7326 pastith
                Group group = dao.getEntityById(Group.class, groupId);
1636 14ad7326 pastith
                User member = dao.getEntityById(User.class, memberId);
1637 14ad7326 pastith
                if (!group.getOwner().equals(owner))
1638 14ad7326 pastith
                        throw new InsufficientPermissionsException("User is not the owner of the group");
1639 14ad7326 pastith
                group.removeMemberFromGroup(member);
1640 14ad7326 pastith
                dao.update(group);
1641 14ad7326 pastith
1642 14ad7326 pastith
        }
1643 14ad7326 pastith
1644 14ad7326 pastith
        @Override
1645 14ad7326 pastith
        public List<UserDTO> getUsersSharingFoldersForUser(Long userId) throws ObjectNotFoundException {
1646 14ad7326 pastith
                List<User> users = dao.getUsersSharingFoldersForUser(userId);
1647 14ad7326 pastith
                List<User> usersFiles = dao.getUsersSharingFilesForUser(userId);
1648 14ad7326 pastith
                List<UserDTO> res = new ArrayList<UserDTO>();
1649 14ad7326 pastith
                for (User u : users)
1650 14ad7326 pastith
                        res.add(u.getDTO());
1651 14ad7326 pastith
                for(User fu : usersFiles)
1652 14ad7326 pastith
                        if(!users.contains(fu))
1653 14ad7326 pastith
                                res.add(fu.getDTO());
1654 14ad7326 pastith
                return res;
1655 14ad7326 pastith
        }
1656 14ad7326 pastith
1657 14ad7326 pastith
        @Override
1658 14ad7326 pastith
        public Set<PermissionDTO> getFilePermissions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
1659 14ad7326 pastith
                if (userId == null)
1660 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1661 14ad7326 pastith
                if (fileId == null)
1662 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1663 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1664 14ad7326 pastith
                FileHeader folder = dao.getEntityById(FileHeader.class, fileId);
1665 14ad7326 pastith
                if(!folder.hasReadPermission(user))
1666 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
1667 14ad7326 pastith
                Set<Permission> perms = folder.getPermissions();
1668 14ad7326 pastith
                Set<PermissionDTO> result = new LinkedHashSet<PermissionDTO>();
1669 14ad7326 pastith
                for (Permission perm : perms)
1670 14ad7326 pastith
                        if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId()))
1671 14ad7326 pastith
                                result.add(perm.getDTO());
1672 14ad7326 pastith
                for (Permission perm : perms)
1673 14ad7326 pastith
                        if (perm.getUser() != null && perm.getUser().getId().equals(folder.getOwner().getId())) {
1674 14ad7326 pastith
                        } else
1675 14ad7326 pastith
                                result.add(perm.getDTO());
1676 14ad7326 pastith
                return result;
1677 14ad7326 pastith
        }
1678 14ad7326 pastith
1679 ba5f9575 Panagiotis Astithas
        /**
1680 ba5f9575 Panagiotis Astithas
         * Set the provided permissions as the new permissions of the specified
1681 ba5f9575 Panagiotis Astithas
         * file. This method sets the modification date/user attributes to the
1682 ba5f9575 Panagiotis Astithas
         * current values as a side effect.
1683 ba5f9575 Panagiotis Astithas
         *
1684 ba5f9575 Panagiotis Astithas
         * @param file
1685 ba5f9575 Panagiotis Astithas
         * @param permissions
1686 ba5f9575 Panagiotis Astithas
         * @throws ObjectNotFoundException
1687 ba5f9575 Panagiotis Astithas
         * @throws InsufficientPermissionsException
1688 ba5f9575 Panagiotis Astithas
         */
1689 ba5f9575 Panagiotis Astithas
        private void setFilePermissions(FileHeader file,
1690 ba5f9575 Panagiotis Astithas
                                Set<PermissionDTO> permissions)
1691 ba5f9575 Panagiotis Astithas
                        throws ObjectNotFoundException, InsufficientPermissionsException {
1692 ba5f9575 Panagiotis Astithas
                if (permissions != null && !permissions.isEmpty()) {
1693 d50c0133 Panagiotis Astithas
                        PermissionDTO ownerPerm = null;
1694 d50c0133 Panagiotis Astithas
                        for (PermissionDTO dto : permissions)
1695 d50c0133 Panagiotis Astithas
                                if (dto.getUser() != null && dto.getUser().getId().equals(file.getOwner().getId())) {
1696 d50c0133 Panagiotis Astithas
                                        ownerPerm = dto;
1697 d50c0133 Panagiotis Astithas
                                        break;
1698 d50c0133 Panagiotis Astithas
                                }
1699 d50c0133 Panagiotis Astithas
                        if (ownerPerm == null || !ownerPerm.hasRead() || !ownerPerm.hasWrite() || !ownerPerm.hasModifyACL())
1700 d50c0133 Panagiotis Astithas
                                throw new InsufficientPermissionsException("Can't remove permissions from owner");
1701 ba5f9575 Panagiotis Astithas
                        // Delete previous entries.
1702 ba5f9575 Panagiotis Astithas
                        for (Permission perm: file.getPermissions())
1703 ba5f9575 Panagiotis Astithas
                                dao.delete(perm);
1704 ba5f9575 Panagiotis Astithas
                        file.getPermissions().clear();
1705 ba5f9575 Panagiotis Astithas
                        for (PermissionDTO dto : permissions) {
1706 d50c0133 Panagiotis Astithas
                                // Skip 'empty' permission entries.
1707 ba5f9575 Panagiotis Astithas
                                if (!dto.getRead() && !dto.getWrite() && !dto.getModifyACL()) continue;
1708 ba5f9575 Panagiotis Astithas
                                file.addPermission(getPermission(dto));
1709 3da65b2c droutsis
                        }
1710 ba5f9575 Panagiotis Astithas
                        dao.flush();
1711 66c7511a Dimitris Routsis
                }
1712 14ad7326 pastith
        }
1713 14ad7326 pastith
1714 14ad7326 pastith
        @Override
1715 14ad7326 pastith
        public List<FileHeaderDTO> getSharedFilesNotInSharedFolders(Long userId) throws ObjectNotFoundException {
1716 14ad7326 pastith
                if (userId == null)
1717 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1718 14ad7326 pastith
                List<FileHeader> files = dao.getSharedFilesNotInSharedFolders(userId);
1719 14ad7326 pastith
                List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
1720 14ad7326 pastith
                for (FileHeader f : files)
1721 14ad7326 pastith
                        result.add(f.getDTO());
1722 14ad7326 pastith
                return result;
1723 14ad7326 pastith
        }
1724 14ad7326 pastith
1725 14ad7326 pastith
        @Override
1726 14ad7326 pastith
        public List<FileHeaderDTO> getSharedFiles(Long userId) throws ObjectNotFoundException {
1727 14ad7326 pastith
                if (userId == null)
1728 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1729 14ad7326 pastith
                List<FileHeader> files = dao.getSharedFiles(userId);
1730 14ad7326 pastith
                List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
1731 14ad7326 pastith
                for (FileHeader f : files)
1732 14ad7326 pastith
                        result.add(f.getDTO());
1733 14ad7326 pastith
                return result;
1734 14ad7326 pastith
        }
1735 14ad7326 pastith
1736 14ad7326 pastith
        @Override
1737 14ad7326 pastith
        public List<FolderDTO> getSharedFolders(Long userId) throws ObjectNotFoundException {
1738 14ad7326 pastith
                if (userId == null)
1739 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1740 14ad7326 pastith
                List<Folder> folders = dao.getSharedFolders(userId);
1741 14ad7326 pastith
                List<FolderDTO> result = new ArrayList<FolderDTO>();
1742 14ad7326 pastith
                for (Folder f : folders)
1743 14ad7326 pastith
                        result.add(f.getDTO());
1744 14ad7326 pastith
                return result;
1745 14ad7326 pastith
        }
1746 14ad7326 pastith
1747 14ad7326 pastith
        /* (non-Javadoc)
1748 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getSharedFiles(java.lang.Long, java.lang.Long)
1749 14ad7326 pastith
         */
1750 14ad7326 pastith
        @Override
1751 14ad7326 pastith
        public List<FileHeaderDTO> getSharedFiles(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
1752 14ad7326 pastith
                if (ownerId == null)
1753 14ad7326 pastith
                        throw new ObjectNotFoundException("No owner specified");
1754 14ad7326 pastith
                if (callingUserId == null)
1755 14ad7326 pastith
                        throw new ObjectNotFoundException("No calling user specified");
1756 14ad7326 pastith
                List<FileHeader> folders = dao.getSharedFiles(ownerId, callingUserId);
1757 14ad7326 pastith
                List<FileHeaderDTO> result = new ArrayList<FileHeaderDTO>();
1758 14ad7326 pastith
                for (FileHeader f : folders)
1759 14ad7326 pastith
                        result.add(f.getDTO());
1760 14ad7326 pastith
                return result;
1761 14ad7326 pastith
        }
1762 14ad7326 pastith
1763 14ad7326 pastith
        @Override
1764 14ad7326 pastith
        public List<FolderDTO> getSharedRootFolders(Long ownerId, Long callingUserId) throws ObjectNotFoundException {
1765 14ad7326 pastith
                if (ownerId == null)
1766 14ad7326 pastith
                        throw new ObjectNotFoundException("No owner specified");
1767 14ad7326 pastith
                if (callingUserId == null)
1768 14ad7326 pastith
                        throw new ObjectNotFoundException("No calling user specified");
1769 14ad7326 pastith
                List<Folder> folders = dao.getSharedRootFolders(ownerId, callingUserId);
1770 14ad7326 pastith
                List<FolderDTO> result = new ArrayList<FolderDTO>();
1771 68410d59 pastith
                for (Folder f : folders) {
1772 68410d59 pastith
                        FolderDTO dto = f.getDTO();
1773 68410d59 pastith
                        dto.setSubfolders(getSharedSubfolders(ownerId, callingUserId, f.getId()));
1774 68410d59 pastith
                        result.add(dto);
1775 68410d59 pastith
                }
1776 14ad7326 pastith
                return result;
1777 14ad7326 pastith
1778 14ad7326 pastith
        }
1779 14ad7326 pastith
1780 14ad7326 pastith
        @Override
1781 14ad7326 pastith
        public List<FolderDTO> getSharedSubfolders(Long userId, Long folderId) throws ObjectNotFoundException {
1782 14ad7326 pastith
                if (userId == null)
1783 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1784 14ad7326 pastith
                if (folderId == null)
1785 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1786 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
1787 14ad7326 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
1788 14ad7326 pastith
                List<FolderDTO> result = new ArrayList<FolderDTO>();
1789 14ad7326 pastith
                if (folder.isShared(user))
1790 14ad7326 pastith
                        for (Folder f : folder.getSubfolders())
1791 14ad7326 pastith
                                if (f.isShared(user) && !f.isDeleted())
1792 14ad7326 pastith
                                        result.add(f.getDTO());
1793 14ad7326 pastith
                return result;
1794 14ad7326 pastith
        }
1795 14ad7326 pastith
1796 14ad7326 pastith
        @Override
1797 14ad7326 pastith
        public List<FolderDTO> getSharedSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException {
1798 14ad7326 pastith
                if (userId == null)
1799 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1800 14ad7326 pastith
                if (callingUserId == null)
1801 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1802 14ad7326 pastith
                if (folderId == null)
1803 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
1804 14ad7326 pastith
                User user = dao.getEntityById(User.class, callingUserId);
1805 14ad7326 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
1806 14ad7326 pastith
                List<FolderDTO> result = new ArrayList<FolderDTO>();
1807 14ad7326 pastith
                if (folder.isSharedForOtherUser(user))
1808 14ad7326 pastith
                        for (Folder f : folder.getSubfolders())
1809 14ad7326 pastith
                                if (f.isSharedForOtherUser(user) && !f.isDeleted()){
1810 14ad7326 pastith
                                        FolderDTO dto = f.getDTO();
1811 14ad7326 pastith
                                        dto.setSubfolders(getSharedSubfolders(userId, callingUserId, dto.getId()));
1812 14ad7326 pastith
                                        result.add(dto);
1813 14ad7326 pastith
                                }
1814 14ad7326 pastith
                return result;
1815 14ad7326 pastith
1816 14ad7326 pastith
        }
1817 14ad7326 pastith
1818 14ad7326 pastith
        /* (non-Javadoc)
1819 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#searchFiles(java.lang.Long, java.lang.String)
1820 14ad7326 pastith
         */
1821 14ad7326 pastith
        @Override
1822 14ad7326 pastith
        public List<FileHeaderDTO> searchFiles(Long userId, String query) throws ObjectNotFoundException {
1823 14ad7326 pastith
                if (userId == null)
1824 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1825 14ad7326 pastith
                User user = getUser(userId);
1826 14ad7326 pastith
                if (query == null)
1827 14ad7326 pastith
                        throw new ObjectNotFoundException("No query specified");
1828 14ad7326 pastith
                List<FileHeader> files = search(user.getId(), query);
1829 14ad7326 pastith
                List<FileHeaderDTO> res = new ArrayList<FileHeaderDTO>();
1830 14ad7326 pastith
                for(FileHeader f : files)
1831 14ad7326 pastith
                        res.add(f.getDTO());
1832 14ad7326 pastith
                return res;
1833 14ad7326 pastith
        }
1834 14ad7326 pastith
1835 14ad7326 pastith
        /**
1836 14ad7326 pastith
         * Performs the actuals search on the solr server and returns the results
1837 14ad7326 pastith
         *
1838 14ad7326 pastith
         * We have to use the dismax query type (instead of the
1839 14ad7326 pastith
         * standard) because it allows for search time field boosting. This is because we can't use indexing
1840 14ad7326 pastith
         * time field boosting due to the patched rich indexing API that does not allow it
1841 14ad7326 pastith
         *
1842 14ad7326 pastith
         * @param userId
1843 14ad7326 pastith
         * @param query
1844 14ad7326 pastith
         * @return a List of FileHeader objects
1845 14ad7326 pastith
         */
1846 14ad7326 pastith
        private List<FileHeader> search(Long userId, String query) {
1847 14ad7326 pastith
                try {
1848 14ad7326 pastith
                        HttpClient httpClient = new HttpClient();
1849 14ad7326 pastith
1850 bde4eafb pastith
                        GetMethod method = new GetMethod(getConfiguration().getString("solrSelectUrl"));
1851 14ad7326 pastith
                        NameValuePair[] params = {new NameValuePair("qt", "dismax"),
1852 14ad7326 pastith
                                                                                new NameValuePair("q", query),
1853 14ad7326 pastith
                                                                                new NameValuePair("sort", "score desc"),
1854 14ad7326 pastith
                                                                                new NameValuePair("indent", "on")};
1855 14ad7326 pastith
                        method.setQueryString(params);
1856 14ad7326 pastith
                        int retryCount = 0;
1857 14ad7326 pastith
                        int statusCode = 0;
1858 14ad7326 pastith
                        String response = null;
1859 14ad7326 pastith
                        do {
1860 14ad7326 pastith
                                statusCode = httpClient.executeMethod(method);
1861 14ad7326 pastith
                                logger.debug("HTTP status: " + statusCode);
1862 14ad7326 pastith
                                response = method.getResponseBodyAsString();
1863 14ad7326 pastith
                                logger.debug(response);
1864 14ad7326 pastith
                                retryCount++;
1865 14ad7326 pastith
                                if (statusCode != 200 && retryCount < 3)
1866 14ad7326 pastith
                                        try {
1867 14ad7326 pastith
                                                Thread.sleep(3000); //Give Solr a little time to be available
1868 14ad7326 pastith
                                        } catch (InterruptedException e) {
1869 14ad7326 pastith
                                        }
1870 14ad7326 pastith
                        } while (statusCode != 200 && retryCount < 3);
1871 14ad7326 pastith
                        if (statusCode != 200)
1872 14ad7326 pastith
                                throw new EJBException("Search query return error:\n" + response);
1873 14ad7326 pastith
1874 14ad7326 pastith
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
1875 14ad7326 pastith
                        DocumentBuilder db = dbf.newDocumentBuilder();
1876 14ad7326 pastith
                        Document doc = db.parse(method.getResponseBodyAsStream());
1877 14ad7326 pastith
                        method.releaseConnection();
1878 14ad7326 pastith
1879 14ad7326 pastith
                        Node root = doc.getElementsByTagName("response").item(0);
1880 14ad7326 pastith
                        Node lst = root.getFirstChild().getNextSibling();
1881 14ad7326 pastith
                        Node status = lst.getFirstChild().getNextSibling();
1882 14ad7326 pastith
                        if (status.getAttributes().getNamedItem("name").getNodeValue().equals("status") &&
1883 14ad7326 pastith
                                status.getTextContent().equals("0")) {
1884 14ad7326 pastith
                                List<FileHeader> fileResult = new ArrayList<FileHeader>();
1885 14ad7326 pastith
                                Node result = lst.getNextSibling().getNextSibling();
1886 14ad7326 pastith
                                NodeList docs = result.getChildNodes();
1887 14ad7326 pastith
                                User user = getUser(userId);
1888 14ad7326 pastith
                                for (int i=1; i<docs.getLength(); i=i+2) {
1889 14ad7326 pastith
                                        Node d = docs.item(i);
1890 14ad7326 pastith
                                        NodeList docData = d.getChildNodes();
1891 14ad7326 pastith
                                        for (int j=1; j<docData.getLength(); j=j+2) {
1892 14ad7326 pastith
                                                Node dd = docData.item(j);
1893 14ad7326 pastith
                                                if (dd.getAttributes().item(0).getNodeName().equals("name") &&
1894 14ad7326 pastith
                                                        dd.getAttributes().item(0).getNodeValue().equals("id")) {
1895 14ad7326 pastith
                                                        Long fileId = Long.valueOf(dd.getTextContent());
1896 14ad7326 pastith
                                                        try {
1897 14ad7326 pastith
                                                                FileHeader file = dao.getEntityById(FileHeader.class, fileId);
1898 14ad7326 pastith
                                                                if (file.hasReadPermission(user)) {
1899 14ad7326 pastith
                                                                        fileResult.add(file);
1900 14ad7326 pastith
                                                                        logger.debug("File added " + fileId);
1901 14ad7326 pastith
                                                                }
1902 14ad7326 pastith
                                                        } catch (ObjectNotFoundException e) {
1903 14ad7326 pastith
                                                                logger.warn("Search result not found", e);
1904 14ad7326 pastith
                                                        }
1905 14ad7326 pastith
                                                }
1906 14ad7326 pastith
                                        }
1907 14ad7326 pastith
                                }
1908 14ad7326 pastith
                                return fileResult;
1909 14ad7326 pastith
                        }
1910 14ad7326 pastith
                        throw new EJBException();
1911 14ad7326 pastith
                } catch (HttpException e) {
1912 14ad7326 pastith
                        throw new EJBException(e);
1913 14ad7326 pastith
                } catch (IOException e) {
1914 14ad7326 pastith
                        throw new EJBException(e);
1915 14ad7326 pastith
                } catch (SAXException e) {
1916 14ad7326 pastith
                        throw new EJBException(e);
1917 14ad7326 pastith
                } catch (ParserConfigurationException e) {
1918 14ad7326 pastith
                        throw new EJBException(e);
1919 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1920 14ad7326 pastith
                        throw new EJBException(e);
1921 14ad7326 pastith
                }
1922 14ad7326 pastith
        }
1923 14ad7326 pastith
1924 14ad7326 pastith
        /* (non-Javadoc)
1925 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#copyFiles(java.lang.Long, java.util.List, java.lang.Long)
1926 14ad7326 pastith
         */
1927 14ad7326 pastith
        @Override
1928 14ad7326 pastith
        public void copyFiles(Long userId, List<Long> fileIds, Long destId) throws ObjectNotFoundException, DuplicateNameException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
1929 14ad7326 pastith
                for(Long l : fileIds){
1930 14ad7326 pastith
                        FileHeader file = dao.getEntityById(FileHeader.class, l);
1931 14ad7326 pastith
                        copyFile(userId, l, destId, file.getName());
1932 14ad7326 pastith
                }
1933 14ad7326 pastith
1934 14ad7326 pastith
1935 14ad7326 pastith
        }
1936 14ad7326 pastith
1937 14ad7326 pastith
        /* (non-Javadoc)
1938 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#moveFiles(java.lang.Long, java.util.List, java.lang.Long)
1939 14ad7326 pastith
         */
1940 14ad7326 pastith
        @Override
1941 4684df80 Fotis Stamatelopoulos
        public void moveFiles(Long userId, List<Long> fileIds, Long destId) throws InsufficientPermissionsException, ObjectNotFoundException, QuotaExceededException {
1942 14ad7326 pastith
                for(Long l : fileIds){
1943 14ad7326 pastith
                        FileHeader file = dao.getEntityById(FileHeader.class, l);
1944 14ad7326 pastith
                        moveFile(userId, l, destId, file.getName());
1945 14ad7326 pastith
                }
1946 14ad7326 pastith
1947 14ad7326 pastith
        }
1948 14ad7326 pastith
1949 14ad7326 pastith
        /* (non-Javadoc)
1950 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#deleteFiles(java.lang.Long, java.util.List)
1951 14ad7326 pastith
         */
1952 14ad7326 pastith
        @Override
1953 14ad7326 pastith
        public void deleteFiles(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
1954 14ad7326 pastith
                if (userId == null)
1955 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
1956 14ad7326 pastith
                final User user = dao.getEntityById(User.class, userId);
1957 4d737770 Fotis Stamatelopoulos
                List<String> filesToRemove = new ArrayList<String>();
1958 14ad7326 pastith
                //first delete database objects
1959 14ad7326 pastith
                for(Long fileId : fileIds){
1960 14ad7326 pastith
                        if (fileId == null)
1961 14ad7326 pastith
                                throw new ObjectNotFoundException("No file specified");
1962 14ad7326 pastith
                        final FileHeader file = dao.getEntityById(FileHeader.class, fileId);
1963 14ad7326 pastith
                        final Folder parent = file.getFolder();
1964 14ad7326 pastith
                        if (parent == null)
1965 14ad7326 pastith
                                throw new ObjectNotFoundException("The specified file has no parent folder");
1966 14ad7326 pastith
                        if (!file.hasDeletePermission(user))
1967 14ad7326 pastith
                                throw new InsufficientPermissionsException("User " + user.getId() + " cannot delete file " + file.getName() + "(" + file.getId() + ")");
1968 14ad7326 pastith
1969 14ad7326 pastith
                        parent.removeFile(file);
1970 4d737770 Fotis Stamatelopoulos
                        for (final FileBody body : file.getBodies())
1971 4d737770 Fotis Stamatelopoulos
                                filesToRemove.add(body.getStoredFilePath());
1972 14ad7326 pastith
                        dao.delete(file);
1973 f22e4d5d Dimitris Routsis
                        touchParentFolders(parent, user, new Date());
1974 14ad7326 pastith
                }
1975 14ad7326 pastith
                //then remove physical files if everything is ok
1976 4d737770 Fotis Stamatelopoulos
                for(String physicalFileName : filesToRemove)
1977 4d737770 Fotis Stamatelopoulos
                        deleteActualFile(physicalFileName);
1978 14ad7326 pastith
                //then unindex deleted files
1979 14ad7326 pastith
                for(Long fileId : fileIds)
1980 14ad7326 pastith
                        indexFile(fileId, true);
1981 14ad7326 pastith
1982 14ad7326 pastith
        }
1983 14ad7326 pastith
1984 14ad7326 pastith
        /* (non-Javadoc)
1985 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#moveFilesToTrash(java.lang.Long, java.util.List)
1986 14ad7326 pastith
         */
1987 14ad7326 pastith
        @Override
1988 14ad7326 pastith
        public void moveFilesToTrash(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
1989 14ad7326 pastith
                for(Long l : fileIds)
1990 14ad7326 pastith
                        moveFileToTrash(userId, l);
1991 14ad7326 pastith
1992 14ad7326 pastith
        }
1993 14ad7326 pastith
1994 14ad7326 pastith
        @Override
1995 14ad7326 pastith
        public void removeFilesFromTrash(Long userId, List<Long> fileIds) throws ObjectNotFoundException, InsufficientPermissionsException {
1996 14ad7326 pastith
                for(Long l : fileIds)
1997 14ad7326 pastith
                        removeFileFromTrash(userId, l);
1998 14ad7326 pastith
1999 14ad7326 pastith
        }
2000 14ad7326 pastith
2001 14ad7326 pastith
        @Override
2002 14ad7326 pastith
        public Nonce createNonce(Long userId) throws ObjectNotFoundException {
2003 14ad7326 pastith
                if (userId == null)
2004 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2005 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
2006 14ad7326 pastith
                Nonce nonce = Nonce.createNonce(user.getId());
2007 14ad7326 pastith
                dao.create(nonce);
2008 14ad7326 pastith
                return nonce;
2009 14ad7326 pastith
        }
2010 14ad7326 pastith
2011 14ad7326 pastith
        @Override
2012 14ad7326 pastith
        public Nonce getNonce(String nonce, Long userId) throws ObjectNotFoundException {
2013 14ad7326 pastith
                if (userId == null)
2014 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2015 14ad7326 pastith
                if (nonce == null)
2016 14ad7326 pastith
                        throw new ObjectNotFoundException("No nonce specified");
2017 14ad7326 pastith
                return dao.getNonce(nonce, userId);
2018 14ad7326 pastith
        }
2019 14ad7326 pastith
2020 14ad7326 pastith
        @Override
2021 14ad7326 pastith
        public void removeNonce(Long id) throws ObjectNotFoundException {
2022 14ad7326 pastith
                if (id == null)
2023 14ad7326 pastith
                        throw new ObjectNotFoundException("No nonce specified");
2024 14ad7326 pastith
                Nonce nonce = dao.getEntityById(Nonce.class, id);
2025 14ad7326 pastith
                dao.delete(nonce);
2026 14ad7326 pastith
        }
2027 14ad7326 pastith
2028 14ad7326 pastith
        @Override
2029 14ad7326 pastith
        public void activateUserNonce(Long userId, String nonce, Date nonceExpiryDate) throws ObjectNotFoundException {
2030 14ad7326 pastith
                if (userId == null)
2031 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2032 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
2033 14ad7326 pastith
                user.setNonce(nonce);
2034 14ad7326 pastith
                user.setNonceExpiryDate(nonceExpiryDate);
2035 14ad7326 pastith
        }
2036 14ad7326 pastith
2037 14ad7326 pastith
        /* (non-Javadoc)
2038 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getUserStatistics(java.lang.Long)
2039 14ad7326 pastith
         */
2040 14ad7326 pastith
        @Override
2041 14ad7326 pastith
        public StatsDTO getUserStatistics(Long userId) throws ObjectNotFoundException {
2042 14ad7326 pastith
                if (userId == null)
2043 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2044 14ad7326 pastith
                StatsDTO stats = new StatsDTO();
2045 14ad7326 pastith
                stats.setFileCount(dao.getFileCount(userId));
2046 14ad7326 pastith
                Long fileSize = dao.getFileSize(userId);
2047 14ad7326 pastith
                stats.setFileSize(fileSize);
2048 d3ff9c69 droutsis
                Long quota = getQuota(userId);
2049 14ad7326 pastith
                Long quotaLeft = quota - fileSize;
2050 14ad7326 pastith
                stats.setQuotaLeftSize(quotaLeft);
2051 14ad7326 pastith
                return stats;
2052 14ad7326 pastith
        }
2053 14ad7326 pastith
2054 14ad7326 pastith
        /* (non-Javadoc)
2055 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#getVersions(java.lang.Long, java.lang.Long)
2056 14ad7326 pastith
         */
2057 14ad7326 pastith
        @Override
2058 14ad7326 pastith
        public List<FileBodyDTO> getVersions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
2059 14ad7326 pastith
                if (userId == null)
2060 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2061 14ad7326 pastith
                if (fileId == null)
2062 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
2063 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
2064 14ad7326 pastith
                FileHeader header = dao.getEntityById(FileHeader.class, fileId);
2065 14ad7326 pastith
                if(!header.hasReadPermission(user))
2066 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
2067 14ad7326 pastith
                List<FileBodyDTO> result = new LinkedList<FileBodyDTO>();
2068 14ad7326 pastith
                for(int i = header.getBodies().size()-1 ; i>=0; i--)
2069 14ad7326 pastith
                        result.add(header.getBodies().get(i).getDTO());
2070 14ad7326 pastith
                return result;
2071 14ad7326 pastith
        }
2072 14ad7326 pastith
2073 14ad7326 pastith
        /* (non-Javadoc)
2074 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#removeVersion(java.lang.Long, java.lang.Long, java.lang.Long)
2075 14ad7326 pastith
         */
2076 14ad7326 pastith
        @Override
2077 14ad7326 pastith
        public void removeVersion(Long userId, Long fileId, Long bodyId) throws ObjectNotFoundException, InsufficientPermissionsException {
2078 14ad7326 pastith
                if (userId == null)
2079 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2080 14ad7326 pastith
                if (fileId == null)
2081 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
2082 14ad7326 pastith
                if (bodyId == null)
2083 14ad7326 pastith
                        throw new ObjectNotFoundException("No body specified");
2084 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
2085 14ad7326 pastith
                FileHeader header = dao.getEntityById(FileHeader.class, fileId);
2086 14ad7326 pastith
                if(!header.hasWritePermission(user))
2087 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
2088 14ad7326 pastith
                FileBody body = dao.getEntityById(FileBody.class, bodyId);
2089 14ad7326 pastith
                if(body.equals(header.getCurrentBody())){
2090 14ad7326 pastith
2091 14ad7326 pastith
                        if(header.getBodies().size() == 1)
2092 14ad7326 pastith
                                throw new InsufficientPermissionsException("You cant delete this version, Delete file instead!");
2093 14ad7326 pastith
                        for(FileBody b : header.getBodies())
2094 14ad7326 pastith
                                if(b.getVersion() == body.getVersion()-1)
2095 14ad7326 pastith
                                        header.setCurrentBody(b);
2096 14ad7326 pastith
                }
2097 4d737770 Fotis Stamatelopoulos
                deleteActualFile(body.getStoredFilePath());
2098 14ad7326 pastith
                header.getBodies().remove(body);
2099 14ad7326 pastith
2100 f22e4d5d Dimitris Routsis
                Folder parent = header.getFolder();
2101 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, user, new Date());
2102 14ad7326 pastith
2103 14ad7326 pastith
        }
2104 14ad7326 pastith
2105 14ad7326 pastith
        @Override
2106 39c34533 pastith
        public void restoreVersion(Long userId, Long fileId, int version) throws ObjectNotFoundException, InsufficientPermissionsException,  GSSIOException, QuotaExceededException {
2107 14ad7326 pastith
                if (userId == null)
2108 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2109 14ad7326 pastith
                if (fileId == null)
2110 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
2111 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
2112 14ad7326 pastith
                FileHeader header = dao.getEntityById(FileHeader.class, fileId);
2113 14ad7326 pastith
                if(!header.hasWritePermission(user))
2114 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
2115 39c34533 pastith
                FileBody body = dao.getFileVersion(fileId, version);
2116 14ad7326 pastith
                final File fileContents = new File(body.getStoredFilePath());
2117 14ad7326 pastith
2118 14ad7326 pastith
                try {
2119 14ad7326 pastith
                        updateFileContents(userId, fileId, body.getMimeType(), new FileInputStream(fileContents) );
2120 14ad7326 pastith
                } catch (FileNotFoundException e) {
2121 14ad7326 pastith
                        throw new GSSIOException(e);
2122 14ad7326 pastith
                }
2123 14ad7326 pastith
2124 14ad7326 pastith
        }
2125 14ad7326 pastith
2126 14ad7326 pastith
        /* (non-Javadoc)
2127 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#removeOldVersions(java.lang.Long, java.lang.Long)
2128 14ad7326 pastith
         */
2129 14ad7326 pastith
        @Override
2130 14ad7326 pastith
        public void removeOldVersions(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
2131 14ad7326 pastith
                if (userId == null)
2132 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2133 14ad7326 pastith
                if (fileId == null)
2134 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
2135 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
2136 14ad7326 pastith
                FileHeader header = dao.getEntityById(FileHeader.class, fileId);
2137 14ad7326 pastith
                if(!header.hasWritePermission(user))
2138 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
2139 14ad7326 pastith
                Iterator<FileBody> it = header.getBodies().iterator();
2140 14ad7326 pastith
                while(it.hasNext()){
2141 14ad7326 pastith
                        FileBody body = it.next();
2142 14ad7326 pastith
                        if(!body.equals(header.getCurrentBody())){
2143 4d737770 Fotis Stamatelopoulos
                                deleteActualFile(body.getStoredFilePath());
2144 14ad7326 pastith
                                it.remove();
2145 14ad7326 pastith
                                dao.delete(body);
2146 14ad7326 pastith
                        }
2147 14ad7326 pastith
                }
2148 14ad7326 pastith
                header.getCurrentBody().setVersion(1);
2149 14ad7326 pastith
2150 f22e4d5d Dimitris Routsis
                Folder parent = header.getFolder();
2151 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, user, new Date());
2152 14ad7326 pastith
        }
2153 14ad7326 pastith
2154 14ad7326 pastith
        /**
2155 01a30cd0 Panagiotis Astithas
         * Gets the quota left for specified user ID.
2156 14ad7326 pastith
         */
2157 01a30cd0 Panagiotis Astithas
        private Long getQuotaLeft(Long userId) throws ObjectNotFoundException{
2158 14ad7326 pastith
                Long fileSize = dao.getFileSize(userId);
2159 d3ff9c69 droutsis
                Long quota = getQuota(userId);
2160 14ad7326 pastith
                return quota - fileSize;
2161 14ad7326 pastith
        }
2162 14ad7326 pastith
2163 d3ff9c69 droutsis
        /**
2164 01a30cd0 Panagiotis Astithas
         * Gets the quota for specified user ID.
2165 78214787 Panagiotis Astithas
         */
2166 01a30cd0 Panagiotis Astithas
        private Long getQuota(Long userId) throws ObjectNotFoundException{
2167 01a30cd0 Panagiotis Astithas
                return getUser(userId).getUserClass().getQuota();
2168 78214787 Panagiotis Astithas
        }
2169 d3ff9c69 droutsis
2170 14ad7326 pastith
        public void rebuildSolrIndex() {
2171 14ad7326 pastith
                MessageProducer sender = null;
2172 14ad7326 pastith
                Session session = null;
2173 14ad7326 pastith
                Connection qConn = null;
2174 14ad7326 pastith
                try {
2175 14ad7326 pastith
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
2176 14ad7326 pastith
                        DocumentBuilder db = dbf.newDocumentBuilder();
2177 14ad7326 pastith
                        Document doc = db.newDocument();
2178 14ad7326 pastith
                        Node root = doc.createElement("delete");
2179 14ad7326 pastith
                        doc.appendChild(root);
2180 14ad7326 pastith
                        Node queryNode = doc.createElement("query");
2181 14ad7326 pastith
                        root.appendChild(queryNode);
2182 14ad7326 pastith
                        queryNode.appendChild(doc.createTextNode("*:*"));
2183 14ad7326 pastith
2184 14ad7326 pastith
                        TransformerFactory fact = TransformerFactory.newInstance();
2185 14ad7326 pastith
                        Transformer trans = fact.newTransformer();
2186 14ad7326 pastith
                        trans.setOutputProperty(OutputKeys.INDENT, "yes");
2187 14ad7326 pastith
                        StringWriter sw = new StringWriter();
2188 14ad7326 pastith
                        StreamResult sr = new StreamResult(sw);
2189 14ad7326 pastith
                        DOMSource source = new DOMSource(doc);
2190 14ad7326 pastith
                        trans.transform(source, sr);
2191 14ad7326 pastith
                        logger.debug(sw.toString());
2192 14ad7326 pastith
2193 14ad7326 pastith
                        HttpClient httpClient = new HttpClient();
2194 bde4eafb pastith
                        PostMethod method = new PostMethod(getConfiguration().getString("solrUpdateUrl"));
2195 14ad7326 pastith
                        method.setRequestEntity(new StringRequestEntity(sw.toString()));
2196 14ad7326 pastith
                        int retryCount = 0;
2197 14ad7326 pastith
                        int statusCode = 0;
2198 14ad7326 pastith
                        String response = null;
2199 14ad7326 pastith
                        do {
2200 14ad7326 pastith
                                statusCode = httpClient.executeMethod(method);
2201 14ad7326 pastith
                                logger.debug("HTTP status: " + statusCode);
2202 14ad7326 pastith
                                response = method.getResponseBodyAsString();
2203 14ad7326 pastith
                                logger.debug(response);
2204 14ad7326 pastith
                                retryCount++;
2205 14ad7326 pastith
                                if (statusCode != 200 && retryCount < 3)
2206 14ad7326 pastith
                                        try {
2207 14ad7326 pastith
                                                Thread.sleep(10000); //Give Solr a little time to be available
2208 14ad7326 pastith
                                        } catch (InterruptedException e) {
2209 14ad7326 pastith
                                        }
2210 14ad7326 pastith
                        } while (statusCode != 200 && retryCount < 3);
2211 14ad7326 pastith
                        method.releaseConnection();
2212 14ad7326 pastith
                        if (statusCode != 200)
2213 14ad7326 pastith
                                throw new EJBException("Cannot clear Solr index. Solr response is:\n" + response);
2214 14ad7326 pastith
                        List<Long> fileIds = dao.getAllFileIds();
2215 14ad7326 pastith
2216 14ad7326 pastith
                        Context jndiCtx = new InitialContext();
2217 14ad7326 pastith
                        ConnectionFactory factory = (QueueConnectionFactory) jndiCtx.lookup("java:/JmsXA");
2218 14ad7326 pastith
                        Queue queue = (Queue) jndiCtx.lookup("queue/gss-indexingQueue");
2219 14ad7326 pastith
                        qConn = factory.createConnection();
2220 14ad7326 pastith
                        session = qConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
2221 14ad7326 pastith
                        sender = session.createProducer(queue);
2222 14ad7326 pastith
2223 14ad7326 pastith
                        for (Long id : fileIds) {
2224 14ad7326 pastith
                                MapMessage map = session.createMapMessage();
2225 14ad7326 pastith
                                map.setObject("id", id);
2226 14ad7326 pastith
                                map.setBoolean("delete", false);
2227 14ad7326 pastith
                                sender.send(map);
2228 14ad7326 pastith
                        }
2229 14ad7326 pastith
                        sendOptimize(httpClient, 0);
2230 14ad7326 pastith
                } catch (DOMException e) {
2231 14ad7326 pastith
                        throw new EJBException(e);
2232 14ad7326 pastith
                } catch (TransformerConfigurationException e) {
2233 14ad7326 pastith
                        throw new EJBException(e);
2234 14ad7326 pastith
                } catch (IllegalArgumentException e) {
2235 14ad7326 pastith
                        throw new EJBException(e);
2236 14ad7326 pastith
                } catch (HttpException e) {
2237 14ad7326 pastith
                        throw new EJBException(e);
2238 14ad7326 pastith
                } catch (UnsupportedEncodingException e) {
2239 14ad7326 pastith
                        throw new EJBException(e);
2240 14ad7326 pastith
                } catch (ParserConfigurationException e) {
2241 14ad7326 pastith
                        throw new EJBException(e);
2242 14ad7326 pastith
                } catch (TransformerException e) {
2243 14ad7326 pastith
                        throw new EJBException(e);
2244 14ad7326 pastith
                } catch (IOException e) {
2245 14ad7326 pastith
                        throw new EJBException(e);
2246 14ad7326 pastith
                } catch (NamingException e) {
2247 14ad7326 pastith
                        throw new EJBException(e);
2248 14ad7326 pastith
                } catch (JMSException e) {
2249 14ad7326 pastith
                        throw new EJBException(e);
2250 14ad7326 pastith
                }
2251 14ad7326 pastith
                finally {
2252 14ad7326 pastith
                        try {
2253 14ad7326 pastith
                                if (sender != null)
2254 14ad7326 pastith
                                        sender.close();
2255 14ad7326 pastith
                                if (session != null)
2256 14ad7326 pastith
                                        session.close();
2257 14ad7326 pastith
                                if (qConn != null)
2258 14ad7326 pastith
                                        qConn.close();
2259 14ad7326 pastith
                        }
2260 14ad7326 pastith
                        catch (JMSException e) {
2261 14ad7326 pastith
                                logger.warn(e);
2262 14ad7326 pastith
                        }
2263 14ad7326 pastith
                }
2264 14ad7326 pastith
        }
2265 14ad7326 pastith
2266 14ad7326 pastith
        /**
2267 14ad7326 pastith
         * Sends a optimize message to the solr server
2268 14ad7326 pastith
         *
2269 14ad7326 pastith
         * @param httpClient
2270 14ad7326 pastith
         * @param retryCount If the commit fails, it is retried three times. This parameter is passed in the recursive
2271 14ad7326 pastith
         *                                         calls to stop the recursion
2272 14ad7326 pastith
         * @throws UnsupportedEncodingException
2273 14ad7326 pastith
         * @throws IOException
2274 14ad7326 pastith
         * @throws HttpException
2275 14ad7326 pastith
         */
2276 14ad7326 pastith
        private void sendOptimize(HttpClient httpClient, int retryCount) throws UnsupportedEncodingException, IOException, HttpException {
2277 14ad7326 pastith
                PostMethod method = null;
2278 14ad7326 pastith
                try {
2279 14ad7326 pastith
                        logger.debug("Optimize retry: " + retryCount);
2280 bde4eafb pastith
                        method = new PostMethod(getConfiguration().getString("solrUpdateUrl"));
2281 14ad7326 pastith
                        method.setRequestEntity(new StringRequestEntity("<optimize/>", "text/xml", "iso8859-1"));
2282 14ad7326 pastith
                        int statusCode = httpClient.executeMethod(method);
2283 14ad7326 pastith
                        logger.debug("HTTP status: " + statusCode);
2284 14ad7326 pastith
                        String response = method.getResponseBodyAsString();
2285 14ad7326 pastith
                        logger.debug(response);
2286 14ad7326 pastith
                        if (statusCode != 200 && retryCount < 2) {
2287 14ad7326 pastith
                                try {
2288 14ad7326 pastith
                                        Thread.sleep(10000); //Give Solr a little time to be available
2289 14ad7326 pastith
                                } catch (InterruptedException e) {
2290 14ad7326 pastith
                                }
2291 14ad7326 pastith
                                sendOptimize(httpClient, retryCount + 1);
2292 14ad7326 pastith
                        }
2293 14ad7326 pastith
                }
2294 14ad7326 pastith
                finally {
2295 14ad7326 pastith
                        if (method != null)
2296 14ad7326 pastith
                                method.releaseConnection();
2297 14ad7326 pastith
                }
2298 14ad7326 pastith
        }
2299 14ad7326 pastith
2300 4d737770 Fotis Stamatelopoulos
        public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, long fileSize, String filePath)
2301 14ad7326 pastith
                        throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
2302 14ad7326 pastith
                        InsufficientPermissionsException, QuotaExceededException {
2303 14ad7326 pastith
                // Validate.
2304 14ad7326 pastith
                if (userId == null)
2305 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2306 14ad7326 pastith
                if (folderId == null)
2307 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
2308 14ad7326 pastith
                String contentType = mimeType;
2309 14ad7326 pastith
                if (StringUtils.isEmpty(mimeType))
2310 14ad7326 pastith
                        contentType = DEFAULT_MIME_TYPE;
2311 14ad7326 pastith
                if (StringUtils.isEmpty(name))
2312 14ad7326 pastith
                        throw new ObjectNotFoundException("No file name specified");
2313 14ad7326 pastith
                if (dao.existsFolderOrFile(folderId, name))
2314 14ad7326 pastith
                        throw new DuplicateNameException("A folder or file with the name '" + name +
2315 14ad7326 pastith
                                                "' already exists at this level");
2316 14ad7326 pastith
2317 14ad7326 pastith
                // Do the actual work.
2318 14ad7326 pastith
                Folder parent = null;
2319 14ad7326 pastith
                try {
2320 14ad7326 pastith
                        parent = dao.getEntityById(Folder.class, folderId);
2321 14ad7326 pastith
                } catch (final ObjectNotFoundException onfe) {
2322 14ad7326 pastith
                        // Supply a more accurate problem description.
2323 14ad7326 pastith
                        throw new ObjectNotFoundException("Parent folder not found");
2324 14ad7326 pastith
                }
2325 14ad7326 pastith
                final User owner = dao.getEntityById(User.class, userId);
2326 14ad7326 pastith
                if (!parent.hasWritePermission(owner))
2327 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the permissions to write to this folder");
2328 14ad7326 pastith
                final FileHeader file = new FileHeader();
2329 14ad7326 pastith
                file.setName(name);
2330 14ad7326 pastith
                parent.addFile(file);
2331 14ad7326 pastith
                // set file owner to folder owner
2332 14ad7326 pastith
                file.setOwner(parent.getOwner());
2333 14ad7326 pastith
2334 14ad7326 pastith
                final Date now = new Date();
2335 14ad7326 pastith
                final AuditInfo auditInfo = new AuditInfo();
2336 14ad7326 pastith
                auditInfo.setCreatedBy(owner);
2337 14ad7326 pastith
                auditInfo.setCreationDate(now);
2338 14ad7326 pastith
                auditInfo.setModifiedBy(owner);
2339 14ad7326 pastith
                auditInfo.setModificationDate(now);
2340 14ad7326 pastith
                file.setAuditInfo(auditInfo);
2341 14ad7326 pastith
                // TODO set the proper versioning flag on creation
2342 14ad7326 pastith
                file.setVersioned(false);
2343 14ad7326 pastith
2344 14ad7326 pastith
                for (final Permission p : parent.getPermissions()) {
2345 14ad7326 pastith
                        final Permission permission = new Permission();
2346 14ad7326 pastith
                        permission.setGroup(p.getGroup());
2347 14ad7326 pastith
                        permission.setUser(p.getUser());
2348 14ad7326 pastith
                        permission.setRead(p.getRead());
2349 14ad7326 pastith
                        permission.setWrite(p.getWrite());
2350 14ad7326 pastith
                        permission.setModifyACL(p.getModifyACL());
2351 14ad7326 pastith
                        file.addPermission(permission);
2352 14ad7326 pastith
                }
2353 14ad7326 pastith
2354 14ad7326 pastith
                // Create the file body.
2355 14ad7326 pastith
                try {
2356 4d737770 Fotis Stamatelopoulos
                        createFileBody(name, contentType, fileSize, filePath, file, auditInfo);
2357 14ad7326 pastith
                } catch (FileNotFoundException e) {
2358 14ad7326 pastith
                        throw new GSSIOException(e);
2359 14ad7326 pastith
                }
2360 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, owner, new Date());
2361 14ad7326 pastith
                dao.flush();
2362 14ad7326 pastith
                indexFile(file.getId(), false);
2363 8f128261 droutsis
2364 8f128261 droutsis
                return file.getDTO();
2365 14ad7326 pastith
        }
2366 14ad7326 pastith
2367 14ad7326 pastith
        /* (non-Javadoc)
2368 14ad7326 pastith
         * @see gr.ebs.gss.server.ejb.ExternalAPI#updateFileContents(java.lang.Long, java.lang.Long, java.lang.String, java.io.InputStream)
2369 14ad7326 pastith
         */
2370 4d737770 Fotis Stamatelopoulos
        public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, long fileSize, String filePath) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
2371 14ad7326 pastith
                if (userId == null)
2372 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2373 14ad7326 pastith
                if (fileId == null)
2374 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
2375 14ad7326 pastith
                String contentType = mimeType;
2376 14ad7326 pastith
2377 14ad7326 pastith
                FileHeader file = dao.getEntityById(FileHeader.class, fileId);
2378 5ca9c0d6 fstamatelopoulos
2379 5ca9c0d6 fstamatelopoulos
                // if no mime type or the generic mime type is defined by the client, then try to identify it from the filename extension
2380 f92730cd droutsis
                if (StringUtils.isEmpty(mimeType) || "application/octet-stream".equals(mimeType)
2381 f92730cd droutsis
                                        || "application/download".equals(mimeType) || "application/force-download".equals(mimeType)
2382 f92730cd droutsis
                                        || "octet/stream".equals(mimeType) || "application/unknown".equals(mimeType))
2383 5ca9c0d6 fstamatelopoulos
                        contentType = identifyMimeType(file.getName());
2384 5ca9c0d6 fstamatelopoulos
2385 14ad7326 pastith
                final User owner = dao.getEntityById(User.class, userId);
2386 14ad7326 pastith
                if (!file.hasWritePermission(owner))
2387 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
2388 14ad7326 pastith
                final Date now = new Date();
2389 14ad7326 pastith
                final AuditInfo auditInfo = new AuditInfo();
2390 14ad7326 pastith
                auditInfo.setCreatedBy(owner);
2391 14ad7326 pastith
                auditInfo.setCreationDate(now);
2392 14ad7326 pastith
                auditInfo.setModifiedBy(owner);
2393 14ad7326 pastith
                auditInfo.setModificationDate(now);
2394 14ad7326 pastith
                try {
2395 4d737770 Fotis Stamatelopoulos
                        createFileBody(file.getName(), contentType, fileSize, filePath, file, auditInfo);
2396 14ad7326 pastith
                } catch (FileNotFoundException e) {
2397 14ad7326 pastith
                        throw new GSSIOException(e);
2398 14ad7326 pastith
                }
2399 f22e4d5d Dimitris Routsis
                Folder parent = file.getFolder();
2400 f22e4d5d Dimitris Routsis
                touchParentFolders(parent, owner, new Date());
2401 14ad7326 pastith
2402 14ad7326 pastith
                indexFile(fileId, false);
2403 8f128261 droutsis
                return file.getDTO();
2404 14ad7326 pastith
        }
2405 14ad7326 pastith
2406 14ad7326 pastith
        /**
2407 5ca9c0d6 fstamatelopoulos
         * Helper method for identifying mime type by examining the filename extension
2408 5ca9c0d6 fstamatelopoulos
         *
2409 5ca9c0d6 fstamatelopoulos
         * @param filename
2410 5ca9c0d6 fstamatelopoulos
         * @return the mime type
2411 5ca9c0d6 fstamatelopoulos
         */
2412 5ca9c0d6 fstamatelopoulos
        private String identifyMimeType(String filename) {
2413 09051786 droutsis
                if (filename.indexOf('.') != -1) {
2414 f3f7bdf3 Fotis Stamatelopoulos
                        String extension = filename.substring(filename.lastIndexOf('.')).toLowerCase(Locale.ENGLISH);
2415 5ca9c0d6 fstamatelopoulos
                        if (".doc".equals(extension))
2416 5ca9c0d6 fstamatelopoulos
                                return "application/msword";
2417 5ca9c0d6 fstamatelopoulos
                        else if (".xls".equals(extension))
2418 5ca9c0d6 fstamatelopoulos
                                return "application/vnd.ms-excel";
2419 5ca9c0d6 fstamatelopoulos
                        else if (".ppt".equals(extension))
2420 5ca9c0d6 fstamatelopoulos
                                return "application/vnd.ms-powerpoint";
2421 5ca9c0d6 fstamatelopoulos
                        else if (".pdf".equals(extension))
2422 5ca9c0d6 fstamatelopoulos
                                return "application/pdf";
2423 4684df80 Fotis Stamatelopoulos
                        else if (".gif".equals(extension))
2424 4684df80 Fotis Stamatelopoulos
                                return "image/gif";
2425 4684df80 Fotis Stamatelopoulos
                        else if (".jpg".equals(extension) || ".jpeg".equals(extension) || ".jpe".equals(extension))
2426 4684df80 Fotis Stamatelopoulos
                                return "image/jpeg";
2427 4684df80 Fotis Stamatelopoulos
                        else if (".tiff".equals(extension) || ".tif".equals(extension))
2428 4684df80 Fotis Stamatelopoulos
                                return "image/tiff";
2429 4684df80 Fotis Stamatelopoulos
                        else if (".png".equals(extension))
2430 4684df80 Fotis Stamatelopoulos
                                return "image/png";
2431 4684df80 Fotis Stamatelopoulos
                        else if (".bmp".equals(extension))
2432 4684df80 Fotis Stamatelopoulos
                                return "image/bmp";
2433 5ca9c0d6 fstamatelopoulos
                }
2434 5ca9c0d6 fstamatelopoulos
                // when all else fails assign the default mime type
2435 5ca9c0d6 fstamatelopoulos
                return DEFAULT_MIME_TYPE;
2436 5ca9c0d6 fstamatelopoulos
        }
2437 5ca9c0d6 fstamatelopoulos
2438 5ca9c0d6 fstamatelopoulos
        /**
2439 14ad7326 pastith
         * Helper method to create a new file body and attach it as the current body
2440 14ad7326 pastith
         * of the provided file header.
2441 14ad7326 pastith
         *
2442 14ad7326 pastith
         * @param name the original file name
2443 14ad7326 pastith
         * @param mimeType the content type
2444 4d737770 Fotis Stamatelopoulos
         * @param fileSize the uploaded file size
2445 4d737770 Fotis Stamatelopoulos
         * @param filePath the uploaded file full path
2446 14ad7326 pastith
         * @param header the file header that will be associated with the new body
2447 14ad7326 pastith
         * @param auditInfo the audit info
2448 14ad7326 pastith
         * @param owner the owner of the file
2449 14ad7326 pastith
         * @throws FileNotFoundException
2450 14ad7326 pastith
         * @throws QuotaExceededException
2451 01a30cd0 Panagiotis Astithas
         * @throws ObjectNotFoundException if the owner was not found
2452 14ad7326 pastith
         */
2453 4d737770 Fotis Stamatelopoulos
        private void createFileBody(String name, String mimeType, long fileSize, String filePath,
2454 4d737770 Fotis Stamatelopoulos
                                FileHeader header, AuditInfo auditInfo)
2455 01a30cd0 Panagiotis Astithas
                        throws FileNotFoundException, QuotaExceededException, ObjectNotFoundException {
2456 6dddaedf Dimitris Routsis
2457 6dddaedf Dimitris Routsis
                long currentTotalSize = 0;
2458 6dddaedf Dimitris Routsis
                if (!header.isVersioned() && header.getCurrentBody() != null && header.getBodies() != null)
2459 6dddaedf Dimitris Routsis
                        currentTotalSize = header.getTotalSize();
2460 b6510556 Dimitris Routsis
                Long quotaLeft = getQuotaLeft(header.getOwner().getId());
2461 4d737770 Fotis Stamatelopoulos
                if(quotaLeft < fileSize-currentTotalSize) {
2462 4d737770 Fotis Stamatelopoulos
                        // quota exceeded -> delete the file
2463 4d737770 Fotis Stamatelopoulos
                        deleteActualFile(filePath);
2464 6dddaedf Dimitris Routsis
                        throw new QuotaExceededException("Not enough free space available");
2465 6dddaedf Dimitris Routsis
                }
2466 6dddaedf Dimitris Routsis
2467 14ad7326 pastith
                FileBody body = new FileBody();
2468 5ca9c0d6 fstamatelopoulos
2469 5ca9c0d6 fstamatelopoulos
                // if no mime type or the generic mime type is defined by the client, then try to identify it from the filename extension
2470 f92730cd droutsis
                if (StringUtils.isEmpty(mimeType) || "application/octet-stream".equals(mimeType)
2471 f92730cd droutsis
                                        || "application/download".equals(mimeType) || "application/force-download".equals(mimeType)
2472 f92730cd droutsis
                                        || "octet/stream".equals(mimeType) || "application/unknown".equals(mimeType))
2473 5ca9c0d6 fstamatelopoulos
                        body.setMimeType(identifyMimeType(name));
2474 5ca9c0d6 fstamatelopoulos
                else
2475 78214787 Panagiotis Astithas
                        body.setMimeType(mimeType);
2476 14ad7326 pastith
                body.setAuditInfo(auditInfo);
2477 4d737770 Fotis Stamatelopoulos
                body.setFileSize(fileSize);
2478 14ad7326 pastith
                body.setOriginalFilename(name);
2479 4d737770 Fotis Stamatelopoulos
                body.setStoredFilePath(filePath);
2480 14ad7326 pastith
                //CLEAR OLD VERSION IF FILE IS NOT VERSIONED AND GETS UPDATED
2481 14ad7326 pastith
                if(!header.isVersioned() && header.getCurrentBody() != null){
2482 14ad7326 pastith
                        header.setCurrentBody(null);
2483 a7401f95 pastith
                        if (header.getBodies() != null) {
2484 a7401f95 pastith
                                Iterator<FileBody> it = header.getBodies().iterator();
2485 a7401f95 pastith
                                while(it.hasNext()){
2486 a7401f95 pastith
                                        FileBody bo = it.next();
2487 4d737770 Fotis Stamatelopoulos
                                        deleteActualFile(bo.getStoredFilePath());
2488 a7401f95 pastith
                                        it.remove();
2489 a7401f95 pastith
                                        dao.delete(bo);
2490 a7401f95 pastith
                                }
2491 14ad7326 pastith
                        }
2492 14ad7326 pastith
                }
2493 14ad7326 pastith
2494 14ad7326 pastith
                dao.flush();
2495 14ad7326 pastith
                header.addBody(body);
2496 82481089 Panagiotis Astithas
                header.setAuditInfo(auditInfo);
2497 14ad7326 pastith
2498 14ad7326 pastith
                dao.create(body);
2499 14ad7326 pastith
        }
2500 14ad7326 pastith
2501 14ad7326 pastith
2502 14ad7326 pastith
        @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
2503 a0788710 pastith
        public File uploadFile(InputStream stream, Long userId) throws IOException, ObjectNotFoundException {
2504 14ad7326 pastith
                if (userId == null)
2505 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2506 14ad7326 pastith
                User owner = dao.getEntityById(User.class, userId);
2507 14ad7326 pastith
                if(owner == null)
2508 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2509 14ad7326 pastith
                long start = 0, end = 0;
2510 14ad7326 pastith
                if (logger.isDebugEnabled())
2511 14ad7326 pastith
                        start = System.currentTimeMillis();
2512 14ad7326 pastith
                File result = new File(generateRepositoryFilePath());
2513 a0788710 pastith
                try {
2514 a0788710 pastith
                        final FileOutputStream output = new FileOutputStream(result);
2515 a0788710 pastith
                        final byte[] buffer = new byte[UPLOAD_BUFFER_SIZE];
2516 a0788710 pastith
                        int n = 0;
2517 a0788710 pastith
2518 a0788710 pastith
                        while (-1 != (n = stream.read(buffer)))
2519 a0788710 pastith
                                output.write(buffer, 0, n);
2520 a0788710 pastith
                        output.close();
2521 a0788710 pastith
                        stream.close();
2522 a0788710 pastith
                } catch (IOException e) {
2523 a0788710 pastith
                        if (!result.delete())
2524 a0788710 pastith
                                logger.warn("Could not delete " + result.getPath());
2525 a0788710 pastith
                        throw e;
2526 a0788710 pastith
                }
2527 14ad7326 pastith
                if (logger.isDebugEnabled()) {
2528 14ad7326 pastith
                        end = System.currentTimeMillis();
2529 a0788710 pastith
                        logger.debug("Time to upload: " + (end - start) + " (msec)");
2530 14ad7326 pastith
                }
2531 14ad7326 pastith
                return result;
2532 14ad7326 pastith
        }
2533 14ad7326 pastith
2534 14ad7326 pastith
2535 14ad7326 pastith
        public void createFileUploadProgress(Long userId, String filename, Long bytesTransfered, Long fileSize) throws ObjectNotFoundException{
2536 14ad7326 pastith
2537 14ad7326 pastith
                if (userId == null)
2538 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2539 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
2540 14ad7326 pastith
                FileUploadStatus status = dao.getFileUploadStatus(userId, filename);
2541 14ad7326 pastith
                if(status == null){
2542 14ad7326 pastith
                        status = new FileUploadStatus();
2543 14ad7326 pastith
                        status.setOwner(user);
2544 14ad7326 pastith
                        status.setFilename(filename);
2545 14ad7326 pastith
                        status.setBytesUploaded(bytesTransfered);
2546 14ad7326 pastith
                        status.setFileSize(fileSize);
2547 14ad7326 pastith
                        dao.create(status);
2548 14ad7326 pastith
                }
2549 14ad7326 pastith
                else{
2550 14ad7326 pastith
                        status.setBytesUploaded(bytesTransfered);
2551 14ad7326 pastith
                        status.setFileSize(fileSize);
2552 14ad7326 pastith
                        dao.update(status);
2553 14ad7326 pastith
                }
2554 14ad7326 pastith
2555 14ad7326 pastith
        }
2556 14ad7326 pastith
2557 14ad7326 pastith
        public void removeFileUploadProgress(Long userId, String filename) throws ObjectNotFoundException{
2558 14ad7326 pastith
                if (userId == null)
2559 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2560 14ad7326 pastith
                FileUploadStatus status = dao.getFileUploadStatus(userId, filename);
2561 14ad7326 pastith
                if(status != null)
2562 14ad7326 pastith
                        dao.delete(status);
2563 14ad7326 pastith
        }
2564 14ad7326 pastith
2565 14ad7326 pastith
        @Override
2566 14ad7326 pastith
        public FileUploadStatus getFileUploadStatus(Long userId, String fileName) {
2567 14ad7326 pastith
                return dao.getFileUploadStatus(userId, fileName);
2568 14ad7326 pastith
        }
2569 14ad7326 pastith
2570 14ad7326 pastith
        @Override
2571 14ad7326 pastith
        public FolderDTO getFolderWithSubfolders(Long userId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
2572 14ad7326 pastith
                if (userId == null)
2573 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2574 14ad7326 pastith
                if (folderId == null)
2575 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
2576 14ad7326 pastith
                final User user = dao.getEntityById(User.class, userId);
2577 14ad7326 pastith
                final Folder folder = dao.getEntityById(Folder.class, folderId);
2578 14ad7326 pastith
                // Check permissions
2579 14ad7326 pastith
                if (!folder.hasReadPermission(user))
2580 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
2581 14ad7326 pastith
                List<FolderDTO> subfolders = new ArrayList<FolderDTO>();
2582 14ad7326 pastith
                if (folder.hasReadPermission(user))
2583 14ad7326 pastith
                        for (Folder f : folder.getSubfolders())
2584 14ad7326 pastith
                                if (f.hasReadPermission(user) && !f.isDeleted())
2585 14ad7326 pastith
                                        subfolders.add(f.getDTO());
2586 14ad7326 pastith
                FolderDTO result = folder.getDTO();
2587 14ad7326 pastith
                result.setSubfolders(subfolders);
2588 14ad7326 pastith
                return folder.getDTO();
2589 14ad7326 pastith
        }
2590 14ad7326 pastith
2591 14ad7326 pastith
        @Override
2592 14ad7326 pastith
        public FolderDTO getFolderWithSubfolders(Long userId, Long callingUserId, Long folderId) throws ObjectNotFoundException, InsufficientPermissionsException {
2593 14ad7326 pastith
                if (userId == null)
2594 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2595 14ad7326 pastith
                if (folderId == null)
2596 14ad7326 pastith
                        throw new ObjectNotFoundException("No folder specified");
2597 68410d59 pastith
                User user = dao.getEntityById(User.class, callingUserId);
2598 68410d59 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
2599 14ad7326 pastith
                // Check permissions
2600 14ad7326 pastith
                if (!folder.hasReadPermission(user))
2601 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the permissions to read this folder");
2602 14ad7326 pastith
2603 14ad7326 pastith
                FolderDTO result = folder.getDTO();
2604 14ad7326 pastith
                result.setSubfolders(getSharedSubfolders(userId, callingUserId, folder.getId()));
2605 14ad7326 pastith
                return result;
2606 14ad7326 pastith
        }
2607 14ad7326 pastith
2608 14ad7326 pastith
        @Override
2609 14ad7326 pastith
        public FileBodyDTO getFileVersion(Long userId, Long fileId, int version)
2610 14ad7326 pastith
                        throws ObjectNotFoundException, InsufficientPermissionsException {
2611 14ad7326 pastith
                if (userId == null)
2612 14ad7326 pastith
                        throw new ObjectNotFoundException("No user specified");
2613 14ad7326 pastith
                if (fileId == null)
2614 14ad7326 pastith
                        throw new ObjectNotFoundException("No file specified");
2615 14ad7326 pastith
                if (version < 1)
2616 14ad7326 pastith
                        throw new ObjectNotFoundException("No valid version specified");
2617 14ad7326 pastith
                User user = dao.getEntityById(User.class, userId);
2618 14ad7326 pastith
                FileHeader file = dao.getEntityById(FileHeader.class, fileId);
2619 14ad7326 pastith
                if (!file.hasReadPermission(user) && !file.getFolder().hasReadPermission(user))
2620 14ad7326 pastith
                        throw new InsufficientPermissionsException("You don't have the necessary permissions");
2621 14ad7326 pastith
                FileBody body = dao.getFileVersion(fileId, version);
2622 14ad7326 pastith
                return body.getDTO();
2623 14ad7326 pastith
        }
2624 14ad7326 pastith
2625 0a4b8f82 pastith
        @Override
2626 0a4b8f82 pastith
        public User updateUserPolicyAcceptance(Long userId, boolean isAccepted) throws ObjectNotFoundException {
2627 0a4b8f82 pastith
                if (userId == null)
2628 0a4b8f82 pastith
                        throw new ObjectNotFoundException("No user specified");
2629 0a4b8f82 pastith
                User user = dao.getEntityById(User.class, userId);
2630 0a4b8f82 pastith
                user.setAcceptedPolicy(isAccepted);
2631 0a4b8f82 pastith
                return user;
2632 0a4b8f82 pastith
        }
2633 0a4b8f82 pastith
2634 8f128261 droutsis
        @Override
2635 8f128261 droutsis
        public void updateAccounting(User user, Date date, long bandwidthDiff) {
2636 8f128261 droutsis
                dao.updateAccounting(user, date, bandwidthDiff);
2637 8f128261 droutsis
        }
2638 8f128261 droutsis
2639 77f75ac4 pastith
        @Override
2640 77f75ac4 pastith
        public boolean canReadFolder(Long userId, Long folderId) throws ObjectNotFoundException {
2641 77f75ac4 pastith
                if (userId == null)
2642 77f75ac4 pastith
                        throw new ObjectNotFoundException("No user specified");
2643 77f75ac4 pastith
                if (folderId == null)
2644 77f75ac4 pastith
                        throw new ObjectNotFoundException("No folder specified");
2645 77f75ac4 pastith
                User user = dao.getEntityById(User.class, userId);
2646 77f75ac4 pastith
                Folder folder = dao.getEntityById(Folder.class, folderId);
2647 77f75ac4 pastith
                // Check permissions
2648 77f75ac4 pastith
                if (!folder.hasReadPermission(user))
2649 77f75ac4 pastith
                        return false;
2650 77f75ac4 pastith
                return true;
2651 77f75ac4 pastith
        }
2652 77f75ac4 pastith
2653 3ef7b691 Dimitris Routsis
        @Override
2654 3ef7b691 Dimitris Routsis
        public String resetWebDAVPassword(Long userId) throws ObjectNotFoundException {
2655 3ef7b691 Dimitris Routsis
                if (userId == null)
2656 3ef7b691 Dimitris Routsis
                        throw new ObjectNotFoundException("No user specified");
2657 3ef7b691 Dimitris Routsis
                User user = dao.getEntityById(User.class, userId);
2658 3ef7b691 Dimitris Routsis
                user.generateWebDAVPassword();
2659 3ef7b691 Dimitris Routsis
                return user.getWebDAVPassword();
2660 3ef7b691 Dimitris Routsis
        }
2661 3ef7b691 Dimitris Routsis
2662 2f551abc Panagiotis Astithas
        @Override
2663 2f551abc Panagiotis Astithas
        public Invitation findInvite(String code) {
2664 82248972 Panagiotis Astithas
                if (code == null)
2665 82248972 Panagiotis Astithas
                        return null;
2666 82248972 Panagiotis Astithas
                return dao.findInvite(code);
2667 2f551abc Panagiotis Astithas
        }
2668 2f551abc Panagiotis Astithas
2669 3f6fd106 Panagiotis Astithas
        @Override
2670 46268014 Panagiotis Astithas
        public void createLdapUser(String username, String firstname, String lastname, String email, String password) {
2671 3f6fd106 Panagiotis Astithas
                LDAPConnection lc = new LDAPConnection();
2672 3f6fd106 Panagiotis Astithas
        LDAPAttributeSet attributeSet = new LDAPAttributeSet();
2673 edf24a21 Panagiotis Astithas
        attributeSet.add(new LDAPAttribute("objectClass", getConfiguration().getStringArray("objectClass")));
2674 3f6fd106 Panagiotis Astithas
        attributeSet.add(new LDAPAttribute("uid", username));
2675 46268014 Panagiotis Astithas
        attributeSet.add(new LDAPAttribute("cn", new String[]{firstname + " " + lastname}));
2676 46268014 Panagiotis Astithas
        attributeSet.add(new LDAPAttribute("sn", lastname));
2677 46268014 Panagiotis Astithas
        attributeSet.add(new LDAPAttribute("givenName", firstname));
2678 3f6fd106 Panagiotis Astithas
        attributeSet.add(new LDAPAttribute("mail", email));
2679 3f6fd106 Panagiotis Astithas
        attributeSet.add(new LDAPAttribute("userPassword", password));
2680 3f6fd106 Panagiotis Astithas
        String dn = "uid=" + username + "," + getConfiguration().getString("baseDn");
2681 3f6fd106 Panagiotis Astithas
        LDAPEntry newEntry = new LDAPEntry(dn, attributeSet);
2682 3f6fd106 Panagiotis Astithas
        try {
2683 3f6fd106 Panagiotis Astithas
                lc.connect(getConfiguration().getString("ldapHost"), LDAPConnection.DEFAULT_PORT);
2684 3f6fd106 Panagiotis Astithas
                lc.bind(LDAPConnection.LDAP_V3, getConfiguration().getString("bindDn"),
2685 3f6fd106 Panagiotis Astithas
                                getConfiguration().getString("bindPassword").getBytes("UTF8"));
2686 3f6fd106 Panagiotis Astithas
                lc.add(newEntry);
2687 3f6fd106 Panagiotis Astithas
                logger.info("Successfully added LDAP account: " + dn);
2688 3f6fd106 Panagiotis Astithas
                lc.disconnect();
2689 3f6fd106 Panagiotis Astithas
        } catch(LDAPException e) {
2690 3f6fd106 Panagiotis Astithas
                throw new RuntimeException(e);
2691 3f6fd106 Panagiotis Astithas
        } catch(UnsupportedEncodingException e) {
2692 3f6fd106 Panagiotis Astithas
                throw new RuntimeException(e);
2693 3f6fd106 Panagiotis Astithas
        }
2694 3f6fd106 Panagiotis Astithas
2695 3f6fd106 Panagiotis Astithas
        }
2696 3f6fd106 Panagiotis Astithas
2697 01a30cd0 Panagiotis Astithas
        @Override
2698 01a30cd0 Panagiotis Astithas
        public void upgradeUserClass(String username, String code) throws ObjectNotFoundException, InvitationUsedException {
2699 01a30cd0 Panagiotis Astithas
                User user = findUser(username);
2700 01a30cd0 Panagiotis Astithas
                if (user == null)
2701 01a30cd0 Panagiotis Astithas
                        throw new ObjectNotFoundException("The user was not found");
2702 01a30cd0 Panagiotis Astithas
                Invitation invite = findInvite(code);
2703 01a30cd0 Panagiotis Astithas
                if (invite.getUser() != null)
2704 01a30cd0 Panagiotis Astithas
                        throw new InvitationUsedException("This code has already been used");
2705 01a30cd0 Panagiotis Astithas
                invite.setUser(user);
2706 01a30cd0 Panagiotis Astithas
                user.setUserClass(getCouponUserClass());
2707 01a30cd0 Panagiotis Astithas
        }
2708 01a30cd0 Panagiotis Astithas
2709 01a30cd0 Panagiotis Astithas
        @Override
2710 01a30cd0 Panagiotis Astithas
        public UserClass getCouponUserClass() {
2711 01a30cd0 Panagiotis Astithas
                return dao.findCouponUserClass();
2712 01a30cd0 Panagiotis Astithas
        }
2713 01a30cd0 Panagiotis Astithas
2714 14ad7326 pastith
}