Statistics
| Branch: | Tag: | Revision:

root / src / gr / ebs / gss / server / rest / FilesHandler.java @ 086c7250

History | View | Annotate | Download (84.7 kB)

1 14ad7326 pastith
/*
2 c62f0b96 Natasa Kapravelou
 * Copyright 2008, 2009, 2010 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.rest;
20 14ad7326 pastith
21 a91ef7e8 Panagiotis Astithas
import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
22 af6aa461 Christos V. Stathis
import gr.ebs.gss.common.exceptions.DuplicateNameException;
23 af6aa461 Christos V. Stathis
import gr.ebs.gss.common.exceptions.GSSIOException;
24 af6aa461 Christos V. Stathis
import gr.ebs.gss.common.exceptions.InsufficientPermissionsException;
25 af6aa461 Christos V. Stathis
import gr.ebs.gss.common.exceptions.ObjectNotFoundException;
26 af6aa461 Christos V. Stathis
import gr.ebs.gss.common.exceptions.QuotaExceededException;
27 af6aa461 Christos V. Stathis
import gr.ebs.gss.common.exceptions.RpcException;
28 a91ef7e8 Panagiotis Astithas
import gr.ebs.gss.server.Login;
29 f7c44c33 fstamatelopoulos
import gr.ebs.gss.server.domain.FileBody;
30 f7c44c33 fstamatelopoulos
import gr.ebs.gss.server.domain.FileHeader;
31 f5903adf pastith
import gr.ebs.gss.server.domain.FileUploadStatus;
32 f7c44c33 fstamatelopoulos
import gr.ebs.gss.server.domain.Folder;
33 f7c44c33 fstamatelopoulos
import gr.ebs.gss.server.domain.Group;
34 f7c44c33 fstamatelopoulos
import gr.ebs.gss.server.domain.Permission;
35 14ad7326 pastith
import gr.ebs.gss.server.domain.User;
36 e150a336 pastith
import gr.ebs.gss.server.ejb.ExternalAPI;
37 3b6b7f25 Dimitris Routsis
import gr.ebs.gss.server.ejb.TransactionHelper;
38 14ad7326 pastith
39 14ad7326 pastith
import java.io.BufferedReader;
40 14ad7326 pastith
import java.io.ByteArrayInputStream;
41 14ad7326 pastith
import java.io.ByteArrayOutputStream;
42 14ad7326 pastith
import java.io.File;
43 14ad7326 pastith
import java.io.FileInputStream;
44 14ad7326 pastith
import java.io.FileNotFoundException;
45 14ad7326 pastith
import java.io.IOException;
46 14ad7326 pastith
import java.io.InputStream;
47 95da8819 koutsoub
import java.io.InputStreamReader;
48 14ad7326 pastith
import java.io.OutputStreamWriter;
49 14ad7326 pastith
import java.io.PrintWriter;
50 5e2b8ec6 koutsoub
import java.io.UnsupportedEncodingException;
51 14ad7326 pastith
import java.net.URI;
52 14ad7326 pastith
import java.net.URISyntaxException;
53 47d800f9 pastith
import java.net.URLDecoder;
54 47d800f9 pastith
import java.net.URLEncoder;
55 14ad7326 pastith
import java.util.ArrayList;
56 a91ef7e8 Panagiotis Astithas
import java.util.Arrays;
57 fc5ef2cc droutsis
import java.util.Collection;
58 8f128261 droutsis
import java.util.Date;
59 14ad7326 pastith
import java.util.HashSet;
60 31e19588 Natasa Kapravelou
import java.util.Iterator;
61 14ad7326 pastith
import java.util.List;
62 14ad7326 pastith
import java.util.Set;
63 5e2b8ec6 koutsoub
import java.util.StringTokenizer;
64 204107fb Panagiotis Astithas
import java.util.concurrent.Callable;
65 14ad7326 pastith
66 14ad7326 pastith
import javax.servlet.ServletContext;
67 14ad7326 pastith
import javax.servlet.ServletException;
68 14ad7326 pastith
import javax.servlet.ServletOutputStream;
69 a91ef7e8 Panagiotis Astithas
import javax.servlet.http.Cookie;
70 14ad7326 pastith
import javax.servlet.http.HttpServletRequest;
71 14ad7326 pastith
import javax.servlet.http.HttpServletResponse;
72 14ad7326 pastith
73 a91ef7e8 Panagiotis Astithas
import org.apache.commons.codec.binary.Base64;
74 e150a336 pastith
import org.apache.commons.fileupload.FileItemIterator;
75 e150a336 pastith
import org.apache.commons.fileupload.FileItemStream;
76 e150a336 pastith
import org.apache.commons.fileupload.FileUploadException;
77 e150a336 pastith
import org.apache.commons.fileupload.ProgressListener;
78 e150a336 pastith
import org.apache.commons.fileupload.servlet.ServletFileUpload;
79 bda7d76d pastith
import org.apache.commons.fileupload.util.Streams;
80 bda7d76d pastith
import org.apache.commons.httpclient.util.DateParseException;
81 bda7d76d pastith
import org.apache.commons.httpclient.util.DateUtil;
82 14ad7326 pastith
import org.apache.commons.logging.Log;
83 14ad7326 pastith
import org.apache.commons.logging.LogFactory;
84 14ad7326 pastith
import org.json.JSONArray;
85 14ad7326 pastith
import org.json.JSONException;
86 14ad7326 pastith
import org.json.JSONObject;
87 14ad7326 pastith
88 14ad7326 pastith
89 14ad7326 pastith
/**
90 14ad7326 pastith
 * A class that handles operations on the 'files' namespace.
91 14ad7326 pastith
 *
92 14ad7326 pastith
 * @author past
93 14ad7326 pastith
 */
94 14ad7326 pastith
public class FilesHandler extends RequestHandler {
95 14ad7326 pastith
        /**
96 14ad7326 pastith
         * The request parameter name for fetching a different version.
97 14ad7326 pastith
         */
98 14ad7326 pastith
        private static final String VERSION_PARAM = "version";
99 14ad7326 pastith
100 14ad7326 pastith
        /**
101 14ad7326 pastith
         * The request attribute containing the owner of the destination URI
102 14ad7326 pastith
         * in a copy or move request.
103 14ad7326 pastith
         */
104 14ad7326 pastith
        private static final String DESTINATION_OWNER_ATTRIBUTE = "destOwner";
105 14ad7326 pastith
106 e150a336 pastith
        private static final int TRACK_PROGRESS_PERCENT = 5;
107 e150a336 pastith
108 14ad7326 pastith
        /**
109 bda7d76d pastith
         * The form parameter name that contains the signature in a browser POST upload.
110 bda7d76d pastith
         */
111 bda7d76d pastith
        private static final String AUTHORIZATION_PARAMETER = "Authorization";
112 bda7d76d pastith
113 bda7d76d pastith
        /**
114 bda7d76d pastith
         * The form parameter name that contains the date in a browser POST upload.
115 bda7d76d pastith
         */
116 bda7d76d pastith
        private static final String DATE_PARAMETER = "Date";
117 bda7d76d pastith
118 bda7d76d pastith
        /**
119 f5903adf pastith
         * The request parameter name for making an upload progress request.
120 f5903adf pastith
         */
121 f5903adf pastith
        private static final String PROGRESS_PARAMETER = "progress";
122 f5903adf pastith
123 f5903adf pastith
        /**
124 39c34533 pastith
         * The request parameter name for restoring a previous version of a file.
125 39c34533 pastith
         */
126 39c34533 pastith
        private static final String RESTORE_VERSION_PARAMETER = "restoreVersion";
127 39c34533 pastith
128 39c34533 pastith
        /**
129 14ad7326 pastith
         * The logger.
130 14ad7326 pastith
         */
131 14ad7326 pastith
        private static Log logger = LogFactory.getLog(FilesHandler.class);
132 14ad7326 pastith
133 14ad7326 pastith
        /**
134 14ad7326 pastith
         * The servlet context provided by the call site.
135 14ad7326 pastith
         */
136 14ad7326 pastith
        private ServletContext context;
137 14ad7326 pastith
138 14ad7326 pastith
        /**
139 31e19588 Natasa Kapravelou
         * The style sheet for displaying the directory listings.
140 31e19588 Natasa Kapravelou
         */
141 31e19588 Natasa Kapravelou
        private static final String GSS_CSS = "H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} " + "H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} " + "H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} " + "BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} " + "B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} " + "P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}" + "A {color : black;}" + "A.name {color : black;}" + "HR {color : #525D76;}";
142 31e19588 Natasa Kapravelou
143 31e19588 Natasa Kapravelou
144 31e19588 Natasa Kapravelou
        /**
145 14ad7326 pastith
         * @param servletContext
146 14ad7326 pastith
         */
147 14ad7326 pastith
        public FilesHandler(ServletContext servletContext) {
148 14ad7326 pastith
                context = servletContext;
149 14ad7326 pastith
        }
150 14ad7326 pastith
151 2f1a60e0 Dimitris Routsis
        private void updateAccounting(final User user, final Date date, final long bandwidthDiff) {
152 2f1a60e0 Dimitris Routsis
                try {
153 2f1a60e0 Dimitris Routsis
                        new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
154 2f1a60e0 Dimitris Routsis
                                @Override
155 2f1a60e0 Dimitris Routsis
                                public Void call() throws Exception {
156 2f1a60e0 Dimitris Routsis
                                        getService().updateAccounting(user, date, bandwidthDiff);
157 2f1a60e0 Dimitris Routsis
                                        return null;
158 2f1a60e0 Dimitris Routsis
                                }
159 2f1a60e0 Dimitris Routsis
                        });
160 2f1a60e0 Dimitris Routsis
                } catch (RuntimeException e) {
161 2f1a60e0 Dimitris Routsis
                        throw e;
162 2f1a60e0 Dimitris Routsis
                } catch (Exception e) {
163 2f1a60e0 Dimitris Routsis
                        // updateAccounting() doesn't throw any checked exceptions
164 2f1a60e0 Dimitris Routsis
                        assert false;
165 2f1a60e0 Dimitris Routsis
                }
166 2f1a60e0 Dimitris Routsis
        }
167 2f1a60e0 Dimitris Routsis
168 14ad7326 pastith
        /**
169 14ad7326 pastith
     * Serve the specified resource, optionally including the data content.
170 14ad7326 pastith
     *
171 14ad7326 pastith
     * @param req The servlet request we are processing
172 14ad7326 pastith
     * @param resp The servlet response we are creating
173 14ad7326 pastith
     * @param content Should the content be included?
174 14ad7326 pastith
     *
175 14ad7326 pastith
     * @exception IOException if an input/output error occurs
176 14ad7326 pastith
     * @exception ServletException if a servlet-specified error occurs
177 14ad7326 pastith
     * @throws RpcException
178 14ad7326 pastith
     * @throws InsufficientPermissionsException
179 14ad7326 pastith
     * @throws ObjectNotFoundException
180 14ad7326 pastith
     */
181 14ad7326 pastith
        @Override
182 14ad7326 pastith
        protected void serveResource(HttpServletRequest req, HttpServletResponse resp, boolean content)
183 14ad7326 pastith
                    throws IOException, ServletException {
184 14ad7326 pastith
                boolean authDeferred = getAuthDeferred(req);
185 14ad7326 pastith
        String path = getInnerPath(req, PATH_FILES);
186 14ad7326 pastith
                if (path.equals(""))
187 14ad7326 pastith
                        path = "/";
188 8fa7f8ff pastith
                try {
189 8fa7f8ff pastith
                        path = URLDecoder.decode(path, "UTF-8");
190 8fa7f8ff pastith
                } catch (IllegalArgumentException e) {
191 8fa7f8ff pastith
                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
192 8fa7f8ff pastith
                        return;
193 8fa7f8ff pastith
                }
194 f5903adf pastith
            String progress = req.getParameter(PROGRESS_PARAMETER);
195 14ad7326 pastith
196 8e471ce5 Natasa Kapravelou
            if (logger.isDebugEnabled())
197 14ad7326 pastith
                        if (content)
198 14ad7326 pastith
                            logger.debug("Serving resource '" +        path + "' headers and data");
199 14ad7326 pastith
                    else
200 14ad7326 pastith
                            logger.debug("Serving resource '" +        path + "' headers only");
201 14ad7326 pastith
202 14ad7326 pastith
            User user = getUser(req);
203 14ad7326 pastith
            User owner = getOwner(req);
204 14ad7326 pastith
        boolean exists = true;
205 14ad7326 pastith
        Object resource = null;
206 f7c44c33 fstamatelopoulos
        FileHeader file = null;
207 f7c44c33 fstamatelopoulos
        Folder folder = null;
208 14ad7326 pastith
        try {
209 68410d59 pastith
                resource = getService().getResourceAtPath(owner.getId(), path, false);
210 14ad7326 pastith
        } catch (ObjectNotFoundException e) {
211 14ad7326 pastith
            exists = false;
212 14ad7326 pastith
        } catch (RpcException e) {
213 14ad7326 pastith
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
214 14ad7326 pastith
                        return;
215 14ad7326 pastith
                }
216 14ad7326 pastith
217 bdf739a9 Natasa Kapravelou
            if (!exists && authDeferred) {
218 bdf739a9 Natasa Kapravelou
                    // We do not want to leak information if the request
219 bdf739a9 Natasa Kapravelou
                    // was not authenticated.
220 bdf739a9 Natasa Kapravelou
                    resp.sendError(HttpServletResponse.SC_FORBIDDEN);
221 14ad7326 pastith
                    return;
222 14ad7326 pastith
            }
223 14ad7326 pastith
224 f7c44c33 fstamatelopoulos
            if (resource instanceof Folder)
225 f7c44c33 fstamatelopoulos
                    folder = (Folder) resource;
226 14ad7326 pastith
            else
227 f7c44c33 fstamatelopoulos
                    file = (FileHeader) resource;        // Note that file will be null, if (!exists).
228 14ad7326 pastith
229 14ad7326 pastith
            // Now it's time to perform the deferred authentication check.
230 14ad7326 pastith
                // Since regular signature checking was already performed,
231 1d36b941 pastith
                // we need to check the read-all flag or the signature-in-parameters.
232 eaf8360b Christos V. Stathis
                if (authDeferred) {
233 d235f94f Natasa Kapravelou
                        if (file != null && !file.isReadForAll() && content) {
234 1d36b941 pastith
                                // Check for GET with the signature in the request parameters.
235 1d36b941 pastith
                                String auth = req.getParameter(AUTHORIZATION_PARAMETER);
236 1d36b941 pastith
                                String dateParam = req.getParameter(DATE_PARAMETER);
237 1d36b941 pastith
                                if (auth == null || dateParam == null) {
238 a91ef7e8 Panagiotis Astithas
                                        // Check for a valid authentication cookie.
239 a91ef7e8 Panagiotis Astithas
                                        if (req.getCookies() != null) {
240 6567092b Panagiotis Astithas
                                                boolean found = false;
241 a91ef7e8 Panagiotis Astithas
                                                for (Cookie cookie : req.getCookies())
242 a91ef7e8 Panagiotis Astithas
                                                        if (Login.AUTH_COOKIE.equals(cookie.getName())) {
243 a91ef7e8 Panagiotis Astithas
                                                                String cookieauth = cookie.getValue();
244 a91ef7e8 Panagiotis Astithas
                                                                int sepIndex = cookieauth.indexOf(Login.COOKIE_SEPARATOR);
245 a91ef7e8 Panagiotis Astithas
                                                                if (sepIndex == -1) {
246 a91ef7e8 Panagiotis Astithas
                                                                        handleAuthFailure(req, resp);
247 a91ef7e8 Panagiotis Astithas
                                                                        return;
248 a91ef7e8 Panagiotis Astithas
                                                                }
249 a91ef7e8 Panagiotis Astithas
                                                                String username = URLDecoder.decode(cookieauth.substring(0, sepIndex), "US-ASCII");
250 a91ef7e8 Panagiotis Astithas
                                                                user = null;
251 a91ef7e8 Panagiotis Astithas
                                                                try {
252 a91ef7e8 Panagiotis Astithas
                                                                        user = getService().findUser(username);
253 a91ef7e8 Panagiotis Astithas
                                                                } catch (RpcException e) {
254 a91ef7e8 Panagiotis Astithas
                                                                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
255 a91ef7e8 Panagiotis Astithas
                                                                        return;
256 a91ef7e8 Panagiotis Astithas
                                                                }
257 a91ef7e8 Panagiotis Astithas
                                                                if (user == null) {
258 a91ef7e8 Panagiotis Astithas
                                                                    resp.sendError(HttpServletResponse.SC_FORBIDDEN);
259 a91ef7e8 Panagiotis Astithas
                                                                    return;
260 a91ef7e8 Panagiotis Astithas
                                                            }
261 a91ef7e8 Panagiotis Astithas
                                                                req.setAttribute(USER_ATTRIBUTE, user);
262 a91ef7e8 Panagiotis Astithas
                                                                String token = cookieauth.substring(sepIndex + 1);
263 a91ef7e8 Panagiotis Astithas
                                                                if (user.getAuthToken() == null) {
264 a91ef7e8 Panagiotis Astithas
                                                                        resp.sendError(HttpServletResponse.SC_FORBIDDEN);
265 a91ef7e8 Panagiotis Astithas
                                                                        return;
266 a91ef7e8 Panagiotis Astithas
                                                                }
267 a91ef7e8 Panagiotis Astithas
                                                                if (!Arrays.equals(user.getAuthToken(), Base64.decodeBase64(token))) {
268 a91ef7e8 Panagiotis Astithas
                                                                        resp.sendError(HttpServletResponse.SC_FORBIDDEN);
269 a91ef7e8 Panagiotis Astithas
                                                                        return;
270 a91ef7e8 Panagiotis Astithas
                                                                }
271 6567092b Panagiotis Astithas
                                                                found = true;
272 a91ef7e8 Panagiotis Astithas
                                                                break;
273 a91ef7e8 Panagiotis Astithas
                                                        }
274 6567092b Panagiotis Astithas
                                                if (!found) {
275 6567092b Panagiotis Astithas
                                                        handleAuthFailure(req, resp);
276 6567092b Panagiotis Astithas
                                                        return;
277 6567092b Panagiotis Astithas
                                                }
278 a91ef7e8 Panagiotis Astithas
                                        } else {
279 a91ef7e8 Panagiotis Astithas
                                                handleAuthFailure(req, resp);
280 a91ef7e8 Panagiotis Astithas
                                                return;
281 a91ef7e8 Panagiotis Astithas
                                        }
282 a91ef7e8 Panagiotis Astithas
                                } else {
283 a91ef7e8 Panagiotis Astithas
                                    long timestamp;
284 a91ef7e8 Panagiotis Astithas
                                        try {
285 a91ef7e8 Panagiotis Astithas
                                                timestamp = DateUtil.parseDate(dateParam).getTime();
286 a91ef7e8 Panagiotis Astithas
                                        } catch (DateParseException e) {
287 a91ef7e8 Panagiotis Astithas
                                            resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
288 a91ef7e8 Panagiotis Astithas
                                            return;
289 a91ef7e8 Panagiotis Astithas
                                        }
290 a91ef7e8 Panagiotis Astithas
                                    if (!isTimeValid(timestamp)) {
291 a91ef7e8 Panagiotis Astithas
                                            resp.sendError(HttpServletResponse.SC_FORBIDDEN);
292 a91ef7e8 Panagiotis Astithas
                                            return;
293 a91ef7e8 Panagiotis Astithas
                                    }
294 a91ef7e8 Panagiotis Astithas
295 a91ef7e8 Panagiotis Astithas
                                        // Fetch the Authorization parameter and find the user specified in it.
296 a91ef7e8 Panagiotis Astithas
                                        String[] authParts = auth.split(" ");
297 a91ef7e8 Panagiotis Astithas
                                        if (authParts.length != 2) {
298 a91ef7e8 Panagiotis Astithas
                                            resp.sendError(HttpServletResponse.SC_FORBIDDEN);
299 a91ef7e8 Panagiotis Astithas
                                            return;
300 a91ef7e8 Panagiotis Astithas
                                    }
301 a91ef7e8 Panagiotis Astithas
                                        String username = authParts[0];
302 a91ef7e8 Panagiotis Astithas
                                        String signature = authParts[1];
303 a91ef7e8 Panagiotis Astithas
                                        user = null;
304 a91ef7e8 Panagiotis Astithas
                                        try {
305 a91ef7e8 Panagiotis Astithas
                                                user = getService().findUser(username);
306 a91ef7e8 Panagiotis Astithas
                                        } catch (RpcException e) {
307 a91ef7e8 Panagiotis Astithas
                                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
308 a91ef7e8 Panagiotis Astithas
                                                return;
309 a91ef7e8 Panagiotis Astithas
                                        }
310 a91ef7e8 Panagiotis Astithas
                                        if (user == null) {
311 a91ef7e8 Panagiotis Astithas
                                            resp.sendError(HttpServletResponse.SC_FORBIDDEN);
312 a91ef7e8 Panagiotis Astithas
                                            return;
313 a91ef7e8 Panagiotis Astithas
                                    }
314 a91ef7e8 Panagiotis Astithas
                                        req.setAttribute(USER_ATTRIBUTE, user);
315 a91ef7e8 Panagiotis Astithas
316 a91ef7e8 Panagiotis Astithas
                                        // Remove the servlet path from the request URI.
317 a91ef7e8 Panagiotis Astithas
                                        String p = req.getRequestURI();
318 a91ef7e8 Panagiotis Astithas
                                        String servletPath = req.getContextPath() + req.getServletPath();
319 a91ef7e8 Panagiotis Astithas
                                        p = p.substring(servletPath.length());
320 a91ef7e8 Panagiotis Astithas
                                        // Validate the signature in the Authorization parameter.
321 a91ef7e8 Panagiotis Astithas
                                        String data = req.getMethod() + dateParam + p;
322 a91ef7e8 Panagiotis Astithas
                                        if (!isSignatureValid(signature, user, data)) {
323 a91ef7e8 Panagiotis Astithas
                                            resp.sendError(HttpServletResponse.SC_FORBIDDEN);
324 a91ef7e8 Panagiotis Astithas
                                            return;
325 a91ef7e8 Panagiotis Astithas
                                    }
326 1d36b941 pastith
                                }
327 c9ffbe84 pastith
                        }
328 eaf8360b Christos V. Stathis
                        else if(folder != null && folder.isReadForAll() || file != null && file.isReadForAll()){
329 eaf8360b Christos V. Stathis
                                //This case refers to a folder or file with public privileges
330 eaf8360b Christos V. Stathis
                                //For a read-for-all folder request, pretend the owner is making it.
331 eaf8360b Christos V. Stathis
                                user = owner;
332 eaf8360b Christos V. Stathis
                                req.setAttribute(USER_ATTRIBUTE, user);
333 eaf8360b Christos V. Stathis
                        }else if(folder != null && !folder.isReadForAll()){
334 eaf8360b Christos V. Stathis
                                resp.sendError(HttpServletResponse.SC_FORBIDDEN);
335 eaf8360b Christos V. Stathis
                                return;
336 eaf8360b Christos V. Stathis
                        }
337 eaf8360b Christos V. Stathis
                        else{
338 eaf8360b Christos V. Stathis
                                resp.sendError(HttpServletResponse.SC_FORBIDDEN);
339 eaf8360b Christos V. Stathis
                                return;
340 eaf8360b Christos V. Stathis
                        }
341 d235f94f Natasa Kapravelou
                }
342 14ad7326 pastith
            // If the resource is not a collection, and the resource path
343 14ad7326 pastith
            // ends with "/" or "\", return NOT FOUND.
344 14ad7326 pastith
            if (folder == null)
345 14ad7326 pastith
                        if (path.endsWith("/") || path.endsWith("\\")) {
346 14ad7326 pastith
                            resp.sendError(HttpServletResponse.SC_NOT_FOUND, req.getRequestURI());
347 14ad7326 pastith
                            return;
348 14ad7326 pastith
                    }
349 14ad7326 pastith
350 a3349f1f pastith
            // Workaround for IE's broken caching behavior.
351 470a59a7 pastith
            if (folder != null)
352 470a59a7 pastith
                    resp.setHeader("Expires", "-1");
353 a3349f1f pastith
354 f5903adf pastith
            // A request for upload progress.
355 f5903adf pastith
            if (progress != null && content) {
356 f5903adf pastith
                    serveProgress(req, resp, progress, user, file);
357 f5903adf pastith
                        return;
358 f5903adf pastith
            }
359 f5903adf pastith
360 14ad7326 pastith
                // Fetch the version to retrieve, if specified.
361 14ad7326 pastith
                String verStr = req.getParameter(VERSION_PARAM);
362 14ad7326 pastith
                int version = 0;
363 f7c44c33 fstamatelopoulos
                FileBody oldBody = null;
364 14ad7326 pastith
                if (verStr != null && file != null)
365 14ad7326 pastith
                        try {
366 14ad7326 pastith
                                version = Integer.valueOf(verStr);
367 14ad7326 pastith
                        } catch (NumberFormatException e) {
368 14ad7326 pastith
                                resp.sendError(HttpServletResponse.SC_BAD_REQUEST, req.getRequestURI());
369 14ad7326 pastith
                            return;
370 14ad7326 pastith
                        }
371 14ad7326 pastith
                if (version > 0)
372 14ad7326 pastith
                        try {
373 14ad7326 pastith
                                oldBody = getService().getFileVersion(user.getId(), file.getId(), version);
374 14ad7326 pastith
                        } catch (RpcException e) {
375 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
376 14ad7326 pastith
                                return;
377 14ad7326 pastith
                        } catch (ObjectNotFoundException e) {
378 14ad7326 pastith
                            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
379 14ad7326 pastith
                            return;
380 14ad7326 pastith
                        } catch (InsufficientPermissionsException e) {
381 14ad7326 pastith
                            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
382 14ad7326 pastith
                            return;
383 14ad7326 pastith
                        }
384 14ad7326 pastith
385 14ad7326 pastith
            // Check if the conditions specified in the optional If headers are
386 14ad7326 pastith
            // satisfied. Doing this for folders would require recursive checking
387 14ad7326 pastith
            // for all of their children, which in turn would defy the purpose of
388 14ad7326 pastith
            // the optimization.
389 62f168b2 Giannis Koutsoubos
            if (folder == null){
390 14ad7326 pastith
                        // Checking If headers.
391 14ad7326 pastith
                    if (!checkIfHeaders(req, resp, file, oldBody))
392 14ad7326 pastith
                                return;
393 62f168b2 Giannis Koutsoubos
            }
394 62f168b2 Giannis Koutsoubos
            else if(!checkIfModifiedSince(req, resp, folder))
395 62f168b2 Giannis Koutsoubos
                    return;
396 14ad7326 pastith
397 14ad7326 pastith
            // Find content type.
398 14ad7326 pastith
            String contentType = null;
399 4e7b8a39 Panagiotis Astithas
            boolean isContentHtml = false;
400 d235f94f Natasa Kapravelou
            boolean expectJSON = false;
401 c5b81911 Natasa Kapravelou
402 14ad7326 pastith
            if (file != null) {
403 f7c44c33 fstamatelopoulos
                contentType = version>0 ? oldBody.getMimeType() : file.getCurrentBody().getMimeType();
404 14ad7326 pastith
                if (contentType == null) {
405 14ad7326 pastith
                        contentType = context.getMimeType(file.getName());
406 f7c44c33 fstamatelopoulos
                        file.getCurrentBody().setMimeType(contentType);
407 14ad7326 pastith
                }
408 4e7b8a39 Panagiotis Astithas
            } else { // folder != null
409 4e7b8a39 Panagiotis Astithas
                    String accept = req.getHeader("Accept");
410 4e7b8a39 Panagiotis Astithas
                    // The order in this conditional pessimizes the common API case,
411 4e7b8a39 Panagiotis Astithas
                    // but is important for backwards compatibility with existing
412 4e7b8a39 Panagiotis Astithas
                    // clients who send no accept header and expect a JSON response.
413 4e7b8a39 Panagiotis Astithas
                    if (accept != null && accept.contains("text/html")) {
414 4e7b8a39 Panagiotis Astithas
                            contentType = "text/html;charset=UTF-8";
415 4e7b8a39 Panagiotis Astithas
                            isContentHtml = true;
416 d235f94f Natasa Kapravelou
                            //this is the case when clients send the appropriate headers, the contentType is "text/html"
417 d235f94f Natasa Kapravelou
                            //and expect a JSON response. The above check applies to FireGSS client
418 4497ec95 Natasa Kapravelou
                            expectJSON = !authDeferred ? true : false;
419 d235f94f Natasa Kapravelou
                    }
420 db93eeea Christos V. Stathis
            else if (authDeferred && req.getMethod().equals(METHOD_GET)) {
421 db93eeea Christos V. Stathis
                contentType = "text/html;charset=UTF-8";
422 db93eeea Christos V. Stathis
                isContentHtml = true;
423 db93eeea Christos V. Stathis
                expectJSON = false;
424 db93eeea Christos V. Stathis
            }
425 4497ec95 Natasa Kapravelou
                    else {
426 4e7b8a39 Panagiotis Astithas
                            contentType = "application/json;charset=UTF-8";
427 d235f94f Natasa Kapravelou
                            expectJSON = true;
428 d235f94f Natasa Kapravelou
                    }
429 4e7b8a39 Panagiotis Astithas
                }
430 31e19588 Natasa Kapravelou
431 14ad7326 pastith
432 14ad7326 pastith
            ArrayList ranges = null;
433 14ad7326 pastith
            long contentLength = -1L;
434 14ad7326 pastith
435 14ad7326 pastith
            if (file != null) {
436 77f75ac4 pastith
                    // Parse range specifier.
437 14ad7326 pastith
                    ranges = parseRange(req, resp, file, oldBody);
438 14ad7326 pastith
                    // ETag header
439 14ad7326 pastith
                    resp.setHeader("ETag", getETag(file, oldBody));
440 77f75ac4 pastith
                    // Last-Modified header.
441 14ad7326 pastith
                    String lastModified = oldBody == null ?
442 14ad7326 pastith
                                            getLastModifiedHttp(file.getAuditInfo()) :
443 14ad7326 pastith
                                            getLastModifiedHttp(oldBody.getAuditInfo());
444 14ad7326 pastith
                    resp.setHeader("Last-Modified", lastModified);
445 77f75ac4 pastith
                    // X-GSS-Metadata header.
446 14ad7326 pastith
                    try {
447 14ad7326 pastith
                                resp.setHeader("X-GSS-Metadata", renderJson(user, file, oldBody));
448 14ad7326 pastith
                        } catch (InsufficientPermissionsException e) {
449 14ad7326 pastith
                                resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
450 14ad7326 pastith
                        return;
451 14ad7326 pastith
                }
452 77f75ac4 pastith
                    // Get content length.
453 f7c44c33 fstamatelopoulos
                    contentLength = version>0 ? oldBody.getFileSize() : file.getCurrentBody().getFileSize();
454 14ad7326 pastith
                    // Special case for zero length files, which would cause a
455 77f75ac4 pastith
                    // (silent) ISE when setting the output buffer size.
456 14ad7326 pastith
                    if (contentLength == 0L)
457 14ad7326 pastith
                                content = false;
458 77f75ac4 pastith
            } else
459 77f75ac4 pastith
                    // Set the folder X-GSS-Metadata header.
460 77f75ac4 pastith
                    try {
461 77f75ac4 pastith
                                resp.setHeader("X-GSS-Metadata", renderJsonMetadata(user, folder));
462 77f75ac4 pastith
                        } catch (InsufficientPermissionsException e) {
463 77f75ac4 pastith
                                resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
464 77f75ac4 pastith
                        return;
465 77f75ac4 pastith
                }
466 14ad7326 pastith
467 14ad7326 pastith
            ServletOutputStream ostream = null;
468 14ad7326 pastith
            PrintWriter writer = null;
469 14ad7326 pastith
470 14ad7326 pastith
            if (content)
471 14ad7326 pastith
                        try {
472 14ad7326 pastith
                            ostream = resp.getOutputStream();
473 14ad7326 pastith
                    } catch (IllegalStateException e) {
474 14ad7326 pastith
                            // If it fails, we try to get a Writer instead if we're
475 14ad7326 pastith
                            // trying to serve a text file
476 14ad7326 pastith
                            if ( contentType == null
477 14ad7326 pastith
                                                    || contentType.startsWith("text")
478 14ad7326 pastith
                                                    || contentType.endsWith("xml") )
479 14ad7326 pastith
                                        writer = resp.getWriter();
480 14ad7326 pastith
                                else
481 14ad7326 pastith
                                        throw e;
482 14ad7326 pastith
                    }
483 bdf739a9 Natasa Kapravelou
            if (folder != null || (ranges == null || ranges.isEmpty()) && req.getHeader("Range") == null || ranges == FULL) {
484 14ad7326 pastith
                    // Set the appropriate output headers
485 14ad7326 pastith
                    if (contentType != null) {
486 14ad7326 pastith
                            if (logger.isDebugEnabled())
487 14ad7326 pastith
                                    logger.debug("contentType='" + contentType + "'");
488 14ad7326 pastith
                            resp.setContentType(contentType);
489 14ad7326 pastith
                    }
490 14ad7326 pastith
                    if (file != null && contentLength >= 0) {
491 14ad7326 pastith
                            if (logger.isDebugEnabled())
492 14ad7326 pastith
                                    logger.debug("contentLength=" + contentLength);
493 14ad7326 pastith
                            if (contentLength < Integer.MAX_VALUE)
494 14ad7326 pastith
                                        resp.setContentLength((int) contentLength);
495 e8fd351d Natasa Kapravelou
496 14ad7326 pastith
                                else
497 14ad7326 pastith
                                        // Set the content-length as String to be able to use a long
498 14ad7326 pastith
                                    resp.setHeader("content-length", "" + contentLength);
499 14ad7326 pastith
                    }
500 14ad7326 pastith
501 14ad7326 pastith
                    InputStream renderResult = null;
502 e8fd351d Natasa Kapravelou
                    String relativePath = getRelativePath(req);
503 e8fd351d Natasa Kapravelou
                    String contextPath = req.getContextPath();
504 e8fd351d Natasa Kapravelou
                    String servletPath = req.getServletPath();
505 e8fd351d Natasa Kapravelou
                    String contextServletPath = contextPath + servletPath;
506 e8fd351d Natasa Kapravelou
                    if (folder != null && content)
507 31e19588 Natasa Kapravelou
                            // Serve the directory browser for a public folder
508 39ece393 Christos V. Stathis
                            if (isContentHtml && !expectJSON) {
509 39ece393 Christos V. Stathis
                    try {
510 39ece393 Christos V. Stathis
                        folder = getService().expandFolder(folder);
511 39ece393 Christos V. Stathis
                    }
512 39ece393 Christos V. Stathis
                    catch (ObjectNotFoundException e) {
513 39ece393 Christos V. Stathis
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
514 39ece393 Christos V. Stathis
                        return;
515 39ece393 Christos V. Stathis
                    }
516 39ece393 Christos V. Stathis
                    catch (RpcException e) {
517 39ece393 Christos V. Stathis
                        //We send 500 instead of 404 because this folder has been loaded before in this method and it is
518 39ece393 Christos V. Stathis
                        //impossible to not be found now
519 39ece393 Christos V. Stathis
                            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
520 39ece393 Christos V. Stathis
                                    return;
521 39ece393 Christos V. Stathis
                            }
522 39ece393 Christos V. Stathis
                    renderResult = renderHtml(contextServletPath, relativePath, folder,user);
523 39ece393 Christos V. Stathis
                }
524 d235f94f Natasa Kapravelou
                            // Serve the directory for an ordinary folder or for fireGSS client
525 31e19588 Natasa Kapravelou
                            else
526 31e19588 Natasa Kapravelou
                                    try {
527 31e19588 Natasa Kapravelou
                                            renderResult = renderJson(user, folder);
528 31e19588 Natasa Kapravelou
                                            } catch (InsufficientPermissionsException e) {
529 31e19588 Natasa Kapravelou
                                                    resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
530 31e19588 Natasa Kapravelou
                                                    return;
531 31e19588 Natasa Kapravelou
                                            }
532 31e19588 Natasa Kapravelou
533 31e19588 Natasa Kapravelou
534 14ad7326 pastith
                    // Copy the input stream to our output stream (if requested)
535 14ad7326 pastith
                    if (content) {
536 14ad7326 pastith
                            try {
537 14ad7326 pastith
                                    resp.setBufferSize(output);
538 14ad7326 pastith
                            } catch (IllegalStateException e) {
539 14ad7326 pastith
                                    // Silent catch
540 14ad7326 pastith
                            }
541 14ad7326 pastith
                            try {
542 617fe906 Dimitris Routsis
                                    if(file != null)
543 617fe906 Dimitris Routsis
                                                if (needsContentDisposition(req))
544 31ec597c Panagiotis Astithas
                                                    resp.setHeader("Content-Disposition","attachment; filename*=UTF-8''"+getDispositionFilename(file));
545 617fe906 Dimitris Routsis
                                            else
546 31ec597c Panagiotis Astithas
                                                    resp.setHeader("Content-Disposition","inline; filename*=UTF-8''"+getDispositionFilename(file));
547 14ad7326 pastith
                                    if (ostream != null)
548 14ad7326 pastith
                                                copy(file, renderResult, ostream, req, oldBody);
549 14ad7326 pastith
                                        else
550 14ad7326 pastith
                                                copy(file, renderResult, writer, req, oldBody);
551 2f1a60e0 Dimitris Routsis
                                    if (file!=null) updateAccounting(owner, new Date(), contentLength);
552 14ad7326 pastith
                        } catch (ObjectNotFoundException e) {
553 14ad7326 pastith
                                resp.sendError(HttpServletResponse.SC_NOT_FOUND);
554 14ad7326 pastith
                                return;
555 14ad7326 pastith
                        } catch (InsufficientPermissionsException e) {
556 14ad7326 pastith
                                resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
557 14ad7326 pastith
                                return;
558 14ad7326 pastith
                        } catch (RpcException e) {
559 14ad7326 pastith
                                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
560 14ad7326 pastith
                                return;
561 2f1a60e0 Dimitris Routsis
                            }
562 14ad7326 pastith
                    }
563 14ad7326 pastith
            } else {
564 14ad7326 pastith
                    if (ranges == null || ranges.isEmpty())
565 14ad7326 pastith
                            return;
566 14ad7326 pastith
                    // Partial content response.
567 14ad7326 pastith
                    resp.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
568 14ad7326 pastith
569 14ad7326 pastith
                    if (ranges.size() == 1) {
570 14ad7326 pastith
                            Range range = (Range) ranges.get(0);
571 14ad7326 pastith
                            resp.addHeader("Content-Range", "bytes "
572 14ad7326 pastith
                                                    + range.start
573 14ad7326 pastith
                                                    + "-" + range.end + "/"
574 14ad7326 pastith
                                                    + range.length);
575 14ad7326 pastith
                            long length = range.end - range.start + 1;
576 14ad7326 pastith
                            if (length < Integer.MAX_VALUE)
577 14ad7326 pastith
                                        resp.setContentLength((int) length);
578 14ad7326 pastith
                                else
579 14ad7326 pastith
                                        // Set the content-length as String to be able to use a long
580 14ad7326 pastith
                                    resp.setHeader("content-length", "" + length);
581 14ad7326 pastith
582 14ad7326 pastith
                            if (contentType != null) {
583 14ad7326 pastith
                                    if (logger.isDebugEnabled())
584 14ad7326 pastith
                                            logger.debug("contentType='" + contentType + "'");
585 14ad7326 pastith
                                    resp.setContentType(contentType);
586 14ad7326 pastith
                            }
587 14ad7326 pastith
588 14ad7326 pastith
                            if (content) {
589 14ad7326 pastith
                                    try {
590 14ad7326 pastith
                                            resp.setBufferSize(output);
591 14ad7326 pastith
                                    } catch (IllegalStateException e) {
592 14ad7326 pastith
                                            // Silent catch
593 14ad7326 pastith
                                    }
594 14ad7326 pastith
                                    try {
595 14ad7326 pastith
                                            if (ostream != null)
596 14ad7326 pastith
                                                        copy(file, ostream, range, req, oldBody);
597 14ad7326 pastith
                                                else
598 14ad7326 pastith
                                                        copy(file, writer, range, req, oldBody);
599 2f1a60e0 Dimitris Routsis
                                            updateAccounting(owner, new Date(), contentLength);
600 14ad7326 pastith
                                } catch (ObjectNotFoundException e) {
601 14ad7326 pastith
                                        resp.sendError(HttpServletResponse.SC_NOT_FOUND);
602 14ad7326 pastith
                                        return;
603 14ad7326 pastith
                                } catch (InsufficientPermissionsException e) {
604 14ad7326 pastith
                                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
605 14ad7326 pastith
                                        return;
606 14ad7326 pastith
                                } catch (RpcException e) {
607 14ad7326 pastith
                                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
608 14ad7326 pastith
                                        return;
609 14ad7326 pastith
                                }
610 14ad7326 pastith
                            }
611 14ad7326 pastith
                    } else {
612 14ad7326 pastith
                            resp.setContentType("multipart/byteranges; boundary=" + mimeSeparation);
613 14ad7326 pastith
                            if (content) {
614 14ad7326 pastith
                                    try {
615 14ad7326 pastith
                                            resp.setBufferSize(output);
616 14ad7326 pastith
                                    } catch (IllegalStateException e) {
617 14ad7326 pastith
                                            // Silent catch
618 14ad7326 pastith
                                    }
619 14ad7326 pastith
                                    try {
620 14ad7326 pastith
                                            if (ostream != null)
621 14ad7326 pastith
                                                        copy(file, ostream, ranges.iterator(), contentType, req, oldBody);
622 14ad7326 pastith
                                                else
623 14ad7326 pastith
                                                        copy(file, writer, ranges.iterator(), contentType, req, oldBody);
624 2f1a60e0 Dimitris Routsis
                                            updateAccounting(owner, new Date(), contentLength);
625 14ad7326 pastith
                                } catch (ObjectNotFoundException e) {
626 14ad7326 pastith
                                        resp.sendError(HttpServletResponse.SC_NOT_FOUND);
627 14ad7326 pastith
                                        return;
628 14ad7326 pastith
                                } catch (InsufficientPermissionsException e) {
629 14ad7326 pastith
                                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
630 14ad7326 pastith
                                        return;
631 14ad7326 pastith
                                } catch (RpcException e) {
632 14ad7326 pastith
                                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
633 14ad7326 pastith
                                        return;
634 14ad7326 pastith
                                }
635 14ad7326 pastith
                            }
636 14ad7326 pastith
                    }
637 14ad7326 pastith
            }
638 14ad7326 pastith
    }
639 14ad7326 pastith
640 14ad7326 pastith
        /**
641 a91ef7e8 Panagiotis Astithas
         * Handles an authentication failure. If no Authorization or Date request
642 a91ef7e8 Panagiotis Astithas
         * parameters and no Authorization, Date or X-GSS-Date headers were present,
643 a91ef7e8 Panagiotis Astithas
         * this is a browser request, so redirect to login and then let the user get
644 a91ef7e8 Panagiotis Astithas
         * back to the file. Otherwise it's a bogus client request and Forbidden is
645 a91ef7e8 Panagiotis Astithas
         * returned.
646 a91ef7e8 Panagiotis Astithas
         */
647 a91ef7e8 Panagiotis Astithas
        private void handleAuthFailure(HttpServletRequest req, HttpServletResponse resp) throws IOException {
648 a91ef7e8 Panagiotis Astithas
                if (req.getParameter(AUTHORIZATION_PARAMETER) == null &&
649 a91ef7e8 Panagiotis Astithas
                                req.getParameter(DATE_PARAMETER) == null &&
650 a91ef7e8 Panagiotis Astithas
                                req.getHeader(AUTHORIZATION_HEADER) == null &&
651 a91ef7e8 Panagiotis Astithas
                                req.getDateHeader(DATE_HEADER) == -1 &&
652 a91ef7e8 Panagiotis Astithas
                                req.getDateHeader(GSS_DATE_HEADER) == -1)
653 6567092b Panagiotis Astithas
                        resp.sendRedirect(getConfiguration().getString("loginUrl") +
654 a91ef7e8 Panagiotis Astithas
                                        "?next=" + req.getRequestURL().toString());
655 a91ef7e8 Panagiotis Astithas
                else
656 a91ef7e8 Panagiotis Astithas
                        resp.sendError(HttpServletResponse.SC_FORBIDDEN);
657 a91ef7e8 Panagiotis Astithas
        }
658 a91ef7e8 Panagiotis Astithas
659 a91ef7e8 Panagiotis Astithas
        /**
660 31ec597c Panagiotis Astithas
         * Return the filename of the specified file properly formatted for
661 31ec597c Panagiotis Astithas
         * including in the Content-Disposition header.
662 31ec597c Panagiotis Astithas
         */
663 f7c44c33 fstamatelopoulos
        private String getDispositionFilename(FileHeader file) throws UnsupportedEncodingException {
664 31ec597c Panagiotis Astithas
                return URLEncoder.encode(file.getName(),"UTF-8").replaceAll("\\+", "%20");
665 31ec597c Panagiotis Astithas
        }
666 31ec597c Panagiotis Astithas
667 31ec597c Panagiotis Astithas
        /**
668 5942d113 pastith
         * Determines whether the user agent needs the Content-Disposition
669 5942d113 pastith
         * header to be set, in order to properly download a file.
670 5942d113 pastith
         *
671 5942d113 pastith
         * @param req the HTTP request
672 5942d113 pastith
         * @return true if the Content-Disposition HTTP header must be set
673 5942d113 pastith
         */
674 5942d113 pastith
        private boolean needsContentDisposition(HttpServletRequest req) {
675 617fe906 Dimitris Routsis
                /*String agent = req.getHeader("user-agent");
676 50364cd8 pastith
                if (agent != null && agent.contains("MSIE"))
677 617fe906 Dimitris Routsis
                        return true;*/
678 617fe906 Dimitris Routsis
                String dl = req.getParameter("dl");
679 617fe906 Dimitris Routsis
                if ("1".equals(dl))
680 5942d113 pastith
                        return true;
681 5942d113 pastith
                return false;
682 5942d113 pastith
        }
683 5942d113 pastith
684 5942d113 pastith
        /**
685 f5903adf pastith
         * Sends a progress update on the amount of bytes received until now for
686 f5903adf pastith
         * a file that the current user is currently uploading.
687 f5903adf pastith
         *
688 f5903adf pastith
         * @param req the HTTP request
689 f5903adf pastith
         * @param resp the HTTP response
690 f5903adf pastith
         * @param parameter the value for the progress request parameter
691 f5903adf pastith
         * @param user the current user
692 f5903adf pastith
         * @param file the file being uploaded, or null if the request is about a new file
693 f5903adf pastith
         * @throws IOException if an I/O error occurs
694 f5903adf pastith
         */
695 f5903adf pastith
        private void serveProgress(HttpServletRequest req, HttpServletResponse resp,
696 f7c44c33 fstamatelopoulos
                                String parameter, User user, FileHeader file)        throws IOException {
697 f5903adf pastith
                String filename = file == null ? parameter : file.getName();
698 f5903adf pastith
                try {
699 f5903adf pastith
                        FileUploadStatus status = getService().getFileUploadStatus(user.getId(), filename);
700 f5903adf pastith
                        if (status == null) {
701 f5903adf pastith
                                resp.sendError(HttpServletResponse.SC_NOT_FOUND);
702 f5903adf pastith
                                return;
703 f5903adf pastith
                        }
704 f5903adf pastith
                        JSONObject json = new JSONObject();
705 f5903adf pastith
                        json.put("bytesUploaded", status.getBytesUploaded()).
706 f5903adf pastith
                                put("bytesTotal", status.getFileSize());
707 f5903adf pastith
                        sendJson(req, resp, json.toString());
708 470a59a7 pastith
709 470a59a7 pastith
                        // Workaround for IE's broken caching behavior.
710 470a59a7 pastith
                    resp.setHeader("Expires", "-1");
711 f5903adf pastith
                        return;
712 f5903adf pastith
                } catch (RpcException e) {
713 f5903adf pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
714 f5903adf pastith
                        return;
715 f5903adf pastith
                } catch (JSONException e) {
716 f5903adf pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
717 f5903adf pastith
                        return;
718 f5903adf pastith
                }
719 f5903adf pastith
        }
720 f5903adf pastith
721 f5903adf pastith
        /**
722 14ad7326 pastith
         * Server a POST request to create/modify a file or folder.
723 14ad7326 pastith
         *
724 14ad7326 pastith
         * @param req the HTTP request
725 14ad7326 pastith
         * @param resp the HTTP response
726 14ad7326 pastith
     * @exception IOException if an input/output error occurs
727 14ad7326 pastith
         */
728 14ad7326 pastith
        void postResource(HttpServletRequest req, HttpServletResponse resp) throws IOException {
729 bda7d76d pastith
                boolean authDeferred = getAuthDeferred(req);
730 bda7d76d pastith
            if (!authDeferred && req.getParameterMap().size() > 1) {
731 14ad7326 pastith
                    resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
732 14ad7326 pastith
                    return;
733 14ad7326 pastith
            }
734 14ad7326 pastith
        String path = getInnerPath(req, PATH_FILES);
735 14ad7326 pastith
            path = path.endsWith("/")? path: path + '/';
736 e8b747c4 pastith
                try {
737 e8b747c4 pastith
                    path = URLDecoder.decode(path, "UTF-8");
738 e8b747c4 pastith
                } catch (IllegalArgumentException e) {
739 e8b747c4 pastith
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
740 e8b747c4 pastith
                        return;
741 e8b747c4 pastith
                }
742 bda7d76d pastith
            // We only defer authenticating multipart POST requests.
743 bda7d76d pastith
            if (authDeferred) {
744 bda7d76d pastith
                        if (!ServletFileUpload.isMultipartContent(req)) {
745 bda7d76d pastith
                            resp.sendError(HttpServletResponse.SC_FORBIDDEN);
746 bda7d76d pastith
                            return;
747 bda7d76d pastith
                    }
748 bda7d76d pastith
                        handleMultipart(req, resp, path);
749 bda7d76d pastith
                        return;
750 bda7d76d pastith
                }
751 bda7d76d pastith
752 14ad7326 pastith
            String newName = req.getParameter(NEW_FOLDER_PARAMETER);
753 891f51ce Natasa Kapravelou
754 14ad7326 pastith
            boolean hasUpdateParam = req.getParameterMap().containsKey(RESOURCE_UPDATE_PARAMETER);
755 14ad7326 pastith
            boolean hasTrashParam = req.getParameterMap().containsKey(RESOURCE_TRASH_PARAMETER);
756 14ad7326 pastith
            boolean hasRestoreParam = req.getParameterMap().containsKey(RESOURCE_RESTORE_PARAMETER);
757 14ad7326 pastith
            String copyTo = req.getParameter(RESOURCE_COPY_PARAMETER);
758 14ad7326 pastith
            String moveTo = req.getParameter(RESOURCE_MOVE_PARAMETER);
759 39c34533 pastith
            String restoreVersion = req.getParameter(RESTORE_VERSION_PARAMETER);
760 14ad7326 pastith
761 891f51ce Natasa Kapravelou
            if (newName != null){
762 891f51ce Natasa Kapravelou
                if (!isValidResourceName(newName)) {
763 891f51ce Natasa Kapravelou
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
764 891f51ce Natasa Kapravelou
                        return;
765 891f51ce Natasa Kapravelou
                }
766 14ad7326 pastith
                        createFolder(req, resp, path, newName);
767 891f51ce Natasa Kapravelou
            }
768 a7bcd018 droutsis
            else if (hasUpdateParam)
769 14ad7326 pastith
                        updateResource(req, resp, path);
770 14ad7326 pastith
                else if (hasTrashParam)
771 14ad7326 pastith
                        trashResource(req, resp, path);
772 14ad7326 pastith
                else if (hasRestoreParam)
773 14ad7326 pastith
                        restoreResource(req, resp, path);
774 14ad7326 pastith
                else if (copyTo != null)
775 14ad7326 pastith
                        copyResource(req, resp, path, copyTo);
776 14ad7326 pastith
                else if (moveTo != null)
777 14ad7326 pastith
                        moveResource(req, resp, path, moveTo);
778 39c34533 pastith
                else if (restoreVersion != null)
779 39c34533 pastith
                        restoreVersion(req, resp, path, restoreVersion);
780 14ad7326 pastith
                else
781 9fd42cf4 Panagiotis Astithas
                        // IE with Gears uses POST for multiple uploads.
782 9fd42cf4 Panagiotis Astithas
                        putResource(req, resp);
783 14ad7326 pastith
        }
784 14ad7326 pastith
785 14ad7326 pastith
        /**
786 39c34533 pastith
         * Restores a previous version for a file.
787 39c34533 pastith
         *
788 39c34533 pastith
         * @param req the HTTP request
789 39c34533 pastith
         * @param resp the HTTP response
790 39c34533 pastith
         * @param path the resource path
791 39c34533 pastith
         * @param version the version number to restore
792 39c34533 pastith
         * @throws IOException if an I/O error occurs
793 39c34533 pastith
         */
794 39c34533 pastith
        private void restoreVersion(HttpServletRequest req, HttpServletResponse resp, String path, String version) throws IOException {
795 2f1a60e0 Dimitris Routsis
                final User user = getUser(req);
796 39c34533 pastith
                User owner = getOwner(req);
797 39c34533 pastith
                Object resource = null;
798 39c34533 pastith
                try {
799 39c34533 pastith
                        resource = getService().getResourceAtPath(owner.getId(), path, true);
800 39c34533 pastith
                } catch (ObjectNotFoundException e) {
801 39c34533 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, path);
802 39c34533 pastith
                        return;
803 39c34533 pastith
                } catch (RpcException e) {
804 39c34533 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
805 39c34533 pastith
                        return;
806 39c34533 pastith
                }
807 f7c44c33 fstamatelopoulos
                if (resource instanceof Folder) {
808 39c34533 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
809 39c34533 pastith
                        return;
810 39c34533 pastith
                }
811 39c34533 pastith
812 39c34533 pastith
                try {
813 f7c44c33 fstamatelopoulos
                        final FileHeader file = (FileHeader) resource;
814 2f1a60e0 Dimitris Routsis
                        final int oldVersion = Integer.parseInt(version);
815 2f1a60e0 Dimitris Routsis
816 2f1a60e0 Dimitris Routsis
                        new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
817 2f1a60e0 Dimitris Routsis
                                @Override
818 2f1a60e0 Dimitris Routsis
                                public Void call() throws Exception {
819 2f1a60e0 Dimitris Routsis
                                        getService().restoreVersion(user.getId(), file.getId(), oldVersion);
820 2f1a60e0 Dimitris Routsis
                                        return null;
821 2f1a60e0 Dimitris Routsis
                                }
822 2f1a60e0 Dimitris Routsis
                        });
823 39c34533 pastith
                } catch (InsufficientPermissionsException e) {
824 39c34533 pastith
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
825 39c34533 pastith
                } catch (ObjectNotFoundException e) {
826 39c34533 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
827 39c34533 pastith
                } catch (RpcException e) {
828 39c34533 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
829 39c34533 pastith
                } catch (GSSIOException e) {
830 39c34533 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
831 39c34533 pastith
                } catch (QuotaExceededException e) {
832 39c34533 pastith
                        resp.sendError(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, e.getMessage());
833 39c34533 pastith
                } catch (NumberFormatException e) {
834 39c34533 pastith
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
835 2f1a60e0 Dimitris Routsis
                } catch (Exception e) {
836 2f1a60e0 Dimitris Routsis
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
837 39c34533 pastith
                }
838 39c34533 pastith
        }
839 39c34533 pastith
840 39c34533 pastith
        /**
841 e150a336 pastith
         * A method for handling multipart POST requests for uploading
842 e150a336 pastith
         * files from browser-based JavaScript clients.
843 e150a336 pastith
         *
844 e150a336 pastith
         * @param request the HTTP request
845 e150a336 pastith
         * @param response the HTTP response
846 e150a336 pastith
         * @param path the resource path
847 e150a336 pastith
         * @throws IOException in case an error occurs writing to the
848 e150a336 pastith
         *                 response stream
849 e150a336 pastith
         */
850 e150a336 pastith
        private void handleMultipart(HttpServletRequest request, HttpServletResponse response, String path) throws IOException {
851 e150a336 pastith
            if (logger.isDebugEnabled())
852 e150a336 pastith
                           logger.debug("Multipart POST for resource: " + path);
853 e150a336 pastith
854 e150a336 pastith
            User owner = getOwner(request);
855 e150a336 pastith
            boolean exists = true;
856 e150a336 pastith
        Object resource = null;
857 f7c44c33 fstamatelopoulos
        FileHeader file = null;
858 e150a336 pastith
        try {
859 e150a336 pastith
                resource = getService().getResourceAtPath(owner.getId(), path, false);
860 e150a336 pastith
        } catch (ObjectNotFoundException e) {
861 e150a336 pastith
            exists = false;
862 e150a336 pastith
        } catch (RpcException e) {
863 e150a336 pastith
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
864 e150a336 pastith
                        return;
865 e150a336 pastith
                }
866 e150a336 pastith
867 e150a336 pastith
        if (exists)
868 f7c44c33 fstamatelopoulos
                        if (resource instanceof FileHeader) {
869 f7c44c33 fstamatelopoulos
                            file = (FileHeader) resource;
870 ebe40d2c pastith
                            if (file.isDeleted()) {
871 ebe40d2c pastith
                                    response.sendError(HttpServletResponse.SC_CONFLICT, file.getName() + " is in the trash");
872 ebe40d2c pastith
                                return;
873 ebe40d2c pastith
                            }
874 ebe40d2c pastith
                        } else {
875 e150a336 pastith
                        response.sendError(HttpServletResponse.SC_CONFLICT, path + " is a folder");
876 e150a336 pastith
                            return;
877 e150a336 pastith
                }
878 e150a336 pastith
879 e150a336 pastith
            Object parent;
880 e150a336 pastith
            String parentPath = null;
881 e150a336 pastith
                try {
882 e150a336 pastith
                        parentPath = getParentPath(path);
883 e150a336 pastith
                        parent = getService().getResourceAtPath(owner.getId(), parentPath, true);
884 e150a336 pastith
                } catch (ObjectNotFoundException e) {
885 e150a336 pastith
                    response.sendError(HttpServletResponse.SC_NOT_FOUND, parentPath);
886 e150a336 pastith
                    return;
887 e150a336 pastith
                } catch (RpcException e) {
888 e150a336 pastith
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
889 e150a336 pastith
                        return;
890 e150a336 pastith
                }
891 f7c44c33 fstamatelopoulos
            if (!(parent instanceof Folder)) {
892 e150a336 pastith
                    response.sendError(HttpServletResponse.SC_CONFLICT);
893 e150a336 pastith
                    return;
894 e150a336 pastith
            }
895 f7c44c33 fstamatelopoulos
            final Folder folderLocal = (Folder) parent;
896 2f1a60e0 Dimitris Routsis
            final String fileName = getLastElement(path);
897 e150a336 pastith
898 8b79a1c8 Natasa Kapravelou
            if (!isValidResourceName(fileName)) {
899 8b79a1c8 Natasa Kapravelou
                    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
900 8b79a1c8 Natasa Kapravelou
                    return;
901 8b79a1c8 Natasa Kapravelou
            }
902 8b79a1c8 Natasa Kapravelou
903 e150a336 pastith
                FileItemIterator iter;
904 e150a336 pastith
                File uploadedFile = null;
905 e150a336 pastith
                try {
906 e150a336 pastith
                        // Create a new file upload handler.
907 e150a336 pastith
                        ServletFileUpload upload = new ServletFileUpload();
908 e150a336 pastith
                        StatusProgressListener progressListener = new StatusProgressListener(getService());
909 e150a336 pastith
                        upload.setProgressListener(progressListener);
910 e150a336 pastith
                        iter = upload.getItemIterator(request);
911 bda7d76d pastith
                        String dateParam = null;
912 bda7d76d pastith
                        String auth = null;
913 e150a336 pastith
                        while (iter.hasNext()) {
914 e150a336 pastith
                                FileItemStream item = iter.next();
915 bda7d76d pastith
                                String name = item.getFieldName();
916 e150a336 pastith
                                InputStream stream = item.openStream();
917 bda7d76d pastith
                                if (item.isFormField()) {
918 bda7d76d pastith
                                        final String value = Streams.asString(stream);
919 bda7d76d pastith
                                        if (name.equals(DATE_PARAMETER))
920 bda7d76d pastith
                                                dateParam = value;
921 bda7d76d pastith
                                        else if (name.equals(AUTHORIZATION_PARAMETER))
922 bda7d76d pastith
                                                auth = value;
923 bda7d76d pastith
924 bda7d76d pastith
                                        if (logger.isDebugEnabled())
925 bda7d76d pastith
                                                logger.debug(name + ":" + value);
926 bda7d76d pastith
                                } else {
927 bda7d76d pastith
                                        // Fetch the timestamp used to guard against replay attacks.
928 bda7d76d pastith
                                    if (dateParam == null) {
929 bda7d76d pastith
                                            response.sendError(HttpServletResponse.SC_FORBIDDEN, "No Date parameter");
930 bda7d76d pastith
                                            return;
931 bda7d76d pastith
                                    }
932 bda7d76d pastith
933 bda7d76d pastith
                                    long timestamp;
934 bda7d76d pastith
                                        try {
935 bda7d76d pastith
                                                timestamp = DateUtil.parseDate(dateParam).getTime();
936 bda7d76d pastith
                                        } catch (DateParseException e) {
937 bda7d76d pastith
                                            response.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
938 bda7d76d pastith
                                            return;
939 bda7d76d pastith
                                        }
940 bda7d76d pastith
                                    if (!isTimeValid(timestamp)) {
941 bda7d76d pastith
                                            response.sendError(HttpServletResponse.SC_FORBIDDEN);
942 bda7d76d pastith
                                            return;
943 bda7d76d pastith
                                    }
944 bda7d76d pastith
945 bda7d76d pastith
                                        // Fetch the Authorization parameter and find the user specified in it.
946 bda7d76d pastith
                                    if (auth == null) {
947 bda7d76d pastith
                                            response.sendError(HttpServletResponse.SC_FORBIDDEN, "No Authorization parameter");
948 bda7d76d pastith
                                            return;
949 bda7d76d pastith
                                    }
950 bda7d76d pastith
                                        String[] authParts = auth.split(" ");
951 bda7d76d pastith
                                        if (authParts.length != 2) {
952 bda7d76d pastith
                                            response.sendError(HttpServletResponse.SC_FORBIDDEN);
953 bda7d76d pastith
                                            return;
954 bda7d76d pastith
                                    }
955 bda7d76d pastith
                                        String username = authParts[0];
956 bda7d76d pastith
                                        String signature = authParts[1];
957 bda7d76d pastith
                                        User user = null;
958 bda7d76d pastith
                                        try {
959 bda7d76d pastith
                                                user = getService().findUser(username);
960 bda7d76d pastith
                                        } catch (RpcException e) {
961 bda7d76d pastith
                                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
962 bda7d76d pastith
                                                return;
963 bda7d76d pastith
                                        }
964 bda7d76d pastith
                                        if (user == null) {
965 bda7d76d pastith
                                            response.sendError(HttpServletResponse.SC_FORBIDDEN);
966 bda7d76d pastith
                                            return;
967 bda7d76d pastith
                                    }
968 bda7d76d pastith
                                        request.setAttribute(USER_ATTRIBUTE, user);
969 bda7d76d pastith
970 c961594d pastith
                                        // Remove the servlet path from the request URI.
971 c961594d pastith
                                        String p = request.getRequestURI();
972 c961594d pastith
                                        String servletPath = request.getContextPath() + request.getServletPath();
973 c961594d pastith
                                        p = p.substring(servletPath.length());
974 bda7d76d pastith
                                        // Validate the signature in the Authorization parameter.
975 c961594d pastith
                                        String data = request.getMethod() + dateParam + p;
976 bda7d76d pastith
                                        if (!isSignatureValid(signature, user, data)) {
977 bda7d76d pastith
                                            response.sendError(HttpServletResponse.SC_FORBIDDEN);
978 bda7d76d pastith
                                            return;
979 bda7d76d pastith
                                    }
980 bda7d76d pastith
981 e150a336 pastith
                                        progressListener.setUserId(user.getId());
982 e150a336 pastith
                                        progressListener.setFilename(fileName);
983 2f1a60e0 Dimitris Routsis
                                        final String contentType = item.getContentType();
984 e150a336 pastith
985 e150a336 pastith
                                        try {
986 e150a336 pastith
                                                uploadedFile = getService().uploadFile(stream, user.getId());
987 e150a336 pastith
                                        } catch (IOException ex) {
988 e150a336 pastith
                                                throw new GSSIOException(ex, false);
989 e150a336 pastith
                                        }
990 f7c44c33 fstamatelopoulos
                                        FileHeader fileLocal = null;
991 2f1a60e0 Dimitris Routsis
                                        final File upf = uploadedFile;
992 f7c44c33 fstamatelopoulos
                                        final FileHeader f = file;
993 2f1a60e0 Dimitris Routsis
                                        final User u = user;
994 e150a336 pastith
                                        if (file == null)
995 f7c44c33 fstamatelopoulos
                                                fileLocal = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
996 2f1a60e0 Dimitris Routsis
                                                        @Override
997 f7c44c33 fstamatelopoulos
                                                        public FileHeader call() throws Exception {
998 f7c44c33 fstamatelopoulos
                                                                return getService().createFile(u.getId(), folderLocal.getId(), fileName, contentType, upf.getCanonicalFile().length(), upf.getAbsolutePath());
999 2f1a60e0 Dimitris Routsis
                                                        }
1000 2f1a60e0 Dimitris Routsis
                                                });
1001 e150a336 pastith
                                        else
1002 f7c44c33 fstamatelopoulos
                                                fileLocal = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
1003 2f1a60e0 Dimitris Routsis
                                                        @Override
1004 f7c44c33 fstamatelopoulos
                                                        public FileHeader call() throws Exception {
1005 2f1a60e0 Dimitris Routsis
                                                                return getService().updateFileContents(u.getId(), f.getId(), contentType, upf.getCanonicalFile().length(), upf.getAbsolutePath());
1006 2f1a60e0 Dimitris Routsis
                                                        }
1007 2f1a60e0 Dimitris Routsis
                                                });
1008 f7c44c33 fstamatelopoulos
                                        updateAccounting(owner, new Date(), fileLocal.getCurrentBody().getFileSize());
1009 599c9fc4 pastith
                                        getService().removeFileUploadProgress(user.getId(), fileName);
1010 e150a336 pastith
                                }
1011 e150a336 pastith
                        }
1012 2e7ca93c pastith
                        // We can't return 204 here since GWT's onSubmitComplete won't fire.
1013 2e7ca93c pastith
                        response.setContentType("text/html");
1014 2e7ca93c pastith
            response.getWriter().print("<pre></pre>");
1015 e150a336 pastith
                } catch (FileUploadException e) {
1016 e150a336 pastith
                        String error = "Error while uploading file";
1017 e150a336 pastith
                        logger.error(error, e);
1018 e150a336 pastith
                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error);
1019 e150a336 pastith
                } catch (GSSIOException e) {
1020 e150a336 pastith
                        if (uploadedFile != null && uploadedFile.exists())
1021 e150a336 pastith
                                uploadedFile.delete();
1022 e150a336 pastith
                        String error = "Error while uploading file";
1023 e150a336 pastith
                        if (e.logAsError())
1024 e150a336 pastith
                                logger.error(error, e);
1025 e150a336 pastith
                        else
1026 e150a336 pastith
                                logger.debug(error, e);
1027 e150a336 pastith
                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error);
1028 e150a336 pastith
                } catch (DuplicateNameException e) {
1029 e150a336 pastith
                        if (uploadedFile != null && uploadedFile.exists())
1030 e150a336 pastith
                                uploadedFile.delete();
1031 e150a336 pastith
                        String error = "The specified file name already exists in this folder";
1032 e150a336 pastith
                        logger.error(error, e);
1033 e150a336 pastith
                        response.sendError(HttpServletResponse.SC_CONFLICT, error);
1034 e150a336 pastith
1035 e150a336 pastith
                } catch (InsufficientPermissionsException e) {
1036 e150a336 pastith
                        if (uploadedFile != null && uploadedFile.exists())
1037 e150a336 pastith
                                uploadedFile.delete();
1038 e150a336 pastith
                        String error = "You don't have the necessary permissions";
1039 e150a336 pastith
                        logger.error(error, e);
1040 e150a336 pastith
                        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, error);
1041 e150a336 pastith
1042 e150a336 pastith
                } catch (QuotaExceededException e) {
1043 e150a336 pastith
                        if (uploadedFile != null && uploadedFile.exists())
1044 e150a336 pastith
                                uploadedFile.delete();
1045 e150a336 pastith
                        String error = "Not enough free space available";
1046 e150a336 pastith
                        if (logger.isDebugEnabled())
1047 e150a336 pastith
                                logger.debug(error, e);
1048 e150a336 pastith
                        response.sendError(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, error);
1049 e150a336 pastith
1050 e150a336 pastith
                } catch (ObjectNotFoundException e) {
1051 e150a336 pastith
                        if (uploadedFile != null && uploadedFile.exists())
1052 e150a336 pastith
                                uploadedFile.delete();
1053 e150a336 pastith
                        String error = "A specified object was not found";
1054 e150a336 pastith
                        logger.error(error, e);
1055 e150a336 pastith
                        response.sendError(HttpServletResponse.SC_NOT_FOUND, error);
1056 e150a336 pastith
                } catch (RpcException e) {
1057 e150a336 pastith
                        if (uploadedFile != null && uploadedFile.exists())
1058 e150a336 pastith
                                uploadedFile.delete();
1059 e150a336 pastith
                        String error = "An error occurred while communicating with the service";
1060 e150a336 pastith
                        logger.error(error, e);
1061 e150a336 pastith
                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error);
1062 2f1a60e0 Dimitris Routsis
                } catch (Exception e) {
1063 2f1a60e0 Dimitris Routsis
                        if (uploadedFile != null && uploadedFile.exists())
1064 2f1a60e0 Dimitris Routsis
                                uploadedFile.delete();
1065 2f1a60e0 Dimitris Routsis
                        String error = "An internal server error occurred";
1066 2f1a60e0 Dimitris Routsis
                        logger.error(error, e);
1067 2f1a60e0 Dimitris Routsis
                        response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, error);
1068 e150a336 pastith
                }
1069 e150a336 pastith
        }
1070 e150a336 pastith
1071 e150a336 pastith
        /**
1072 14ad7326 pastith
         * Move the resource in the specified path to the specified destination.
1073 14ad7326 pastith
         *
1074 14ad7326 pastith
         * @param req the HTTP request
1075 14ad7326 pastith
         * @param resp the HTTP response
1076 14ad7326 pastith
         * @param path the path of the resource
1077 14ad7326 pastith
         * @param moveTo the destination of the move procedure
1078 14ad7326 pastith
         * @throws IOException if an input/output error occurs
1079 14ad7326 pastith
         */
1080 14ad7326 pastith
        private void moveResource(HttpServletRequest req, HttpServletResponse resp, String path, String moveTo) throws IOException {
1081 2f1a60e0 Dimitris Routsis
                final User user = getUser(req);
1082 14ad7326 pastith
                User owner = getOwner(req);
1083 14ad7326 pastith
                Object resource = null;
1084 14ad7326 pastith
                try {
1085 68410d59 pastith
                        resource = getService().getResourceAtPath(owner.getId(), path, true);
1086 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1087 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, path);
1088 14ad7326 pastith
                        return;
1089 14ad7326 pastith
                } catch (RpcException e) {
1090 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1091 14ad7326 pastith
                        return;
1092 14ad7326 pastith
                }
1093 14ad7326 pastith
1094 14ad7326 pastith
        String destination = null;
1095 14ad7326 pastith
        User destOwner = null;
1096 14ad7326 pastith
                boolean exists = true;
1097 14ad7326 pastith
                try {
1098 5e2b8ec6 koutsoub
                        destination = getDestinationPath(req, encodePath(moveTo));
1099 5e2b8ec6 koutsoub
                        destination = URLDecoder.decode(destination, "UTF-8");
1100 14ad7326 pastith
                        destOwner = getDestinationOwner(req);
1101 68410d59 pastith
                        getService().getResourceAtPath(destOwner.getId(), destination, true);
1102 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1103 14ad7326 pastith
                        exists = false;
1104 14ad7326 pastith
                } catch (URISyntaxException e) {
1105 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
1106 14ad7326 pastith
                        return;
1107 14ad7326 pastith
                } catch (RpcException e) {
1108 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, destination);
1109 14ad7326 pastith
                        return;
1110 14ad7326 pastith
                }
1111 14ad7326 pastith
                if (exists) {
1112 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT, destination + " already exists");
1113 14ad7326 pastith
                        return;
1114 14ad7326 pastith
                }
1115 14ad7326 pastith
1116 14ad7326 pastith
                try {
1117 2f1a60e0 Dimitris Routsis
                        final User dOwner = destOwner;
1118 2f1a60e0 Dimitris Routsis
                        final String dest = destination;
1119 f7c44c33 fstamatelopoulos
                        if (resource instanceof Folder) {
1120 f7c44c33 fstamatelopoulos
                                final Folder folderLocal = (Folder) resource;
1121 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1122 2f1a60e0 Dimitris Routsis
                                        @Override
1123 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1124 f7c44c33 fstamatelopoulos
                                                getService().moveFolderToPath(user.getId(), dOwner.getId(), folderLocal.getId(), dest);
1125 2f1a60e0 Dimitris Routsis
                                                return null;
1126 2f1a60e0 Dimitris Routsis
                                        }
1127 2f1a60e0 Dimitris Routsis
                                });
1128 14ad7326 pastith
                        } else {
1129 f7c44c33 fstamatelopoulos
                                final FileHeader fileLocal = (FileHeader) resource;
1130 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1131 2f1a60e0 Dimitris Routsis
                                        @Override
1132 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1133 f7c44c33 fstamatelopoulos
                                                getService().moveFileToPath(user.getId(), dOwner.getId(), fileLocal.getId(), dest);
1134 2f1a60e0 Dimitris Routsis
                                                return null;
1135 2f1a60e0 Dimitris Routsis
                                        }
1136 2f1a60e0 Dimitris Routsis
                                });
1137 2f1a60e0 Dimitris Routsis
1138 14ad7326 pastith
                        }
1139 14ad7326 pastith
                } catch (InsufficientPermissionsException e) {
1140 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1141 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1142 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
1143 14ad7326 pastith
                } catch (RpcException e) {
1144 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, destination);
1145 14ad7326 pastith
                } catch (DuplicateNameException e) {
1146 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT, e.getMessage());
1147 14ad7326 pastith
                } catch (GSSIOException e) {
1148 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1149 14ad7326 pastith
                } catch (QuotaExceededException e) {
1150 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, e.getMessage());
1151 2f1a60e0 Dimitris Routsis
                } catch (Exception e) {
1152 2f1a60e0 Dimitris Routsis
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, destination);
1153 14ad7326 pastith
                }
1154 14ad7326 pastith
        }
1155 14ad7326 pastith
1156 14ad7326 pastith
        /**
1157 14ad7326 pastith
         * Copy the resource in the specified path to the specified destination.
1158 14ad7326 pastith
         *
1159 14ad7326 pastith
         * @param req the HTTP request
1160 14ad7326 pastith
         * @param resp the HTTP response
1161 14ad7326 pastith
         * @param path the path of the resource
1162 14ad7326 pastith
         * @param copyTo the destination of the copy procedure
1163 14ad7326 pastith
         * @throws IOException if an input/output error occurs
1164 14ad7326 pastith
         */
1165 14ad7326 pastith
        private void copyResource(HttpServletRequest req, HttpServletResponse resp, String path, String copyTo) throws IOException {
1166 2f1a60e0 Dimitris Routsis
                final User user = getUser(req);
1167 14ad7326 pastith
                User owner = getOwner(req);
1168 14ad7326 pastith
                Object resource = null;
1169 14ad7326 pastith
                try {
1170 68410d59 pastith
                        resource = getService().getResourceAtPath(owner.getId(), path, true);
1171 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1172 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, path);
1173 14ad7326 pastith
                        return;
1174 14ad7326 pastith
                } catch (RpcException e) {
1175 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1176 14ad7326 pastith
                        return;
1177 14ad7326 pastith
                }
1178 14ad7326 pastith
1179 14ad7326 pastith
        String destination = null;
1180 14ad7326 pastith
        User destOwner = null;
1181 14ad7326 pastith
                boolean exists = true;
1182 14ad7326 pastith
                try {
1183 4c44fdca Dimitris Routsis
                        String destinationEncoded = getDestinationPath(req, encodePath(copyTo));
1184 4c44fdca Dimitris Routsis
                        destination = URLDecoder.decode(destinationEncoded, "UTF-8");
1185 14ad7326 pastith
                        destOwner = getDestinationOwner(req);
1186 4c44fdca Dimitris Routsis
                        getService().getResourceAtPath(destOwner.getId(), destinationEncoded, true);
1187 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1188 14ad7326 pastith
                        exists = false;
1189 14ad7326 pastith
                } catch (URISyntaxException e) {
1190 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
1191 14ad7326 pastith
                        return;
1192 14ad7326 pastith
                } catch (RpcException e) {
1193 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, destination);
1194 14ad7326 pastith
                        return;
1195 14ad7326 pastith
                }
1196 14ad7326 pastith
                if (exists) {
1197 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT, destination + " already exists");
1198 14ad7326 pastith
                        return;
1199 14ad7326 pastith
                }
1200 14ad7326 pastith
1201 14ad7326 pastith
                try {
1202 2f1a60e0 Dimitris Routsis
                        final User dOwner = destOwner;
1203 2f1a60e0 Dimitris Routsis
                        final String dest = destination;
1204 f7c44c33 fstamatelopoulos
                        if (resource instanceof Folder) {
1205 f7c44c33 fstamatelopoulos
                                final Folder folderLocal = (Folder) resource;
1206 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1207 2f1a60e0 Dimitris Routsis
                                        @Override
1208 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1209 f7c44c33 fstamatelopoulos
                                                getService().copyFolderStructureToPath(user.getId(), dOwner.getId(), folderLocal.getId(), dest);
1210 2f1a60e0 Dimitris Routsis
                                                return null;
1211 2f1a60e0 Dimitris Routsis
                                        }
1212 2f1a60e0 Dimitris Routsis
                                });
1213 14ad7326 pastith
                        } else {
1214 f7c44c33 fstamatelopoulos
                                final FileHeader fileLocal = (FileHeader) resource;
1215 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1216 2f1a60e0 Dimitris Routsis
                                        @Override
1217 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1218 f7c44c33 fstamatelopoulos
                                                getService().copyFileToPath(user.getId(), dOwner.getId(), fileLocal.getId(), dest);
1219 2f1a60e0 Dimitris Routsis
                                                return null;
1220 2f1a60e0 Dimitris Routsis
                                        }
1221 2f1a60e0 Dimitris Routsis
                                });
1222 14ad7326 pastith
                        }
1223 14ad7326 pastith
                } catch (InsufficientPermissionsException e) {
1224 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1225 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1226 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
1227 14ad7326 pastith
                } catch (RpcException e) {
1228 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, destination);
1229 14ad7326 pastith
                } catch (DuplicateNameException e) {
1230 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT, e.getMessage());
1231 14ad7326 pastith
                } catch (GSSIOException e) {
1232 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
1233 14ad7326 pastith
                } catch (QuotaExceededException e) {
1234 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, e.getMessage());
1235 2f1a60e0 Dimitris Routsis
                } catch (Exception e) {
1236 2f1a60e0 Dimitris Routsis
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, destination);
1237 14ad7326 pastith
                }
1238 14ad7326 pastith
        }
1239 14ad7326 pastith
1240 5e2b8ec6 koutsoub
        private String encodePath(String path) throws UnsupportedEncodingException{
1241 5e2b8ec6 koutsoub
                StringTokenizer str = new StringTokenizer(path, "/:", true);
1242 5e2b8ec6 koutsoub
                String result = new String();
1243 5e2b8ec6 koutsoub
                while(str.hasMoreTokens()){
1244 5e2b8ec6 koutsoub
                        String token = str.nextToken();
1245 5e2b8ec6 koutsoub
                        if(!token.equals("/") && !token.equals(":"))
1246 5e2b8ec6 koutsoub
                                token = URLEncoder.encode(token,"UTF-8");
1247 5e2b8ec6 koutsoub
                        result = result + token;
1248 5e2b8ec6 koutsoub
                }
1249 5e2b8ec6 koutsoub
                return result;
1250 5e2b8ec6 koutsoub
        }
1251 14ad7326 pastith
        /**
1252 14ad7326 pastith
         * A helper method that extracts the relative resource path,
1253 14ad7326 pastith
         * after removing the 'files' namespace.
1254 4c44fdca Dimitris Routsis
         * The path returned is <i>not</i> URL-decoded.
1255 14ad7326 pastith
         *
1256 14ad7326 pastith
         * @param req the HTTP request
1257 14ad7326 pastith
         * @param path the specified path
1258 14ad7326 pastith
         * @return the path relative to the root folder
1259 14ad7326 pastith
         * @throws URISyntaxException
1260 14ad7326 pastith
         * @throws RpcException in case an error occurs while communicating
1261 14ad7326 pastith
         *                                                 with the backend
1262 4c44fdca Dimitris Routsis
         * @throws UnsupportedEncodingException
1263 14ad7326 pastith
         */
1264 4c44fdca Dimitris Routsis
        private String getDestinationPath(HttpServletRequest req, String path) throws URISyntaxException, RpcException, UnsupportedEncodingException {
1265 14ad7326 pastith
                URI uri = new URI(path);
1266 4c44fdca Dimitris Routsis
                String dest = uri.getRawPath();
1267 14ad7326 pastith
                // Remove the context path from the destination URI.
1268 14ad7326 pastith
                String contextPath = req.getContextPath();
1269 14ad7326 pastith
                if (!dest.startsWith(contextPath))
1270 14ad7326 pastith
                        throw new URISyntaxException(dest, "Destination path does not start with " + contextPath);
1271 14ad7326 pastith
                dest = dest.substring(contextPath.length());
1272 14ad7326 pastith
                // Remove the servlet path from the destination URI.
1273 14ad7326 pastith
                String servletPath = req.getServletPath();
1274 14ad7326 pastith
                if (!dest.startsWith(servletPath))
1275 14ad7326 pastith
                        throw new URISyntaxException(dest, "Destination path does not start with " + servletPath);
1276 14ad7326 pastith
                dest = dest.substring(servletPath.length());
1277 14ad7326 pastith
            // Strip the username part
1278 14ad7326 pastith
                if (dest.length() < 2)
1279 14ad7326 pastith
                        throw new URISyntaxException(dest, "No username in the destination URI");
1280 14ad7326 pastith
                int slash = dest.substring(1).indexOf('/');
1281 14ad7326 pastith
                if (slash == -1)
1282 14ad7326 pastith
                        throw new URISyntaxException(dest, "No username in the destination URI");
1283 4c44fdca Dimitris Routsis
                // Decode the user to get the proper characters (mainly the @)
1284 4c44fdca Dimitris Routsis
                String owner = URLDecoder.decode(dest.substring(1, slash + 1), "UTF-8");
1285 14ad7326 pastith
                User o;
1286 14ad7326 pastith
                o = getService().findUser(owner);
1287 14ad7326 pastith
                if (o == null)
1288 14ad7326 pastith
                        throw new URISyntaxException(dest, "User " + owner + " not found");
1289 14ad7326 pastith
1290 14ad7326 pastith
                req.setAttribute(DESTINATION_OWNER_ATTRIBUTE, o);
1291 14ad7326 pastith
                dest = dest.substring(slash + 1);
1292 14ad7326 pastith
1293 14ad7326 pastith
                // Chop the resource namespace part
1294 14ad7326 pastith
                dest = dest.substring(RequestHandler.PATH_FILES.length());
1295 14ad7326 pastith
1296 14ad7326 pastith
            dest = dest.endsWith("/")? dest: dest + '/';
1297 14ad7326 pastith
                return dest;
1298 14ad7326 pastith
        }
1299 14ad7326 pastith
1300 14ad7326 pastith
        /**
1301 14ad7326 pastith
         * Move the resource in the specified path to the trash bin.
1302 14ad7326 pastith
         *
1303 14ad7326 pastith
         * @param req the HTTP request
1304 14ad7326 pastith
         * @param resp the HTTP response
1305 14ad7326 pastith
         * @param path the path of the resource
1306 14ad7326 pastith
         * @throws IOException if an input/output error occurs
1307 14ad7326 pastith
         */
1308 14ad7326 pastith
        private void trashResource(HttpServletRequest req, HttpServletResponse resp, String path) throws IOException {
1309 2f1a60e0 Dimitris Routsis
                final User user = getUser(req);
1310 14ad7326 pastith
                User owner = getOwner(req);
1311 14ad7326 pastith
                Object resource = null;
1312 14ad7326 pastith
                try {
1313 68410d59 pastith
                        resource = getService().getResourceAtPath(owner.getId(), path, true);
1314 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1315 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, path);
1316 14ad7326 pastith
                        return;
1317 14ad7326 pastith
                } catch (RpcException e) {
1318 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1319 14ad7326 pastith
                        return;
1320 14ad7326 pastith
                }
1321 14ad7326 pastith
1322 14ad7326 pastith
                try {
1323 f7c44c33 fstamatelopoulos
                        if (resource instanceof Folder) {
1324 f7c44c33 fstamatelopoulos
                                final Folder folderLocal = (Folder) resource;
1325 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1326 2f1a60e0 Dimitris Routsis
                                        @Override
1327 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1328 f7c44c33 fstamatelopoulos
                                                getService().moveFolderToTrash(user.getId(), folderLocal.getId());
1329 2f1a60e0 Dimitris Routsis
                                                return null;
1330 2f1a60e0 Dimitris Routsis
                                        }
1331 2f1a60e0 Dimitris Routsis
                                });
1332 14ad7326 pastith
                        } else {
1333 f7c44c33 fstamatelopoulos
                                final FileHeader fileLocal = (FileHeader) resource;
1334 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1335 2f1a60e0 Dimitris Routsis
                                        @Override
1336 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1337 f7c44c33 fstamatelopoulos
                                                getService().moveFileToTrash(user.getId(), fileLocal.getId());
1338 2f1a60e0 Dimitris Routsis
                                                return null;
1339 2f1a60e0 Dimitris Routsis
                                        }
1340 2f1a60e0 Dimitris Routsis
                                });
1341 14ad7326 pastith
                        }
1342 14ad7326 pastith
                } catch (InsufficientPermissionsException e) {
1343 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1344 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1345 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
1346 14ad7326 pastith
                } catch (RpcException e) {
1347 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1348 2f1a60e0 Dimitris Routsis
                } catch (Exception e) {
1349 2f1a60e0 Dimitris Routsis
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1350 14ad7326 pastith
                }
1351 14ad7326 pastith
        }
1352 14ad7326 pastith
1353 14ad7326 pastith
        /**
1354 14ad7326 pastith
         * Restore the resource in the specified path from the trash bin.
1355 14ad7326 pastith
         *
1356 14ad7326 pastith
         * @param req the HTTP request
1357 14ad7326 pastith
         * @param resp the HTTP response
1358 14ad7326 pastith
         * @param path the path of the resource
1359 14ad7326 pastith
         * @throws IOException if an input/output error occurs
1360 14ad7326 pastith
         */
1361 14ad7326 pastith
        private void restoreResource(HttpServletRequest req, HttpServletResponse resp, String path) throws IOException {
1362 2f1a60e0 Dimitris Routsis
                final User user = getUser(req);
1363 14ad7326 pastith
                User owner = getOwner(req);
1364 14ad7326 pastith
                Object resource = null;
1365 14ad7326 pastith
                try {
1366 e150a336 pastith
                        resource = getService().getResourceAtPath(owner.getId(), path, false);
1367 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1368 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, path);
1369 14ad7326 pastith
                        return;
1370 14ad7326 pastith
                } catch (RpcException e) {
1371 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1372 14ad7326 pastith
                        return;
1373 14ad7326 pastith
                }
1374 14ad7326 pastith
1375 14ad7326 pastith
                try {
1376 f7c44c33 fstamatelopoulos
                        if (resource instanceof Folder) {
1377 f7c44c33 fstamatelopoulos
                                final Folder folderLocal = (Folder) resource;
1378 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1379 2f1a60e0 Dimitris Routsis
                                        @Override
1380 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1381 f7c44c33 fstamatelopoulos
                                                getService().removeFolderFromTrash(user.getId(), folderLocal.getId());
1382 2f1a60e0 Dimitris Routsis
                                                return null;
1383 2f1a60e0 Dimitris Routsis
                                        }
1384 2f1a60e0 Dimitris Routsis
                                });
1385 14ad7326 pastith
                        } else {
1386 f7c44c33 fstamatelopoulos
                                final FileHeader fileLocal = (FileHeader) resource;
1387 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1388 2f1a60e0 Dimitris Routsis
                                        @Override
1389 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1390 f7c44c33 fstamatelopoulos
                                                getService().removeFileFromTrash(user.getId(), fileLocal.getId());
1391 2f1a60e0 Dimitris Routsis
                                                return null;
1392 2f1a60e0 Dimitris Routsis
                                        }
1393 2f1a60e0 Dimitris Routsis
                                });
1394 14ad7326 pastith
                        }
1395 14ad7326 pastith
                } catch (InsufficientPermissionsException e) {
1396 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1397 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1398 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
1399 14ad7326 pastith
                } catch (RpcException e) {
1400 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1401 2f1a60e0 Dimitris Routsis
                } catch (Exception e) {
1402 2f1a60e0 Dimitris Routsis
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1403 14ad7326 pastith
                }
1404 14ad7326 pastith
        }
1405 14ad7326 pastith
1406 14ad7326 pastith
        /**
1407 14ad7326 pastith
         * Update the resource in the specified path.
1408 14ad7326 pastith
         *
1409 14ad7326 pastith
         * @param req the HTTP request
1410 14ad7326 pastith
         * @param resp the HTTP response
1411 14ad7326 pastith
         * @param path the path of the resource
1412 14ad7326 pastith
         * @throws IOException if an input/output error occurs
1413 14ad7326 pastith
         */
1414 14ad7326 pastith
        private void updateResource(HttpServletRequest req, HttpServletResponse resp, String path) throws IOException {
1415 77dcb3f1 Panagiotis Astithas
                final User user = getUser(req);
1416 14ad7326 pastith
                User owner = getOwner(req);
1417 14ad7326 pastith
                Object resource = null;
1418 9e6a28ed Natasa Kapravelou
1419 14ad7326 pastith
                try {
1420 3d1b9329 koutsoub
                        resource = getService().getResourceAtPath(owner.getId(), path, false);
1421 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1422 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, path);
1423 14ad7326 pastith
                        return;
1424 14ad7326 pastith
                } catch (RpcException e) {
1425 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1426 14ad7326 pastith
                        return;
1427 14ad7326 pastith
                }
1428 14ad7326 pastith
                StringBuffer input = new StringBuffer();
1429 14ad7326 pastith
                JSONObject json = null;
1430 a2c88d01 Panagiotis Astithas
                if (req.getContentType() != null && req.getContentType().startsWith("application/x-www-form-urlencoded"))
1431 f9e01fcb Panagiotis Astithas
                        input.append(req.getParameter(RESOURCE_UPDATE_PARAMETER));
1432 f9e01fcb Panagiotis Astithas
                else {
1433 f9e01fcb Panagiotis Astithas
                        // Assume application/json
1434 f9e01fcb Panagiotis Astithas
                        BufferedReader reader = new BufferedReader(new InputStreamReader(req.getInputStream(),"UTF-8"));
1435 f9e01fcb Panagiotis Astithas
                        String line = null;
1436 f9e01fcb Panagiotis Astithas
                        while ((line = reader.readLine()) != null)
1437 f9e01fcb Panagiotis Astithas
                                input.append(line);
1438 f9e01fcb Panagiotis Astithas
                        reader.close();
1439 f9e01fcb Panagiotis Astithas
                }
1440 14ad7326 pastith
                try {
1441 14ad7326 pastith
                        json = new JSONObject(input.toString());
1442 14ad7326 pastith
                        if (logger.isDebugEnabled())
1443 14ad7326 pastith
                                logger.debug("JSON update: " + json);
1444 f7c44c33 fstamatelopoulos
                        if (resource instanceof Folder) {
1445 f7c44c33 fstamatelopoulos
                                final Folder folderLocal = (Folder) resource;
1446 14ad7326 pastith
                                String name = json.optString("name");
1447 891f51ce Natasa Kapravelou
                                if (!isValidResourceName(name)) {
1448 891f51ce Natasa Kapravelou
                                resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
1449 891f51ce Natasa Kapravelou
                                return;
1450 891f51ce Natasa Kapravelou
                        }
1451 ba5f9575 Panagiotis Astithas
                                JSONArray permissions = json.optJSONArray("permissions");
1452 f7c44c33 fstamatelopoulos
                                Set<Permission> perms = null;
1453 ba5f9575 Panagiotis Astithas
                                if (permissions != null)
1454 ba5f9575 Panagiotis Astithas
                                        perms = parsePermissions(user, permissions);
1455 9e6a28ed Natasa Kapravelou
                                Boolean readForAll = null;
1456 9e6a28ed Natasa Kapravelou
                                if (json.opt("readForAll") != null)
1457 9e6a28ed Natasa Kapravelou
                                        readForAll = json.optBoolean("readForAll");
1458 9e6a28ed Natasa Kapravelou
                                if (!name.isEmpty() || permissions != null || readForAll != null) {
1459 ba5f9575 Panagiotis Astithas
                                        final String fName = name.isEmpty()? null: name;
1460 46397af3 Panagiotis Astithas
                                        final Boolean freadForAll =  readForAll;
1461 f7c44c33 fstamatelopoulos
                                        final Set<Permission> fPerms = perms;
1462 f7c44c33 fstamatelopoulos
                                        Folder folderUpdated = new TransactionHelper<Folder>().tryExecute(new Callable<Folder>() {
1463 77dcb3f1 Panagiotis Astithas
                                                @Override
1464 f7c44c33 fstamatelopoulos
                                                public Folder call() throws Exception {
1465 f7c44c33 fstamatelopoulos
                                                        return getService().updateFolder(user.getId(), folderLocal.getId(), fName, freadForAll, fPerms);
1466 77dcb3f1 Panagiotis Astithas
                                                }
1467 77dcb3f1 Panagiotis Astithas
1468 77dcb3f1 Panagiotis Astithas
                                        });
1469 425e3d5e Panagiotis Astithas
                                        resp.getWriter().println(getNewUrl(req, folderUpdated));
1470 5e2b8ec6 koutsoub
                                }
1471 14ad7326 pastith
                        } else {
1472 f7c44c33 fstamatelopoulos
                                final FileHeader fileLocal = (FileHeader) resource;
1473 14ad7326 pastith
                                String name = null;
1474 14ad7326 pastith
                                if (json.opt("name") != null)
1475 14ad7326 pastith
                                        name = json.optString("name");
1476 9bee2fe5 Natasa Kapravelou
                                if (name != null)
1477 9bee2fe5 Natasa Kapravelou
                                        if (!isValidResourceName(name)) {
1478 9bee2fe5 Natasa Kapravelou
                                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
1479 9bee2fe5 Natasa Kapravelou
                                        return;
1480 9bee2fe5 Natasa Kapravelou
                                }
1481 d114cfe2 Panagiotis Astithas
                                Long modificationDate = null;
1482 d114cfe2 Panagiotis Astithas
                                if (json.optLong("modificationDate") != 0)
1483 d114cfe2 Panagiotis Astithas
                                        modificationDate = json.optLong("modificationDate");
1484 d74c0270 Panagiotis Astithas
                                Boolean versioned = null;
1485 d74c0270 Panagiotis Astithas
                                if (json.opt("versioned") != null)
1486 d74c0270 Panagiotis Astithas
                                        versioned = json.getBoolean("versioned");
1487 14ad7326 pastith
                                JSONArray tagset = json.optJSONArray("tags");
1488 867d129b Fotis Stamatelopoulos
                                String tags = null;
1489 14ad7326 pastith
                                StringBuffer t = new StringBuffer();
1490 14ad7326 pastith
                                if (tagset != null) {
1491 14ad7326 pastith
                                        for (int i = 0; i < tagset.length(); i++)
1492 14ad7326 pastith
                                                t.append(tagset.getString(i) + ',');
1493 14ad7326 pastith
                                        tags = t.toString();
1494 14ad7326 pastith
                                }
1495 14ad7326 pastith
                                JSONArray permissions = json.optJSONArray("permissions");
1496 f7c44c33 fstamatelopoulos
                                Set<Permission> perms = null;
1497 14ad7326 pastith
                                if (permissions != null)
1498 14ad7326 pastith
                                        perms = parsePermissions(user, permissions);
1499 14ad7326 pastith
                                Boolean readForAll = null;
1500 14ad7326 pastith
                                if (json.opt("readForAll") != null)
1501 14ad7326 pastith
                                        readForAll = json.optBoolean("readForAll");
1502 d74c0270 Panagiotis Astithas
                                if (name != null || tags != null || modificationDate != null
1503 d74c0270 Panagiotis Astithas
                                                        || versioned != null || perms != null
1504 d74c0270 Panagiotis Astithas
                                                        || readForAll != null) {
1505 d74c0270 Panagiotis Astithas
                                        final String fName = name;
1506 d74c0270 Panagiotis Astithas
                                        final String fTags = tags;
1507 d74c0270 Panagiotis Astithas
                                        final Date mDate = modificationDate != null? new Date(modificationDate): null;
1508 d74c0270 Panagiotis Astithas
                                        final Boolean fVersioned = versioned;
1509 77dcb3f1 Panagiotis Astithas
                                        final Boolean fReadForAll = readForAll;
1510 f7c44c33 fstamatelopoulos
                                        final Set<Permission> fPerms = perms;
1511 77dcb3f1 Panagiotis Astithas
                                        new TransactionHelper<Object>().tryExecute(new Callable<Object>() {
1512 77dcb3f1 Panagiotis Astithas
                                                @Override
1513 77dcb3f1 Panagiotis Astithas
                                                public Object call() throws Exception {
1514 f7c44c33 fstamatelopoulos
                                                        getService().updateFile(user.getId(), fileLocal.getId(),
1515 d74c0270 Panagiotis Astithas
                                                                                fName, fTags, mDate, fVersioned,
1516 d74c0270 Panagiotis Astithas
                                                                                fReadForAll, fPerms);
1517 77dcb3f1 Panagiotis Astithas
                                                        return null;
1518 77dcb3f1 Panagiotis Astithas
                                                }
1519 77dcb3f1 Panagiotis Astithas
1520 77dcb3f1 Panagiotis Astithas
                                        });
1521 14ad7326 pastith
                                }
1522 14ad7326 pastith
                        }
1523 14ad7326 pastith
                } catch (JSONException e) {
1524 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
1525 14ad7326 pastith
                } catch (InsufficientPermissionsException e) {
1526 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1527 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1528 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_NOT_FOUND, e.getMessage());
1529 14ad7326 pastith
                } catch (DuplicateNameException e) {
1530 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT, e.getMessage());
1531 14ad7326 pastith
                } catch (RpcException e) {
1532 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1533 77dcb3f1 Panagiotis Astithas
                } catch (Exception e) {
1534 77dcb3f1 Panagiotis Astithas
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1535 77dcb3f1 Panagiotis Astithas
                        return;
1536 14ad7326 pastith
                }
1537 14ad7326 pastith
        }
1538 14ad7326 pastith
1539 14ad7326 pastith
        /**
1540 425e3d5e Panagiotis Astithas
         * Returns the new URL of an updated folder.
1541 425e3d5e Panagiotis Astithas
         */
1542 f7c44c33 fstamatelopoulos
        private String getNewUrl(HttpServletRequest req, Folder folder) throws UnsupportedEncodingException {
1543 8dca7586 Panagiotis Astithas
                String parentUrl = URLDecoder.decode(getContextPath(req, true),"UTF-8");
1544 8dca7586 Panagiotis Astithas
                String fpath = URLDecoder.decode(getRelativePath(req), "UTF-8");
1545 425e3d5e Panagiotis Astithas
                if (parentUrl.indexOf(fpath) != -1)
1546 425e3d5e Panagiotis Astithas
                        parentUrl = parentUrl.substring(0, parentUrl.indexOf(fpath));
1547 425e3d5e Panagiotis Astithas
                if(!parentUrl.endsWith("/"))
1548 425e3d5e Panagiotis Astithas
                        parentUrl = parentUrl+"/";
1549 425e3d5e Panagiotis Astithas
                parentUrl = parentUrl+folder.getOwner().getUsername()+PATH_FILES+folder.getPath();
1550 425e3d5e Panagiotis Astithas
                return parentUrl;
1551 425e3d5e Panagiotis Astithas
        }
1552 425e3d5e Panagiotis Astithas
1553 425e3d5e Panagiotis Astithas
        /**
1554 14ad7326 pastith
         * Helper method to convert a JSON array of permissions into a set of
1555 f7c44c33 fstamatelopoulos
         * Permission objects.
1556 14ad7326 pastith
         *
1557 14ad7326 pastith
         * @param user the current user
1558 14ad7326 pastith
         * @param permissions the JSON array to parse
1559 14ad7326 pastith
         * @return the parsed set of permissions
1560 14ad7326 pastith
         * @throws JSONException if there was an error parsing the JSON object
1561 14ad7326 pastith
         * @throws RpcException if there was an error communicating with the EJB
1562 14ad7326 pastith
         * @throws ObjectNotFoundException if the user could not be found
1563 867d129b Fotis Stamatelopoulos
         * @throws UnsupportedEncodingException
1564 14ad7326 pastith
         */
1565 f7c44c33 fstamatelopoulos
        private Set<Permission> parsePermissions(User user, JSONArray permissions)
1566 867d129b Fotis Stamatelopoulos
                        throws JSONException, RpcException, ObjectNotFoundException, UnsupportedEncodingException {
1567 14ad7326 pastith
                if (permissions == null)
1568 14ad7326 pastith
                        return null;
1569 f7c44c33 fstamatelopoulos
                Set<Permission> perms = new HashSet<Permission>();
1570 14ad7326 pastith
                for (int i = 0; i < permissions.length(); i++) {
1571 14ad7326 pastith
                        JSONObject j = permissions.getJSONObject(i);
1572 f7c44c33 fstamatelopoulos
                        Permission perm = new Permission();
1573 14ad7326 pastith
                        perm.setModifyACL(j.optBoolean("modifyACL"));
1574 14ad7326 pastith
                        perm.setRead(j.optBoolean("read"));
1575 14ad7326 pastith
                        perm.setWrite(j.optBoolean("write"));
1576 14ad7326 pastith
                        String permUser = j.optString("user");
1577 14ad7326 pastith
                        if (!permUser.isEmpty()) {
1578 14ad7326 pastith
                                User u = getService().findUser(permUser);
1579 14ad7326 pastith
                                if (u == null)
1580 14ad7326 pastith
                                        throw new ObjectNotFoundException("User " + permUser + " not found");
1581 f7c44c33 fstamatelopoulos
                                perm.setUser(u);
1582 14ad7326 pastith
                        }
1583 867d129b Fotis Stamatelopoulos
                        // 31/8/2009: Add optional groupUri which takes priority if it exists
1584 867d129b Fotis Stamatelopoulos
                        String permGroupUri = j.optString("groupUri");
1585 14ad7326 pastith
                        String permGroup = j.optString("group");
1586 867d129b Fotis Stamatelopoulos
                        if (!permGroupUri.isEmpty()) {
1587 867d129b Fotis Stamatelopoulos
                                String[] names = permGroupUri.split("/");
1588 867d129b Fotis Stamatelopoulos
                                String grp = URLDecoder.decode(names[names.length - 1], "UTF-8");
1589 867d129b Fotis Stamatelopoulos
                                String usr = URLDecoder.decode(names[names.length - 3], "UTF-8");
1590 867d129b Fotis Stamatelopoulos
                                User u = getService().findUser(usr);
1591 867d129b Fotis Stamatelopoulos
                                if (u == null)
1592 867d129b Fotis Stamatelopoulos
                                        throw new ObjectNotFoundException("User " + permUser + " not found");
1593 f7c44c33 fstamatelopoulos
                                Group g = getService().getGroup(u.getId(), grp);
1594 867d129b Fotis Stamatelopoulos
                                perm.setGroup(g);
1595 867d129b Fotis Stamatelopoulos
                        }
1596 867d129b Fotis Stamatelopoulos
                        else if (!permGroup.isEmpty()) {
1597 f7c44c33 fstamatelopoulos
                                Group g = getService().getGroup(user.getId(), permGroup);
1598 14ad7326 pastith
                                perm.setGroup(g);
1599 14ad7326 pastith
                        }
1600 867d129b Fotis Stamatelopoulos
                        if (permUser.isEmpty() && permGroupUri.isEmpty() && permGroup.isEmpty())
1601 14ad7326 pastith
                                throw new JSONException("A permission must correspond to either a user or a group");
1602 14ad7326 pastith
                        perms.add(perm);
1603 14ad7326 pastith
                }
1604 14ad7326 pastith
                return perms;
1605 14ad7326 pastith
        }
1606 14ad7326 pastith
1607 14ad7326 pastith
        /**
1608 14ad7326 pastith
         * Creates a new folder with the specified name under the folder in the provided path.
1609 14ad7326 pastith
         *
1610 14ad7326 pastith
         * @param req the HTTP request
1611 14ad7326 pastith
         * @param resp the HTTP response
1612 14ad7326 pastith
         * @param path the parent folder path
1613 14ad7326 pastith
         * @param folderName the name of the new folder
1614 14ad7326 pastith
         * @throws IOException if an input/output error occurs
1615 14ad7326 pastith
         */
1616 77dcb3f1 Panagiotis Astithas
        private void createFolder(HttpServletRequest req, HttpServletResponse resp, String path, final String folderName) throws IOException {
1617 14ad7326 pastith
                if (logger.isDebugEnabled())
1618 14ad7326 pastith
                           logger.debug("Creating folder " + folderName + " in '" + path);
1619 14ad7326 pastith
1620 77dcb3f1 Panagiotis Astithas
            final User user = getUser(req);
1621 14ad7326 pastith
            User owner = getOwner(req);
1622 14ad7326 pastith
        boolean exists = true;
1623 14ad7326 pastith
        try {
1624 e150a336 pastith
                getService().getResourceAtPath(owner.getId(), path + folderName, false);
1625 14ad7326 pastith
        } catch (ObjectNotFoundException e) {
1626 14ad7326 pastith
            exists = false;
1627 14ad7326 pastith
        } catch (RpcException e) {
1628 14ad7326 pastith
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path + folderName);
1629 14ad7326 pastith
                        return;
1630 14ad7326 pastith
                }
1631 14ad7326 pastith
1632 14ad7326 pastith
        if (exists) {
1633 14ad7326 pastith
            resp.addHeader("Allow", METHOD_GET + ", " + METHOD_DELETE +
1634 14ad7326 pastith
                                    ", " + METHOD_HEAD);
1635 14ad7326 pastith
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1636 14ad7326 pastith
            return;
1637 14ad7326 pastith
        }
1638 14ad7326 pastith
1639 14ad7326 pastith
                Object parent;
1640 14ad7326 pastith
                try {
1641 68410d59 pastith
                        parent = getService().getResourceAtPath(owner.getId(), path, true);
1642 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1643 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
1644 14ad7326 pastith
                        return;
1645 14ad7326 pastith
                } catch (RpcException e) {
1646 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path + folderName);
1647 14ad7326 pastith
                        return;
1648 14ad7326 pastith
                }
1649 14ad7326 pastith
                try {
1650 f7c44c33 fstamatelopoulos
                        if (parent instanceof Folder) {
1651 f7c44c33 fstamatelopoulos
                                final Folder folderLocal = (Folder) parent;
1652 f7c44c33 fstamatelopoulos
                                Folder newFolder = new TransactionHelper<Folder>().tryExecute(new Callable<Folder>() {
1653 77dcb3f1 Panagiotis Astithas
                                        @Override
1654 f7c44c33 fstamatelopoulos
                                        public Folder call() throws Exception {
1655 f7c44c33 fstamatelopoulos
                                                return getService().createFolder(user.getId(), folderLocal.getId(), folderName);
1656 77dcb3f1 Panagiotis Astithas
                                        }
1657 77dcb3f1 Panagiotis Astithas
1658 77dcb3f1 Panagiotis Astithas
                                });
1659 a0dde818 Panagiotis Astithas
                        String newResource = getApiRoot() + newFolder.getURI();
1660 14ad7326 pastith
                        resp.setHeader("Location", newResource);
1661 14ad7326 pastith
                        resp.setContentType("text/plain");
1662 14ad7326 pastith
                        PrintWriter out = resp.getWriter();
1663 14ad7326 pastith
                        out.println(newResource);
1664 14ad7326 pastith
                        } else {
1665 14ad7326 pastith
                                resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1666 14ad7326 pastith
                            return;
1667 14ad7326 pastith
                        }
1668 14ad7326 pastith
                } catch (DuplicateNameException e) {
1669 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
1670 14ad7326 pastith
                    return;
1671 14ad7326 pastith
                } catch (InsufficientPermissionsException e) {
1672 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1673 14ad7326 pastith
                    return;
1674 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1675 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
1676 14ad7326 pastith
                        return;
1677 14ad7326 pastith
                } catch (RpcException e) {
1678 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path + folderName);
1679 14ad7326 pastith
                        return;
1680 77dcb3f1 Panagiotis Astithas
                } catch (Exception e) {
1681 77dcb3f1 Panagiotis Astithas
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1682 77dcb3f1 Panagiotis Astithas
                        return;
1683 14ad7326 pastith
                }
1684 14ad7326 pastith
            resp.setStatus(HttpServletResponse.SC_CREATED);
1685 14ad7326 pastith
        }
1686 14ad7326 pastith
1687 14ad7326 pastith
        /**
1688 14ad7326 pastith
         * @param req
1689 14ad7326 pastith
         * @param resp
1690 14ad7326 pastith
         * @throws IOException
1691 14ad7326 pastith
         * @throws FileNotFoundException
1692 14ad7326 pastith
         */
1693 14ad7326 pastith
        void putResource(HttpServletRequest req, HttpServletResponse resp) throws IOException, FileNotFoundException {
1694 14ad7326 pastith
        String path = getInnerPath(req, PATH_FILES);
1695 f0c744b4 Panagiotis Astithas
                try {
1696 f0c744b4 Panagiotis Astithas
                    path = URLDecoder.decode(path, "UTF-8");
1697 f0c744b4 Panagiotis Astithas
                } catch (IllegalArgumentException e) {
1698 f0c744b4 Panagiotis Astithas
                        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
1699 f0c744b4 Panagiotis Astithas
                        return;
1700 f0c744b4 Panagiotis Astithas
                }
1701 14ad7326 pastith
            if (logger.isDebugEnabled())
1702 14ad7326 pastith
                           logger.debug("Updating resource: " + path);
1703 14ad7326 pastith
1704 204107fb Panagiotis Astithas
            final User user = getUser(req);
1705 14ad7326 pastith
            User owner = getOwner(req);
1706 14ad7326 pastith
            boolean exists = true;
1707 14ad7326 pastith
        Object resource = null;
1708 f7c44c33 fstamatelopoulos
        FileHeader fileLocal = null;
1709 14ad7326 pastith
        try {
1710 e150a336 pastith
                resource = getService().getResourceAtPath(owner.getId(), path, false);
1711 14ad7326 pastith
        } catch (ObjectNotFoundException e) {
1712 14ad7326 pastith
            exists = false;
1713 14ad7326 pastith
        } catch (RpcException e) {
1714 14ad7326 pastith
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1715 14ad7326 pastith
                        return;
1716 14ad7326 pastith
                }
1717 14ad7326 pastith
1718 14ad7326 pastith
        if (exists)
1719 f7c44c33 fstamatelopoulos
                        if (resource instanceof FileHeader)
1720 f7c44c33 fstamatelopoulos
                            fileLocal = (FileHeader) resource;
1721 14ad7326 pastith
                        else {
1722 e150a336 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT, path + " is a folder");
1723 14ad7326 pastith
                            return;
1724 14ad7326 pastith
                }
1725 14ad7326 pastith
        boolean result = true;
1726 14ad7326 pastith
1727 14ad7326 pastith
        // Temporary content file used to support partial PUT.
1728 14ad7326 pastith
        File contentFile = null;
1729 14ad7326 pastith
1730 14ad7326 pastith
        Range range = parseContentRange(req, resp);
1731 14ad7326 pastith
1732 14ad7326 pastith
        InputStream resourceInputStream = null;
1733 14ad7326 pastith
1734 14ad7326 pastith
        // Append data specified in ranges to existing content for this
1735 14ad7326 pastith
        // resource - create a temporary file on the local filesystem to
1736 14ad7326 pastith
        // perform this operation.
1737 14ad7326 pastith
        // Assume just one range is specified for now
1738 14ad7326 pastith
        if (range != null) {
1739 14ad7326 pastith
            try {
1740 14ad7326 pastith
                                contentFile = executePartialPut(req, range, path);
1741 14ad7326 pastith
                        } catch (RpcException e) {
1742 14ad7326 pastith
                                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1743 14ad7326 pastith
                                return;
1744 14ad7326 pastith
                        } catch (ObjectNotFoundException e) {
1745 14ad7326 pastith
                                resp.sendError(HttpServletResponse.SC_CONFLICT);
1746 14ad7326 pastith
                        return;
1747 14ad7326 pastith
                        } catch (InsufficientPermissionsException e) {
1748 14ad7326 pastith
                                resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1749 14ad7326 pastith
                        return;
1750 14ad7326 pastith
                        }
1751 14ad7326 pastith
            resourceInputStream = new FileInputStream(contentFile);
1752 14ad7326 pastith
        } else
1753 14ad7326 pastith
                        resourceInputStream = req.getInputStream();
1754 14ad7326 pastith
1755 14ad7326 pastith
        try {
1756 f7c44c33 fstamatelopoulos
                Folder folderLocal = null;
1757 68410d59 pastith
                Object parent = getService().getResourceAtPath(owner.getId(), getParentPath(path), true);
1758 f7c44c33 fstamatelopoulos
                if (!(parent instanceof Folder)) {
1759 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
1760 14ad7326 pastith
                        return;
1761 14ad7326 pastith
                }
1762 f7c44c33 fstamatelopoulos
                       folderLocal = (Folder) parent;
1763 204107fb Panagiotis Astithas
                final String name = getLastElement(path);
1764 204107fb Panagiotis Astithas
                final String mimeType = context.getMimeType(name);
1765 b13aae04 pastith
                File uploadedFile = null;
1766 b13aae04 pastith
                try {
1767 b13aae04 pastith
                                uploadedFile = getService().uploadFile(resourceInputStream, user.getId());
1768 b13aae04 pastith
                        } catch (IOException ex) {
1769 b13aae04 pastith
                                throw new GSSIOException(ex, false);
1770 b13aae04 pastith
                        }
1771 f7c44c33 fstamatelopoulos
                FileHeader fileTemp = null;
1772 2f1a60e0 Dimitris Routsis
                final File uploadedf = uploadedFile;
1773 f7c44c33 fstamatelopoulos
                        final Folder parentf = folderLocal;
1774 f7c44c33 fstamatelopoulos
                        final FileHeader f = fileLocal;
1775 14ad7326 pastith
            if (exists)
1776 f7c44c33 fstamatelopoulos
                    fileTemp = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
1777 2f1a60e0 Dimitris Routsis
                                        @Override
1778 f7c44c33 fstamatelopoulos
                                        public FileHeader call() throws Exception {
1779 2f1a60e0 Dimitris Routsis
                                                return getService().updateFileContents(user.getId(), f.getId(), mimeType, uploadedf.getCanonicalFile().length(), uploadedf.getAbsolutePath());
1780 2f1a60e0 Dimitris Routsis
                                        }
1781 2f1a60e0 Dimitris Routsis
                                });
1782 2f1a60e0 Dimitris Routsis
                        else
1783 f7c44c33 fstamatelopoulos
                                fileTemp = new TransactionHelper<FileHeader>().tryExecute(new Callable<FileHeader>() {
1784 204107fb Panagiotis Astithas
                                        @Override
1785 f7c44c33 fstamatelopoulos
                                        public FileHeader call() throws Exception {
1786 4d737770 Fotis Stamatelopoulos
                                                return getService().createFile(user.getId(), parentf.getId(), name, mimeType, uploadedf.getCanonicalFile().length(), uploadedf.getAbsolutePath());
1787 204107fb Panagiotis Astithas
                                        }
1788 204107fb Panagiotis Astithas
1789 204107fb Panagiotis Astithas
                                });
1790 f7c44c33 fstamatelopoulos
            updateAccounting(owner, new Date(), fileTemp.getCurrentBody().getFileSize());
1791 f7c44c33 fstamatelopoulos
                        getService().removeFileUploadProgress(user.getId(), fileTemp.getName());
1792 14ad7326 pastith
        } catch(ObjectNotFoundException e) {
1793 14ad7326 pastith
            result = false;
1794 14ad7326 pastith
        } catch (RpcException e) {
1795 14ad7326 pastith
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1796 14ad7326 pastith
                        return;
1797 14ad7326 pastith
        } catch (IOException e) {
1798 14ad7326 pastith
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1799 14ad7326 pastith
                        return;
1800 14ad7326 pastith
                } catch (GSSIOException e) {
1801 14ad7326 pastith
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1802 14ad7326 pastith
                        return;
1803 14ad7326 pastith
                } catch (DuplicateNameException e) {
1804 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
1805 14ad7326 pastith
                    return;
1806 14ad7326 pastith
                } catch (InsufficientPermissionsException e) {
1807 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1808 14ad7326 pastith
                    return;
1809 14ad7326 pastith
                } catch (QuotaExceededException e) {
1810 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, e.getMessage());
1811 14ad7326 pastith
                    return;
1812 204107fb Panagiotis Astithas
                } catch (Exception e) {
1813 204107fb Panagiotis Astithas
                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, path);
1814 204107fb Panagiotis Astithas
                        return;
1815 14ad7326 pastith
                }
1816 14ad7326 pastith
1817 14ad7326 pastith
        if (result) {
1818 14ad7326 pastith
            if (exists)
1819 14ad7326 pastith
                                resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
1820 14ad7326 pastith
                        else
1821 14ad7326 pastith
                                resp.setStatus(HttpServletResponse.SC_CREATED);
1822 14ad7326 pastith
        } else
1823 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_CONFLICT);
1824 14ad7326 pastith
        }
1825 14ad7326 pastith
1826 14ad7326 pastith
    /**
1827 14ad7326 pastith
     * Delete a resource.
1828 14ad7326 pastith
     *
1829 14ad7326 pastith
     * @param req The servlet request we are processing
1830 14ad7326 pastith
     * @param resp The servlet response we are processing
1831 14ad7326 pastith
         * @throws IOException if the response cannot be sent
1832 14ad7326 pastith
     */
1833 14ad7326 pastith
    void deleteResource(HttpServletRequest req, HttpServletResponse resp) throws IOException {
1834 14ad7326 pastith
        String path = getInnerPath(req, PATH_FILES);
1835 14ad7326 pastith
            if (logger.isDebugEnabled())
1836 14ad7326 pastith
                           logger.debug("Deleting resource '" + path);
1837 5e2b8ec6 koutsoub
            path = URLDecoder.decode(path, "UTF-8");
1838 2f1a60e0 Dimitris Routsis
            final User user = getUser(req);
1839 14ad7326 pastith
            User owner = getOwner(req);
1840 14ad7326 pastith
            boolean exists = true;
1841 14ad7326 pastith
            Object object = null;
1842 14ad7326 pastith
            try {
1843 e150a336 pastith
                    object = getService().getResourceAtPath(owner.getId(), path, false);
1844 14ad7326 pastith
            } catch (ObjectNotFoundException e) {
1845 14ad7326 pastith
                    exists = false;
1846 14ad7326 pastith
            } catch (RpcException e) {
1847 14ad7326 pastith
                    resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1848 14ad7326 pastith
                        return;
1849 14ad7326 pastith
                }
1850 14ad7326 pastith
1851 14ad7326 pastith
            if (!exists) {
1852 14ad7326 pastith
                    resp.sendError(HttpServletResponse.SC_NOT_FOUND);
1853 14ad7326 pastith
                    return;
1854 14ad7326 pastith
            }
1855 14ad7326 pastith
1856 f7c44c33 fstamatelopoulos
            Folder folderLocal = null;
1857 f7c44c33 fstamatelopoulos
            FileHeader fileLocal = null;
1858 f7c44c33 fstamatelopoulos
            if (object instanceof Folder)
1859 f7c44c33 fstamatelopoulos
                    folderLocal = (Folder) object;
1860 14ad7326 pastith
            else
1861 f7c44c33 fstamatelopoulos
                    fileLocal = (FileHeader) object;
1862 14ad7326 pastith
1863 f7c44c33 fstamatelopoulos
            if (fileLocal != null)
1864 14ad7326 pastith
                        try {
1865 f7c44c33 fstamatelopoulos
                                final FileHeader f = fileLocal;
1866 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1867 2f1a60e0 Dimitris Routsis
                                        @Override
1868 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1869 2f1a60e0 Dimitris Routsis
                                                getService().deleteFile(user.getId(), f.getId());
1870 2f1a60e0 Dimitris Routsis
                                                return null;
1871 2f1a60e0 Dimitris Routsis
                                        }
1872 2f1a60e0 Dimitris Routsis
                                });
1873 14ad7326 pastith
                } catch (InsufficientPermissionsException e) {
1874 14ad7326 pastith
                        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1875 14ad7326 pastith
                                return;
1876 14ad7326 pastith
                    } catch (ObjectNotFoundException e) {
1877 14ad7326 pastith
                            // Although we had already found the object, it was
1878 14ad7326 pastith
                            // probably deleted from another thread.
1879 14ad7326 pastith
                            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
1880 14ad7326 pastith
                            return;
1881 14ad7326 pastith
                    } catch (RpcException e) {
1882 14ad7326 pastith
                            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1883 14ad7326 pastith
                            return;
1884 2f1a60e0 Dimitris Routsis
                    } catch (Exception e) {
1885 2f1a60e0 Dimitris Routsis
                            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1886 2f1a60e0 Dimitris Routsis
                            return;
1887 14ad7326 pastith
                    }
1888 f7c44c33 fstamatelopoulos
                else if (folderLocal != null)
1889 14ad7326 pastith
                        try {
1890 f7c44c33 fstamatelopoulos
                                final Folder fo = folderLocal;
1891 2f1a60e0 Dimitris Routsis
                                new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
1892 2f1a60e0 Dimitris Routsis
                                        @Override
1893 2f1a60e0 Dimitris Routsis
                                        public Void call() throws Exception {
1894 2f1a60e0 Dimitris Routsis
                                                getService().deleteFolder(user.getId(), fo.getId());
1895 2f1a60e0 Dimitris Routsis
                                                return null;
1896 2f1a60e0 Dimitris Routsis
                                        }
1897 2f1a60e0 Dimitris Routsis
                                });
1898 14ad7326 pastith
                } catch (InsufficientPermissionsException e) {
1899 14ad7326 pastith
                        resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
1900 14ad7326 pastith
                        return;
1901 14ad7326 pastith
                    } catch (ObjectNotFoundException e) {
1902 14ad7326 pastith
                        resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
1903 14ad7326 pastith
                        return;
1904 14ad7326 pastith
                    } catch (RpcException e) {
1905 14ad7326 pastith
                        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1906 14ad7326 pastith
                        return;
1907 2f1a60e0 Dimitris Routsis
                    } catch (Exception e) {
1908 2f1a60e0 Dimitris Routsis
                        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
1909 2f1a60e0 Dimitris Routsis
                        return;
1910 14ad7326 pastith
                    }
1911 14ad7326 pastith
                resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
1912 14ad7326 pastith
            return;
1913 14ad7326 pastith
    }
1914 14ad7326 pastith
1915 14ad7326 pastith
        /**
1916 14ad7326 pastith
     * Return an InputStream to a JSON representation of the contents
1917 14ad7326 pastith
     * of this directory.
1918 14ad7326 pastith
     *
1919 14ad7326 pastith
         * @param user the user that made the request
1920 14ad7326 pastith
     * @param folder the specified directory
1921 14ad7326 pastith
     * @return an input stream with the rendered contents
1922 14ad7326 pastith
         * @throws IOException if the response cannot be sent
1923 14ad7326 pastith
     * @throws ServletException
1924 14ad7326 pastith
         * @throws InsufficientPermissionsException if the user does not have
1925 14ad7326 pastith
         *                         the necessary privileges to read the directory
1926 14ad7326 pastith
     */
1927 f7c44c33 fstamatelopoulos
    private InputStream renderJson(User user, Folder folder) throws IOException,
1928 14ad7326 pastith
                    ServletException, InsufficientPermissionsException {
1929 a3c09df3 Giannis Koutsoubos
            try {
1930 a3c09df3 Giannis Koutsoubos
                        folder = getService().expandFolder(folder);
1931 a3c09df3 Giannis Koutsoubos
                } catch (ObjectNotFoundException e1) {
1932 a3c09df3 Giannis Koutsoubos
                        // TODO Auto-generated catch block
1933 a3c09df3 Giannis Koutsoubos
                        e1.printStackTrace();
1934 a3c09df3 Giannis Koutsoubos
                } catch (RpcException e1) {
1935 a3c09df3 Giannis Koutsoubos
                        // TODO Auto-generated catch block
1936 a3c09df3 Giannis Koutsoubos
                        e1.printStackTrace();
1937 a3c09df3 Giannis Koutsoubos
                }
1938 14ad7326 pastith
            JSONObject json = new JSONObject();
1939 14ad7326 pastith
            try {
1940 08c62ec7 pastith
                        json.put("name", folder.getName()).
1941 47d800f9 pastith
                                        put("owner", folder.getOwner().getUsername()).
1942 14ad7326 pastith
                                        put("createdBy", folder.getAuditInfo().getCreatedBy().getUsername()).
1943 14ad7326 pastith
                                        put("creationDate", folder.getAuditInfo().getCreationDate().getTime()).
1944 9e6a28ed Natasa Kapravelou
                                        put("deleted", folder.isDeleted()).
1945 16b54aa8 koutsoub
                                        put("shared", folder.getShared()).
1946 9e6a28ed Natasa Kapravelou
                                        put("readForAll", folder.isReadForAll());
1947 9e6a28ed Natasa Kapravelou
1948 77f75ac4 pastith
                        if (folder.getAuditInfo().getModifiedBy() != null)
1949 77f75ac4 pastith
                                json.put("modifiedBy", folder.getAuditInfo().getModifiedBy().getUsername()).
1950 77f75ac4 pastith
                                                put("modificationDate", folder.getAuditInfo().getModificationDate().getTime());
1951 8cc77d04 pastith
                        if (folder.getParent() != null) {
1952 8cc77d04 pastith
                                JSONObject j = new JSONObject();
1953 865f1d02 pastith
                                j.put("uri", getApiRoot() + folder.getParent().getURI());
1954 8cc77d04 pastith
                                j.put("name", folder.getParent().getName());
1955 8cc77d04 pastith
                                json.put("parent", j);
1956 d6ba3052 koutsoub
                        }
1957 f7abcd5a pastith
                    List<JSONObject> subfolders = new ArrayList<JSONObject>();
1958 f7c44c33 fstamatelopoulos
                    for (Folder f: folder.getSubfolders())
1959 f7abcd5a pastith
                                if (!f.isDeleted()) {
1960 f7abcd5a pastith
                                        JSONObject j = new JSONObject();
1961 f7abcd5a pastith
                                        j.put("name", f.getName()).
1962 086c7250 koutsoub
                                                put("uri", getApiRoot() + f.getURI()).
1963 086c7250 koutsoub
                                                put("shared", f.getShared());
1964 f7abcd5a pastith
                                        subfolders.add(j);
1965 f7abcd5a pastith
                                }
1966 f7abcd5a pastith
                    json.put("folders", subfolders);
1967 f7abcd5a pastith
                    List<JSONObject> files = new ArrayList<JSONObject>();
1968 f7c44c33 fstamatelopoulos
                    List<FileHeader> fileHeaders = getService().getFiles(user.getId(), folder.getId(), false);
1969 f7c44c33 fstamatelopoulos
                    for (FileHeader f: fileHeaders) {
1970 f7abcd5a pastith
                            JSONObject j = new JSONObject();
1971 f7abcd5a pastith
                                j.put("name", f.getName()).
1972 3f2e14a0 pastith
                                        put("owner", f.getOwner().getUsername()).
1973 f7abcd5a pastith
                                        put("deleted", f.isDeleted()).
1974 f7c44c33 fstamatelopoulos
                                        put("version", f.getCurrentBody().getVersion()).
1975 f7c44c33 fstamatelopoulos
                                        put("content", f.getCurrentBody().getMimeType()).
1976 f7c44c33 fstamatelopoulos
                                        put("size", f.getCurrentBody().getFileSize()).
1977 16b54aa8 koutsoub
                                        put("shared", f.getShared()).
1978 16b54aa8 koutsoub
                                        put("versioned",f.isVersioned()).
1979 f7abcd5a pastith
                                        put("creationDate", f.getAuditInfo().getCreationDate().getTime()).
1980 d6ba3052 koutsoub
                                        put("path", f.getFolder().getPath()).
1981 2b90ab8a pastith
                                        put("uri", getApiRoot() + f.getURI());
1982 eee18108 pastith
                                if (f.getAuditInfo().getModificationDate() != null)
1983 eee18108 pastith
                                        j.put("modificationDate", f.getAuditInfo().getModificationDate().getTime());
1984 f7abcd5a pastith
                                files.add(j);
1985 f7abcd5a pastith
                    }
1986 14ad7326 pastith
                    json.put("files", files);
1987 f7c44c33 fstamatelopoulos
                    Set<Permission> perms = getService().getFolderPermissions(user.getId(), folder.getId());
1988 14ad7326 pastith
                    json.put("permissions", renderJson(perms));
1989 14ad7326 pastith
                } catch (JSONException e) {
1990 14ad7326 pastith
                        throw new ServletException(e);
1991 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
1992 14ad7326 pastith
                        throw new ServletException(e);
1993 14ad7326 pastith
                } catch (RpcException e) {
1994 14ad7326 pastith
                        throw new ServletException(e);
1995 14ad7326 pastith
                }
1996 14ad7326 pastith
1997 14ad7326 pastith
            // Prepare a writer to a buffered area
1998 14ad7326 pastith
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
1999 14ad7326 pastith
            OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8");
2000 14ad7326 pastith
            PrintWriter writer = new PrintWriter(osWriter);
2001 14ad7326 pastith
2002 14ad7326 pastith
            // Return an input stream to the underlying bytes
2003 14ad7326 pastith
            writer.write(json.toString());
2004 14ad7326 pastith
            writer.flush();
2005 14ad7326 pastith
            return new ByteArrayInputStream(stream.toByteArray());
2006 14ad7326 pastith
    }
2007 14ad7326 pastith
2008 14ad7326 pastith
        /**
2009 14ad7326 pastith
     * Return a String with a JSON representation of the metadata
2010 77f75ac4 pastith
     * of the specified folder.
2011 77f75ac4 pastith
         * @throws RpcException
2012 77f75ac4 pastith
         * @throws InsufficientPermissionsException
2013 77f75ac4 pastith
         * @throws ObjectNotFoundException
2014 77f75ac4 pastith
     */
2015 f7c44c33 fstamatelopoulos
    private String renderJsonMetadata(User user, Folder folder)
2016 77f75ac4 pastith
                    throws ServletException, InsufficientPermissionsException {
2017 77f75ac4 pastith
            // Check if the user has read permission.
2018 77f75ac4 pastith
                try {
2019 77f75ac4 pastith
                        if (!getService().canReadFolder(user.getId(), folder.getId()))
2020 77f75ac4 pastith
                                throw new InsufficientPermissionsException();
2021 77f75ac4 pastith
                } catch (ObjectNotFoundException e) {
2022 77f75ac4 pastith
                        throw new ServletException(e);
2023 77f75ac4 pastith
                } catch (RpcException e) {
2024 77f75ac4 pastith
                        throw new ServletException(e);
2025 77f75ac4 pastith
                }
2026 77f75ac4 pastith
2027 77f75ac4 pastith
            JSONObject json = new JSONObject();
2028 77f75ac4 pastith
            try {
2029 c031299f Christos V. Stathis
                        json.put("name", URLEncoder.encode(folder.getName(), "UTF-8")).
2030 77f75ac4 pastith
                        put("owner", folder.getOwner().getUsername()).
2031 77f75ac4 pastith
                        put("createdBy", folder.getAuditInfo().getCreatedBy().getUsername()).
2032 77f75ac4 pastith
                        put("creationDate", folder.getAuditInfo().getCreationDate().getTime()).
2033 77f75ac4 pastith
                        put("deleted", folder.isDeleted());
2034 77f75ac4 pastith
                        if (folder.getAuditInfo().getModifiedBy() != null)
2035 77f75ac4 pastith
                                json.put("modifiedBy", folder.getAuditInfo().getModifiedBy().getUsername()).
2036 77f75ac4 pastith
                                                put("modificationDate", folder.getAuditInfo().getModificationDate().getTime());
2037 77f75ac4 pastith
                } catch (JSONException e) {
2038 77f75ac4 pastith
                        throw new ServletException(e);
2039 77f75ac4 pastith
                }
2040 c031299f Christos V. Stathis
        catch (UnsupportedEncodingException e) {
2041 c031299f Christos V. Stathis
            throw new ServletException(e);
2042 c031299f Christos V. Stathis
        }
2043 c031299f Christos V. Stathis
        return json.toString();
2044 77f75ac4 pastith
    }
2045 77f75ac4 pastith
2046 77f75ac4 pastith
        /**
2047 77f75ac4 pastith
     * Return a String with a JSON representation of the metadata
2048 14ad7326 pastith
     * of the specified file. If an old file body is provided, then
2049 14ad7326 pastith
     * the metadata of that particular version will be returned.
2050 14ad7326 pastith
     *
2051 14ad7326 pastith
         * @param user the user that made the request
2052 14ad7326 pastith
     * @param file the specified file header
2053 14ad7326 pastith
     * @param oldBody the version number
2054 14ad7326 pastith
     * @return the JSON-encoded file
2055 14ad7326 pastith
     * @throws ServletException
2056 14ad7326 pastith
         * @throws InsufficientPermissionsException if the user does not have
2057 14ad7326 pastith
         *                         the necessary privileges to read the directory
2058 14ad7326 pastith
     */
2059 f7c44c33 fstamatelopoulos
    private String renderJson(User user, FileHeader file, FileBody oldBody)
2060 3a90e4f3 pastith
                    throws ServletException, InsufficientPermissionsException {
2061 14ad7326 pastith
            JSONObject json = new JSONObject();
2062 14ad7326 pastith
            try {
2063 a3c09df3 Giannis Koutsoubos
                    file=getService().expandFile(file);
2064 8cc77d04 pastith
                    // Need to encode file name in order to properly display it in the web client.
2065 5e2b8ec6 koutsoub
                        json.put("name", URLEncoder.encode(file.getName(),"UTF-8")).
2066 47d800f9 pastith
                                        put("owner", file.getOwner().getUsername()).
2067 47d800f9 pastith
                                        put("versioned", file.isVersioned()).
2068 f7c44c33 fstamatelopoulos
                                        put("version", oldBody != null ? oldBody.getVersion() : file.getCurrentBody().getVersion()).
2069 47d800f9 pastith
                                        put("readForAll", file.isReadForAll()).
2070 16b54aa8 koutsoub
                                        put("shared", file.getShared()).
2071 f7c44c33 fstamatelopoulos
                                        put("tags", renderJson(file.getFileTagsAsStrings())).
2072 2b90ab8a pastith
                                        put("path", file.getFolder().getPath()).
2073 865f1d02 pastith
                                    put("uri", getApiRoot() + file.getURI()).
2074 14ad7326 pastith
                                        put("deleted", file.isDeleted());
2075 8cc77d04 pastith
                        JSONObject j = new JSONObject();
2076 865f1d02 pastith
                        j.put("uri", getApiRoot() + file.getFolder().getURI()).
2077 8cc77d04 pastith
                                        put("name", URLEncoder.encode(file.getFolder().getName(),"UTF-8"));
2078 8cc77d04 pastith
                        json.put("folder", j);
2079 14ad7326 pastith
                        if (oldBody != null)
2080 14ad7326 pastith
                                json.put("createdBy", oldBody.getAuditInfo().getCreatedBy().getUsername()).
2081 14ad7326 pastith
                                                put("creationDate", oldBody.getAuditInfo().getCreationDate().getTime()).
2082 14ad7326 pastith
                                                put("modifiedBy", oldBody.getAuditInfo().getModifiedBy().getUsername()).
2083 2d40bbc6 pastith
                                                put("modificationDate", oldBody.getAuditInfo().getModificationDate().getTime()).
2084 0e4865ee pastith
                                                put("content", oldBody.getMimeType()).
2085 2d40bbc6 pastith
                                                put("size", oldBody.getFileSize());
2086 14ad7326 pastith
                        else
2087 14ad7326 pastith
                                json.put("createdBy", file.getAuditInfo().getCreatedBy().getUsername()).
2088 14ad7326 pastith
                                                put("creationDate", file.getAuditInfo().getCreationDate().getTime()).
2089 14ad7326 pastith
                                                put("modifiedBy", file.getAuditInfo().getModifiedBy().getUsername()).
2090 2d40bbc6 pastith
                                                put("modificationDate", file.getAuditInfo().getModificationDate().getTime()).
2091 f7c44c33 fstamatelopoulos
                                                put("content", file.getCurrentBody().getMimeType()).
2092 f7c44c33 fstamatelopoulos
                                                put("size", file.getCurrentBody().getFileSize());
2093 f7c44c33 fstamatelopoulos
                    Set<Permission> perms = getService().getFilePermissions(user.getId(), file.getId());
2094 14ad7326 pastith
                    json.put("permissions", renderJson(perms));
2095 14ad7326 pastith
                } catch (JSONException e) {
2096 14ad7326 pastith
                        throw new ServletException(e);
2097 14ad7326 pastith
                } catch (ObjectNotFoundException e) {
2098 14ad7326 pastith
                        throw new ServletException(e);
2099 14ad7326 pastith
                } catch (RpcException e) {
2100 14ad7326 pastith
                        throw new ServletException(e);
2101 3a90e4f3 pastith
                } catch (UnsupportedEncodingException e) {
2102 3a90e4f3 pastith
                        throw new ServletException(e);
2103 14ad7326 pastith
                }
2104 14ad7326 pastith
2105 14ad7326 pastith
            return json.toString();
2106 14ad7326 pastith
    }
2107 14ad7326 pastith
2108 14ad7326 pastith
        /**
2109 14ad7326 pastith
         * Return a String with a JSON representation of the
2110 14ad7326 pastith
         * specified set of permissions.
2111 14ad7326 pastith
     *
2112 14ad7326 pastith
         * @param permissions the set of permissions
2113 14ad7326 pastith
         * @return the JSON-encoded object
2114 14ad7326 pastith
         * @throws JSONException
2115 fc5ef2cc droutsis
         * @throws UnsupportedEncodingException
2116 14ad7326 pastith
         */
2117 f7c44c33 fstamatelopoulos
        private JSONArray renderJson(Set<Permission> permissions) throws JSONException, UnsupportedEncodingException {
2118 14ad7326 pastith
                JSONArray perms = new JSONArray();
2119 f7c44c33 fstamatelopoulos
                for (Permission p: permissions) {
2120 14ad7326 pastith
                        JSONObject permission = new JSONObject();
2121 14ad7326 pastith
                        permission.put("read", p.hasRead()).put("write", p.hasWrite()).put("modifyACL", p.hasModifyACL());
2122 14ad7326 pastith
                        if (p.getUser() != null)
2123 14ad7326 pastith
                                permission.put("user", p.getUser().getUsername());
2124 867d129b Fotis Stamatelopoulos
                        if (p.getGroup() != null) {
2125 f7c44c33 fstamatelopoulos
                                Group group = p.getGroup();
2126 867d129b Fotis Stamatelopoulos
                                permission.put("groupUri", getApiRoot() + group.getOwner().getUsername() + PATH_GROUPS + "/" + URLEncoder.encode(group.getName(),"UTF-8"));
2127 fc5ef2cc droutsis
                                permission.put("group", URLEncoder.encode(p.getGroup().getName(),"UTF-8"));
2128 867d129b Fotis Stamatelopoulos
                        }
2129 14ad7326 pastith
                        perms.put(permission);
2130 14ad7326 pastith
                }
2131 14ad7326 pastith
                return perms;
2132 14ad7326 pastith
        }
2133 14ad7326 pastith
2134 14ad7326 pastith
        /**
2135 fc5ef2cc droutsis
         * Return a String with a JSON representation of the
2136 fc5ef2cc droutsis
         * specified collection of tags.
2137 fc5ef2cc droutsis
     *
2138 fc5ef2cc droutsis
         * @param tags the collection of tags
2139 fc5ef2cc droutsis
         * @return the JSON-encoded object
2140 fc5ef2cc droutsis
         * @throws JSONException
2141 fc5ef2cc droutsis
         * @throws UnsupportedEncodingException
2142 fc5ef2cc droutsis
         */
2143 fc5ef2cc droutsis
        private JSONArray renderJson(Collection<String> tags) throws JSONException, UnsupportedEncodingException {
2144 fc5ef2cc droutsis
                JSONArray tagArray = new JSONArray();
2145 fc5ef2cc droutsis
                for (String t: tags)
2146 fc5ef2cc droutsis
                        tagArray.put(URLEncoder.encode(t,"UTF-8"));
2147 fc5ef2cc droutsis
                return tagArray;
2148 fc5ef2cc droutsis
        }
2149 fc5ef2cc droutsis
2150 fc5ef2cc droutsis
        /**
2151 14ad7326 pastith
         * Retrieves the user who owns the destination namespace, for a
2152 14ad7326 pastith
         * copy or move request.
2153 14ad7326 pastith
         *
2154 14ad7326 pastith
         * @param req the HTTP request
2155 14ad7326 pastith
         * @return the owner of the namespace
2156 14ad7326 pastith
         */
2157 14ad7326 pastith
        protected User getDestinationOwner(HttpServletRequest req) {
2158 14ad7326 pastith
                return (User) req.getAttribute(DESTINATION_OWNER_ATTRIBUTE);
2159 14ad7326 pastith
        }
2160 e150a336 pastith
2161 e150a336 pastith
        /**
2162 e150a336 pastith
         * A helper inner class for updating the progress status of a file upload.
2163 e150a336 pastith
         *
2164 e150a336 pastith
         * @author kman
2165 e150a336 pastith
         */
2166 e150a336 pastith
        public static class StatusProgressListener implements ProgressListener {
2167 e150a336 pastith
                private int percentLogged = 0;
2168 e150a336 pastith
                private long bytesTransferred = 0;
2169 e150a336 pastith
2170 e150a336 pastith
                private long fileSize = -100;
2171 e150a336 pastith
2172 e150a336 pastith
                private Long userId;
2173 e150a336 pastith
2174 e150a336 pastith
                private String filename;
2175 e150a336 pastith
2176 e150a336 pastith
                private ExternalAPI service;
2177 e150a336 pastith
2178 e150a336 pastith
                public StatusProgressListener(ExternalAPI aService) {
2179 e150a336 pastith
                        service = aService;
2180 e150a336 pastith
                }
2181 e150a336 pastith
2182 e150a336 pastith
                /**
2183 e150a336 pastith
                 * Modify the userId.
2184 e150a336 pastith
                 *
2185 e150a336 pastith
                 * @param aUserId the userId to set
2186 e150a336 pastith
                 */
2187 e150a336 pastith
                public void setUserId(Long aUserId) {
2188 e150a336 pastith
                        userId = aUserId;
2189 e150a336 pastith
                }
2190 e150a336 pastith
2191 e150a336 pastith
                /**
2192 e150a336 pastith
                 * Modify the filename.
2193 e150a336 pastith
                 *
2194 e150a336 pastith
                 * @param aFilename the filename to set
2195 e150a336 pastith
                 */
2196 e150a336 pastith
                public void setFilename(String aFilename) {
2197 e150a336 pastith
                        filename = aFilename;
2198 e150a336 pastith
                }
2199 e150a336 pastith
2200 023f6f1e Panagiotis Astithas
                @Override
2201 e150a336 pastith
                public void update(long bytesRead, long contentLength, int items) {
2202 e150a336 pastith
                        //monitoring per percent of bytes uploaded
2203 e150a336 pastith
                        bytesTransferred = bytesRead;
2204 e150a336 pastith
                        if (fileSize != contentLength)
2205 e150a336 pastith
                                fileSize = contentLength;
2206 e150a336 pastith
                        int percent = new Long(bytesTransferred * 100 / fileSize).intValue();
2207 e150a336 pastith
                        if (percent < 5 || percent % TRACK_PROGRESS_PERCENT == 0 )
2208 bb9093fe Christos V. Stathis
                                if (percent != percentLogged){
2209 bb9093fe Christos V. Stathis
                                        percentLogged = percent;
2210 e150a336 pastith
                                        try {
2211 e150a336 pastith
                                                if (userId != null && filename != null)
2212 e150a336 pastith
                                                        service.createFileUploadProgress(userId, filename, bytesTransferred, fileSize);
2213 e150a336 pastith
                                        } catch (ObjectNotFoundException e) {
2214 e150a336 pastith
                                                // Swallow the exception since it is going to be caught
2215 e150a336 pastith
                                                // by previously called methods
2216 e150a336 pastith
                                        }
2217 bb9093fe Christos V. Stathis
                                }
2218 e150a336 pastith
                }
2219 e150a336 pastith
        }
2220 51ad539e Natasa Kapravelou
2221 31e19588 Natasa Kapravelou
        /**
2222 31e19588 Natasa Kapravelou
         * Return an InputStream to an HTML representation of the contents of this
2223 31e19588 Natasa Kapravelou
         * directory.
2224 31e19588 Natasa Kapravelou
         *
2225 31e19588 Natasa Kapravelou
         * @param contextPath Context path to which our internal paths are relative
2226 51ad539e Natasa Kapravelou
         * @param path the requested path to the resource
2227 31e19588 Natasa Kapravelou
         * @param folder the specified directory
2228 51ad539e Natasa Kapravelou
         * @param user the specified user
2229 31e19588 Natasa Kapravelou
         * @return an input stream with the rendered contents
2230 31e19588 Natasa Kapravelou
         * @throws IOException
2231 31e19588 Natasa Kapravelou
         * @throws ServletException
2232 31e19588 Natasa Kapravelou
         */
2233 f7c44c33 fstamatelopoulos
        private InputStream renderHtml(String contextPath, String path, Folder folder, User user)
2234 51ad539e Natasa Kapravelou
                throws IOException, ServletException {
2235 31e19588 Natasa Kapravelou
                String name = folder.getName();
2236 31e19588 Natasa Kapravelou
                // Prepare a writer to a buffered area
2237 31e19588 Natasa Kapravelou
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
2238 31e19588 Natasa Kapravelou
                OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8");
2239 31e19588 Natasa Kapravelou
                PrintWriter writer = new PrintWriter(osWriter);
2240 31e19588 Natasa Kapravelou
                StringBuffer sb = new StringBuffer();
2241 31e19588 Natasa Kapravelou
                // rewriteUrl(contextPath) is expensive. cache result for later reuse
2242 31e19588 Natasa Kapravelou
                String rewrittenContextPath = rewriteUrl(contextPath);
2243 31e19588 Natasa Kapravelou
                // Render the page header
2244 31e19588 Natasa Kapravelou
                sb.append("<html>\r\n");
2245 31e19588 Natasa Kapravelou
                sb.append("<head>\r\n");
2246 31e19588 Natasa Kapravelou
                sb.append("<title>");
2247 31e19588 Natasa Kapravelou
                sb.append("Index of " + name);
2248 31e19588 Natasa Kapravelou
                sb.append("</title>\r\n");
2249 31e19588 Natasa Kapravelou
                sb.append("<STYLE><!--");
2250 31e19588 Natasa Kapravelou
                sb.append(GSS_CSS);
2251 31e19588 Natasa Kapravelou
                sb.append("--></STYLE> ");
2252 31e19588 Natasa Kapravelou
                sb.append("</head>\r\n");
2253 31e19588 Natasa Kapravelou
                sb.append("<body>");
2254 31e19588 Natasa Kapravelou
                sb.append("<h1>");
2255 31e19588 Natasa Kapravelou
                sb.append("Index of " + name);
2256 31e19588 Natasa Kapravelou
2257 31e19588 Natasa Kapravelou
                // Render the link to our parent (if required)
2258 51ad539e Natasa Kapravelou
                String parentDirectory = path;
2259 31e19588 Natasa Kapravelou
                if (parentDirectory.endsWith("/"))
2260 31e19588 Natasa Kapravelou
                        parentDirectory = parentDirectory.substring(0, parentDirectory.length() - 1);
2261 31e19588 Natasa Kapravelou
                int slash = parentDirectory.lastIndexOf('/');
2262 31e19588 Natasa Kapravelou
                if (slash >= 0) {
2263 51ad539e Natasa Kapravelou
                        String parent = path.substring(0, slash);
2264 8e471ce5 Natasa Kapravelou
                        sb.append(" - <a href=\"");
2265 8e471ce5 Natasa Kapravelou
                        sb.append(rewrittenContextPath);
2266 51ad539e Natasa Kapravelou
                        if (parent.equals(""))
2267 51ad539e Natasa Kapravelou
                                parent = "/";
2268 51ad539e Natasa Kapravelou
                        sb.append(parent);
2269 51ad539e Natasa Kapravelou
                        if (!parent.endsWith("/"))
2270 51ad539e Natasa Kapravelou
                                sb.append("/");
2271 8e471ce5 Natasa Kapravelou
                        sb.append("\">");
2272 8e471ce5 Natasa Kapravelou
                        sb.append("<b>");
2273 51ad539e Natasa Kapravelou
                        sb.append("Up To " + parent);
2274 8e471ce5 Natasa Kapravelou
                        sb.append("</b>");
2275 8e471ce5 Natasa Kapravelou
                        sb.append("</a>");
2276 31e19588 Natasa Kapravelou
                }
2277 31e19588 Natasa Kapravelou
2278 31e19588 Natasa Kapravelou
                sb.append("</h1>");
2279 31e19588 Natasa Kapravelou
                sb.append("<HR size=\"1\" noshade=\"noshade\">");
2280 31e19588 Natasa Kapravelou
2281 31e19588 Natasa Kapravelou
                sb.append("<table width=\"100%\" cellspacing=\"0\"" + " cellpadding=\"5\" align=\"center\">\r\n");
2282 31e19588 Natasa Kapravelou
2283 31e19588 Natasa Kapravelou
                // Render the column headings
2284 31e19588 Natasa Kapravelou
                sb.append("<tr>\r\n");
2285 31e19588 Natasa Kapravelou
                sb.append("<td align=\"left\"><font size=\"+1\"><strong>");
2286 31e19588 Natasa Kapravelou
                sb.append("Name");
2287 31e19588 Natasa Kapravelou
                sb.append("</strong></font></td>\r\n");
2288 31e19588 Natasa Kapravelou
                sb.append("<td align=\"center\"><font size=\"+1\"><strong>");
2289 31e19588 Natasa Kapravelou
                sb.append("Size");
2290 31e19588 Natasa Kapravelou
                sb.append("</strong></font></td>\r\n");
2291 31e19588 Natasa Kapravelou
                sb.append("<td align=\"right\"><font size=\"+1\"><strong>");
2292 31e19588 Natasa Kapravelou
                sb.append("Last modified");
2293 31e19588 Natasa Kapravelou
                sb.append("</strong></font></td>\r\n");
2294 31e19588 Natasa Kapravelou
                sb.append("</tr>");
2295 31e19588 Natasa Kapravelou
                // Render the directory entries within this directory
2296 31e19588 Natasa Kapravelou
                boolean shade = false;
2297 31e19588 Natasa Kapravelou
                Iterator iter = folder.getSubfolders().iterator();
2298 31e19588 Natasa Kapravelou
                while (iter.hasNext()) {
2299 f7c44c33 fstamatelopoulos
                        Folder subf = (Folder) iter.next();
2300 51ad539e Natasa Kapravelou
                        if(subf.isReadForAll() && !subf.isDeleted()){
2301 8e471ce5 Natasa Kapravelou
                                String resourceName = subf.getName();
2302 8e471ce5 Natasa Kapravelou
                                if (resourceName.equalsIgnoreCase("WEB-INF") || resourceName.equalsIgnoreCase("META-INF"))
2303 8e471ce5 Natasa Kapravelou
                                        continue;
2304 31e19588 Natasa Kapravelou
2305 8e471ce5 Natasa Kapravelou
                                sb.append("<tr");
2306 8e471ce5 Natasa Kapravelou
                                if (shade)
2307 8e471ce5 Natasa Kapravelou
                                        sb.append(" bgcolor=\"#eeeeee\"");
2308 8e471ce5 Natasa Kapravelou
                                sb.append(">\r\n");
2309 8e471ce5 Natasa Kapravelou
                                shade = !shade;
2310 51ad539e Natasa Kapravelou
2311 8e471ce5 Natasa Kapravelou
                                sb.append("<td align=\"left\">&nbsp;&nbsp;\r\n");
2312 8e471ce5 Natasa Kapravelou
                                sb.append("<a href=\"");
2313 51ad539e Natasa Kapravelou
                                sb.append(rewrittenContextPath+path);
2314 51ad539e Natasa Kapravelou
                                sb.append(rewriteUrl(resourceName));
2315 8e471ce5 Natasa Kapravelou
                                sb.append("/");
2316 8e471ce5 Natasa Kapravelou
                                sb.append("\"><tt>");
2317 8e471ce5 Natasa Kapravelou
                                sb.append(RequestUtil.filter(resourceName));
2318 8e471ce5 Natasa Kapravelou
                                sb.append("/");
2319 8e471ce5 Natasa Kapravelou
                                sb.append("</tt></a></td>\r\n");
2320 31e19588 Natasa Kapravelou
2321 8e471ce5 Natasa Kapravelou
                                sb.append("<td align=\"right\"><tt>");
2322 8e471ce5 Natasa Kapravelou
                                sb.append("&nbsp;");
2323 8e471ce5 Natasa Kapravelou
                                sb.append("</tt></td>\r\n");
2324 51ad539e Natasa Kapravelou
2325 8e471ce5 Natasa Kapravelou
                                sb.append("<td align=\"right\"><tt>");
2326 8e471ce5 Natasa Kapravelou
                                sb.append(getLastModifiedHttp(folder.getAuditInfo()));
2327 8e471ce5 Natasa Kapravelou
                                sb.append("</tt></td>\r\n");
2328 31e19588 Natasa Kapravelou
2329 8e471ce5 Natasa Kapravelou
                                sb.append("</tr>\r\n");
2330 51ad539e Natasa Kapravelou
2331 51ad539e Natasa Kapravelou
                        }
2332 31e19588 Natasa Kapravelou
                }
2333 f7c44c33 fstamatelopoulos
                List<FileHeader> files;
2334 31e19588 Natasa Kapravelou
                try {
2335 31e19588 Natasa Kapravelou
                        files = getService().getFiles(user.getId(), folder.getId(), true);
2336 31e19588 Natasa Kapravelou
                } catch (ObjectNotFoundException e) {
2337 31e19588 Natasa Kapravelou
                        throw new ServletException(e.getMessage());
2338 31e19588 Natasa Kapravelou
                } catch (InsufficientPermissionsException e) {
2339 31e19588 Natasa Kapravelou
                        throw new ServletException(e.getMessage());
2340 31e19588 Natasa Kapravelou
                } catch (RpcException e) {
2341 31e19588 Natasa Kapravelou
                        throw new ServletException(e.getMessage());
2342 31e19588 Natasa Kapravelou
                }
2343 f7c44c33 fstamatelopoulos
                for (FileHeader file : files)
2344 51ad539e Natasa Kapravelou
                //Display only file resources that are marked as public and are not deleted
2345 51ad539e Natasa Kapravelou
                        if(file.isReadForAll() && !file.isDeleted()){
2346 f9bd859c Natasa Kapravelou
                                String resourceName = file.getName();
2347 f9bd859c Natasa Kapravelou
                                if (resourceName.equalsIgnoreCase("WEB-INF") || resourceName.equalsIgnoreCase("META-INF"))
2348 f9bd859c Natasa Kapravelou
                                        continue;
2349 51ad539e Natasa Kapravelou
2350 f9bd859c Natasa Kapravelou
                                sb.append("<tr");
2351 f9bd859c Natasa Kapravelou
                                if (shade)
2352 f9bd859c Natasa Kapravelou
                                        sb.append(" bgcolor=\"#eeeeee\"");
2353 f9bd859c Natasa Kapravelou
                                sb.append(">\r\n");
2354 f9bd859c Natasa Kapravelou
                                shade = !shade;
2355 f9bd859c Natasa Kapravelou
2356 f9bd859c Natasa Kapravelou
                                sb.append("<td align=\"left\">&nbsp;&nbsp;\r\n");
2357 f9bd859c Natasa Kapravelou
                                sb.append("<a href=\"");
2358 51ad539e Natasa Kapravelou
                                sb.append(rewrittenContextPath + path);
2359 51ad539e Natasa Kapravelou
                                sb.append(rewriteUrl(resourceName));
2360 f9bd859c Natasa Kapravelou
                                sb.append("\"><tt>");
2361 f9bd859c Natasa Kapravelou
                                sb.append(RequestUtil.filter(resourceName));
2362 f9bd859c Natasa Kapravelou
                                sb.append("</tt></a></td>\r\n");
2363 f9bd859c Natasa Kapravelou
2364 f9bd859c Natasa Kapravelou
                                sb.append("<td align=\"right\"><tt>");
2365 f7c44c33 fstamatelopoulos
                                sb.append(renderSize(file.getCurrentBody().getFileSize()));
2366 f9bd859c Natasa Kapravelou
                                sb.append("</tt></td>\r\n");
2367 f9bd859c Natasa Kapravelou
2368 f9bd859c Natasa Kapravelou
                                sb.append("<td align=\"right\"><tt>");
2369 f9bd859c Natasa Kapravelou
                                sb.append(getLastModifiedHttp(file.getAuditInfo()));
2370 f9bd859c Natasa Kapravelou
                                sb.append("</tt></td>\r\n");
2371 f9bd859c Natasa Kapravelou
2372 f9bd859c Natasa Kapravelou
                                sb.append("</tr>\r\n");
2373 f9bd859c Natasa Kapravelou
                        }
2374 31e19588 Natasa Kapravelou
2375 31e19588 Natasa Kapravelou
                // Render the page footer
2376 31e19588 Natasa Kapravelou
                sb.append("</table>\r\n");
2377 31e19588 Natasa Kapravelou
2378 31e19588 Natasa Kapravelou
                sb.append("<HR size=\"1\" noshade=\"noshade\">");
2379 31e19588 Natasa Kapravelou
                sb.append("</body>\r\n");
2380 31e19588 Natasa Kapravelou
                sb.append("</html>\r\n");
2381 31e19588 Natasa Kapravelou
2382 31e19588 Natasa Kapravelou
                // Return an input stream to the underlying bytes
2383 31e19588 Natasa Kapravelou
                writer.write(sb.toString());
2384 31e19588 Natasa Kapravelou
                writer.flush();
2385 31e19588 Natasa Kapravelou
                return new ByteArrayInputStream(stream.toByteArray());
2386 31e19588 Natasa Kapravelou
2387 31e19588 Natasa Kapravelou
        }
2388 14ad7326 pastith
}