Revision 8f128261

b/gss/src/gr/ebs/gss/server/domain/AccountingInfo.java
1
/*
2
 * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
3
 *
4
 * This file is part of GSS.
5
 *
6
 * GSS is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * GSS is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
package gr.ebs.gss.server.domain;
20

  
21
import java.io.Serializable;
22
import java.util.Date;
23

  
24
import javax.persistence.Column;
25
import javax.persistence.Entity;
26
import javax.persistence.GeneratedValue;
27
import javax.persistence.Id;
28
import javax.persistence.JoinColumn;
29
import javax.persistence.ManyToOne;
30
import javax.persistence.Temporal;
31
import javax.persistence.TemporalType;
32

  
33
/**
34
 * This class holds information about bandwidth usage by users.
35
 * This information is broken down in time periods.
36
 */
37
@Entity
38
public class AccountingInfo  implements Serializable{
39

  
40
	/**
41
	 * The persistence ID of the object.
42
	 */
43
	@SuppressWarnings("unused")
44
	@Id
45
	@GeneratedValue
46
	private Long id;
47

  
48
	/**
49
	 * The user whose usage we are noting. We can never change it after
50
	 * creation.
51
	 */
52
	@ManyToOne
53
	@JoinColumn(updatable = false, nullable = false)
54
	private User user;
55

  
56
	/**
57
	 * The start of the time period. We can never change it after
58
	 * creation.
59
	 */
60
	@Temporal(TemporalType.TIMESTAMP)
61
	@Column(updatable = false, nullable = false)
62
	private Date dateFrom;
63

  
64

  
65
	/**
66
	 * The end of the time period. We can never change it after
67
	 * creation.
68
	 */
69
	@Temporal(TemporalType.TIMESTAMP)
70
	@Column(updatable = false, nullable = false)
71
	private Date dateTo;
72

  
73

  
74
	/**
75
	 * The usage itself, in bytes.
76
	 */
77
	@Column(nullable = false)
78
	private long bandwidthUsed = 0;
79

  
80

  
81
	/**
82
	 * Default constructor. Required by Hibernate,
83
	 * but shouldn't be called.
84
	 */
85
	@SuppressWarnings("unused")
86
	private AccountingInfo() {
87
	}
88

  
89

  
90
	/**
91
	 * Constructor
92
	 */
93
	public AccountingInfo(User _user, Date _dateFrom, Date _dateTo) {
94
		user = _user;
95
		dateFrom = _dateFrom;
96
		dateTo = _dateTo;
97
	}
98

  
99

  
100
	/**
101
	 * Retrieve the user
102
	 * @return the user
103
	 */
104
	public User getUser() {
105
		return user;
106
	}
107

  
108

  
109
	/**
110
	 * Retrieve the start of the time period.
111
	 * @return the start of the time period
112
	 */
113
	public Date getDateFrom() {
114
		return dateFrom;
115
	}
116

  
117

  
118
	/**
119
	 * Retrieve the end of the time period.
120
	 * @return the end of the time period
121
	 */
122
	public Date getDateTo() {
123
		return dateTo;
124
	}
125

  
126

  
127
	/**
128
	 * Retrieve the bandwidth used.
129
	 * @return the bandwidth used
130
	 */
131
	public long getBandwidthUsed() {
132
		return bandwidthUsed;
133
	}
134

  
135

  
136
	/**
137
	 * Update bandwidth used upwards or downwards with new amount.
138
	 * @param bandwidthDiff The amount by which to update;
139
	 * positive for increase, negative for decrease.
140
	 */
141
	public void updateBandwidth(long bandwidthDiff) {
142
		bandwidthUsed += bandwidthDiff;
143
	}
144

  
145
}
b/gss/src/gr/ebs/gss/server/ejb/ExternalAPI.java
304 304
	 * @param name the name of the new file
305 305
	 * @param mimeType the MIME type of the file
306 306
	 * @param stream the input stream with the file contents
307
	 * @return The FileHeaderDTO created
307 308
	 * @throws DuplicateNameException if the specified name already exists in
308 309
	 *             the parent folder, as either a folder or file
309 310
	 * @throws ObjectNotFoundException if the user or parent folder was not
......
313 314
	 * @throws InsufficientPermissionsException
314 315
	 * @throws QuotaExceededException
315 316
	 */
316
	public void createFile(Long userId, Long folderId, String name, String mimeType,
317
	public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType,
317 318
				InputStream stream) throws DuplicateNameException, ObjectNotFoundException,
318 319
				GSSIOException, InsufficientPermissionsException, QuotaExceededException;
319 320

  
......
464 465
	 * @param fileId the ID of the file header object
465 466
	 * @param mimeType the content type of the file
466 467
	 * @param resourceInputStream a stream of the file contents
468
	 * @return The FileHeaderDTO created
467 469
	 * @throws ObjectNotFoundException if the user or file was not found, with
468 470
	 * 			the exception message mentioning the precise problem
469 471
	 * @throws GSSIOException if there was an error while storing the file contents
470 472
	 * @throws InsufficientPermissionsException
471 473
	 * @throws QuotaExceededException
472 474
	 */
473
	public void updateFileContents(Long userId, Long fileId, String mimeType,
475
	public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType,
474 476
				InputStream resourceInputStream) throws ObjectNotFoundException,
475 477
				GSSIOException, InsufficientPermissionsException, QuotaExceededException;
476 478

  
......
1159 1161
	 * @param name the name of the new file
1160 1162
	 * @param mimeType the MIME type of the file
1161 1163
	 * @param uploadedFile the uploaded file
1164
	 * @return The FileHeaderDTO created
1162 1165
	 * @throws DuplicateNameException if the specified name already exists in
1163 1166
	 *             the parent folder, as either a folder or file
1164 1167
	 * @throws ObjectNotFoundException if the user or parent folder was not
......
1168 1171
	 * @throws InsufficientPermissionsException
1169 1172
	 * @throws QuotaExceededException
1170 1173
	 */
1171
	public void createFile(Long userId, Long folderId, String name, String mimeType, File uploadedFile)
1174
	public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, File uploadedFile)
1172 1175
			throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
1173 1176
			InsufficientPermissionsException, QuotaExceededException;
1174 1177

  
......
1180 1183
	 * @param fileId the ID of the file header object
1181 1184
	 * @param mimeType the content type of the file
1182 1185
	 * @param uploadedFile the already uploadedFile
1186
	 * @return The FileHeaderDTO updated
1183 1187
	 * @throws ObjectNotFoundException if the user or file was not found, with
1184 1188
	 * 			the exception message mentioning the precise problem
1185 1189
	 * @throws GSSIOException when an IO exception occurs
1186 1190
	 * @throws InsufficientPermissionsException
1187 1191
	 * @throws QuotaExceededException
1188 1192
	 */
1189
	public void updateFileContents(Long userId, Long fileId, String mimeType,
1193
	public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType,
1190 1194
				File uploadedFile) throws ObjectNotFoundException, GSSIOException,
1191 1195
				InsufficientPermissionsException, QuotaExceededException;
1192 1196

  
......
1235 1239
	 * Update the user with the values from the supplied object.
1236 1240
	 */
1237 1241
	public void updateUser(User user);
1242

  
1243
	/**
1244
	 * Update accounting information for given user.
1245
	 *
1246
	 * @param user The user to update
1247
	 * @param date Date of transaction
1248
	 * @param bandwidthDiff Bandwidth used; positive for addition,
1249
	 * negative for subtraction (e.g. to rollback)
1250
	 */
1251
	public void updateAccounting(User user, Date date, long bandwidthDiff);
1238 1252
}
b/gss/src/gr/ebs/gss/server/ejb/ExternalAPIBean.java
489 489
	}
490 490

  
491 491
	@Override
492
	public void createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
492
	public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream)
493 493
			throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
494 494
			InsufficientPermissionsException, QuotaExceededException {
495 495
		File file = null;
......
499 499
			// Supply a more accurate problem description.
500 500
			throw new GSSIOException("Problem creating file",ioe);
501 501
		}
502
		createFile(userId, folderId, name, mimeType, file);
502
		return createFile(userId, folderId, name, mimeType, file);
503 503
	}
504 504

  
505 505
	/* (non-Javadoc)
......
832 832
	}
833 833

  
834 834
	@Override
835
	public void updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
835
	public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
836 836
		File file = null;
837 837
		try {
838 838
			file = uploadFile(resourceInputStream, userId);
......
840 840
			// Supply a more accurate problem description.
841 841
			throw new GSSIOException("Problem creating file",ioe);
842 842
		}
843
		updateFileContents(userId, fileId, mimeType, file);
843
		return updateFileContents(userId, fileId, mimeType, file);
844 844
	}
845 845

  
846 846
	@Override
......
2134 2134
		}
2135 2135
	}
2136 2136

  
2137
	public void createFile(Long userId, Long folderId, String name, String mimeType, File fileObject)
2137
	public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, File fileObject)
2138 2138
			throws DuplicateNameException, ObjectNotFoundException, GSSIOException,
2139 2139
			InsufficientPermissionsException, QuotaExceededException {
2140 2140
		// Validate.
......
2196 2196
		}
2197 2197
		dao.flush();
2198 2198
		indexFile(file.getId(), false);
2199

  
2200
		return file.getDTO();
2199 2201
	}
2200 2202

  
2201 2203
	/* (non-Javadoc)
2202 2204
	 * @see gr.ebs.gss.server.ejb.ExternalAPI#updateFileContents(java.lang.Long, java.lang.Long, java.lang.String, java.io.InputStream)
2203 2205
	 */
2204
	public void updateFileContents(Long userId, Long fileId, String mimeType, File fileObject) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
2206
	public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, File fileObject) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
2205 2207
		if (userId == null)
2206 2208
			throw new ObjectNotFoundException("No user specified");
2207 2209
		if (fileId == null)
......
2230 2232
		}
2231 2233

  
2232 2234
		indexFile(fileId, false);
2235
		return file.getDTO();
2233 2236
	}
2234 2237

  
2235 2238
	/**
......
2276 2279
		if (StringUtils.isEmpty(mimeType) || "application/octet-stream".equals(mimeType))
2277 2280
			body.setMimeType(identifyMimeType(name));
2278 2281
		else
2279
			body.setMimeType(mimeType);
2282
		body.setMimeType(mimeType);
2280 2283
		body.setAuditInfo(auditInfo);
2281 2284
		body.setFileSize(uploadedFile.length());
2282 2285
		body.setOriginalFilename(name);
......
2433 2436
		return user;
2434 2437
	}
2435 2438

  
2439
	@Override
2440
	public void updateAccounting(User user, Date date, long bandwidthDiff) {
2441
		dao.updateAccounting(user, date, bandwidthDiff);
2442
	}
2443

  
2436 2444
}
b/gss/src/gr/ebs/gss/server/ejb/ExternalAPIRemote.java
244 244
	 * @param name the name of the new file
245 245
	 * @param mimeType the MIME type of the file
246 246
	 * @param stream the input stream with the file contents
247
	 * @return The FileHeaderDTO created
247 248
	 * @throws DuplicateNameException if the specified name already exists in
248 249
	 *             the parent folder, as either a folder or file
249 250
	 * @throws ObjectNotFoundException if the user or parent folder was not
......
252 253
	 * @throws GSSIOException if there was an error while storing the file contents
253 254
	 * @throws InsufficientPermissionsException
254 255
	 */
255
	public void createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream) throws DuplicateNameException, ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
256
	public FileHeaderDTO createFile(Long userId, Long folderId, String name, String mimeType, InputStream stream) throws DuplicateNameException, ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
256 257

  
257 258
	/**
258 259
	 * Deletes the specified file in the specified user's namespace.
......
353 354
	 * @param fileId the ID of the file header object
354 355
	 * @param mimeType the content type of the file
355 356
	 * @param resourceInputStream a stream of the file contents
357
	 * @return The FileHeaderDTO updated
356 358
	 * @throws ObjectNotFoundException if the user or file was not found, with
357 359
	 * 			the exception message mentioning the precise problem
358 360
	 * @throws GSSIOException if there was an error while storing the file contents
359 361
	 * @throws InsufficientPermissionsException
360 362
	 */
361
	public void updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
363
	public FileHeaderDTO updateFileContents(Long userId, Long fileId, String mimeType, InputStream resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException;
362 364

  
363 365
	/**
364 366
	 * Copy the provided file to the specified destination.
b/gss/src/gr/ebs/gss/server/ejb/GSSDAO.java
27 27
import gr.ebs.gss.server.domain.Nonce;
28 28
import gr.ebs.gss.server.domain.User;
29 29

  
30
import java.util.Date;
30 31
import java.util.List;
31 32
import java.util.Set;
32 33

  
......
379 380
	 * @throws ObjectNotFoundException if the file body was not found
380 381
	 */
381 382
	public FileBody getFileVersion(Long fileId, int version) throws ObjectNotFoundException;
383

  
384
	/**
385
	 * Update accounting info for given user.
386
	 * Adds bandwidth used to appropriate time period bucket.
387
	 * Bucket is created if needed.
388
	 *
389
	 * @param user The user to update
390
	 * @param date Date of transaction
391
	 * @param bandwidthDiff Bandwidth used; positive for addition,
392
	 * negative for subtraction (e.g. to rollback)
393
	 */
394
	public void updateAccounting(User user, Date date, long bandwidthDiff);
382 395
}
b/gss/src/gr/ebs/gss/server/ejb/GSSDAOBean.java
19 19
package gr.ebs.gss.server.ejb;
20 20

  
21 21
import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
22
import gr.ebs.gss.server.domain.AccountingInfo;
22 23
import gr.ebs.gss.server.domain.FileBody;
23 24
import gr.ebs.gss.server.domain.FileHeader;
24 25
import gr.ebs.gss.server.domain.FileUploadStatus;
......
28 29
import gr.ebs.gss.server.domain.User;
29 30

  
30 31
import java.util.ArrayList;
32
import java.util.Calendar;
33
import java.util.Date;
34
import java.util.GregorianCalendar;
31 35
import java.util.HashSet;
32 36
import java.util.List;
33 37
import java.util.Set;
......
45 49
@Stateless
46 50
public class GSSDAOBean implements GSSDAO {
47 51

  
52
	private static final int BANDWIDTH_TIME_PERIOD_FIELD = Calendar.MONTH;
53
	private static final int BANDWIDTH_TIME_PERIOD_AMOUNT = 1;
54

  
48 55
	/**
49 56
	 * The entity manager for the persistence unit
50 57
	 */
......
535 542
			throw new ObjectNotFoundException("No version " + version + " found for file #" + fileId);
536 543
		}
537 544
	}
545

  
546
	@Override
547
	public void updateAccounting(User user, Date date, long bandwidthDiff) {
548
		AccountingInfo ai = null;
549
		try {
550
			ai = (AccountingInfo) manager.createQuery("select ai from AccountingInfo ai " +
551
				"where ai.user=:user and ai.dateFrom<=:date and ai.dateTo>:date")
552
				.setParameter("user", user)
553
				.setParameter("date", date)
554
				.getSingleResult();
555
		}
556
		catch (NoResultException e) {
557
			ai = null;
558
		}
559

  
560
		if (ai==null) {
561
			// The right entry does not exist; must be created.
562
			// This is where we set the initial time period.
563
			// We now start from the user's creation, we can change this to something else.
564
			Calendar creationDate = new GregorianCalendar();
565
			creationDate.setTime(user.getAuditInfo().getCreationDate());
566
			int offset = 0;
567
			Calendar dateFrom;
568
			Calendar dateTo;
569
			long timeInMillis = date.getTime();
570
			do {
571
				dateFrom = (Calendar) creationDate.clone();
572
				dateFrom.add(BANDWIDTH_TIME_PERIOD_FIELD, offset);
573
				dateTo = (Calendar) dateFrom.clone();
574
				dateTo.add(BANDWIDTH_TIME_PERIOD_FIELD, 1);
575
				offset += BANDWIDTH_TIME_PERIOD_AMOUNT;
576
			}
577
			while (!(dateFrom.getTimeInMillis()<=timeInMillis && dateTo.getTimeInMillis()>timeInMillis));
578

  
579
			ai = new AccountingInfo(user, dateFrom.getTime(), dateTo.getTime());
580
			manager.persist(ai);
581
		}
582

  
583
		// Do the update.
584
		ai.updateBandwidth(bandwidthDiff);
585
	}
586

  
538 587
}
b/gss/src/gr/ebs/gss/server/rest/FilesHandler.java
51 51
import java.net.URLDecoder;
52 52
import java.net.URLEncoder;
53 53
import java.util.ArrayList;
54
import java.util.Date;
54 55
import java.util.HashSet;
55 56
import java.util.List;
56 57
import java.util.Set;
......
425 426
						copy(file, renderResult, ostream, req, oldBody);
426 427
					else
427 428
						copy(file, renderResult, writer, req, oldBody);
429
	    			if (file!=null) getService().updateAccounting(user, new Date(), contentLength);
428 430
        		} catch (ObjectNotFoundException e) {
429 431
        			resp.sendError(HttpServletResponse.SC_NOT_FOUND);
430 432
        			return;
......
472 474
							copy(file, ostream, range, req, oldBody);
473 475
						else
474 476
							copy(file, writer, range, req, oldBody);
477
	    				getService().updateAccounting(user, new Date(), contentLength);
475 478
    	    		} catch (ObjectNotFoundException e) {
476 479
    	    			resp.sendError(HttpServletResponse.SC_NOT_FOUND);
477 480
    	    			return;
......
496 499
							copy(file, ostream, ranges.iterator(), contentType, req, oldBody);
497 500
						else
498 501
							copy(file, writer, ranges.iterator(), contentType, req, oldBody);
502
	    				getService().updateAccounting(user, new Date(), contentLength);
499 503
    	    		} catch (ObjectNotFoundException e) {
500 504
    	    			resp.sendError(HttpServletResponse.SC_NOT_FOUND);
501 505
    	    			return;
......
816 820
					} catch (IOException ex) {
817 821
						throw new GSSIOException(ex, false);
818 822
					}
823
					FileHeaderDTO fileDTO = null;
819 824
					if (file == null)
820
						getService().createFile(user.getId(), folder.getId(), fileName, contentType, uploadedFile);
825
						fileDTO = getService().createFile(user.getId(), folder.getId(), fileName, contentType, uploadedFile);
821 826
					else
822
						getService().updateFileContents(user.getId(), file.getId(), contentType, uploadedFile);
827
						fileDTO = getService().updateFileContents(user.getId(), file.getId(), contentType, uploadedFile);
828
					getService().updateAccounting(user, new Date(), fileDTO.getFileSize());
823 829
					getService().removeFileUploadProgress(user.getId(), fileName);
824 830
				}
825 831
			}
......
1471 1477
        	String name = getLastElement(path);
1472 1478
        	String mimeType = context.getMimeType(name);
1473 1479
            // FIXME: Add attributes
1480
        	FileHeaderDTO fileDTO = null;
1474 1481
            if (exists)
1475
				getService().updateFileContents(user.getId(), file.getId(), mimeType, resourceInputStream);
1482
            	fileDTO = getService().updateFileContents(user.getId(), file.getId(), mimeType, resourceInputStream);
1476 1483
			else
1477
	        	getService().createFile(user.getId(), folder.getId(), name, mimeType, resourceInputStream);
1484
				fileDTO = getService().createFile(user.getId(), folder.getId(), name, mimeType, resourceInputStream);
1485
            getService().updateAccounting(user, new Date(), fileDTO.getFileSize());
1478 1486
			getService().removeFileUploadProgress(user.getId(), file.getName());
1479 1487
        } catch(ObjectNotFoundException e) {
1480 1488
            result = false;
b/gss/src/gr/ebs/gss/server/soap/WSAPIBean.java
35 35

  
36 36
import java.io.File;
37 37
import java.io.IOException;
38
import java.util.Date;
38 39
import java.util.List;
39 40
import java.util.Set;
40 41

  
......
88 89
	@Override
89 90
	public void createFile(@WebParam(name="userId")Long userId, @WebParam(name="folderId")Long folderId, @WebParam(name="name")String name, @WebParam(name="mimeType")String mimeType, @WebParam(name="stream")DataHandler stream) throws DuplicateNameException, ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
90 91
		try {
91
			api.createFile(userId, folderId, name, mimeType, stream.getInputStream());
92
			FileHeaderDTO file = api.createFile(userId, folderId, name, mimeType, stream.getInputStream());
93
			User user = api.getUser(userId);
94
			api.updateAccounting(user, new Date(), file.getFileSize());
92 95
		} catch (IOException e) {
93 96
			throw new GSSIOException(e);
94 97
		}
......
379 382
	@Override
380 383
	public void updateFileContents(@WebParam(name="userId") Long userId, @WebParam(name="fileId") Long fileId, @WebParam(name="mimeType") String mimeType, @WebParam(name="resourceStream") DataHandler resourceInputStream) throws ObjectNotFoundException, GSSIOException, InsufficientPermissionsException, QuotaExceededException {
381 384
		try {
382
			api.updateFileContents(userId, fileId, mimeType, resourceInputStream.getInputStream());
385
			FileHeaderDTO file = api.updateFileContents(userId, fileId, mimeType, resourceInputStream.getInputStream());
386
			User user = api.getUser(userId);
387
			api.updateAccounting(user, new Date(), file.getFileSize());
383 388
		} catch (IOException e) {
384 389
			throw new GSSIOException(e);
385 390
		}
b/gss/src/gr/ebs/gss/server/webdav/Webdav.java
790 790
			String name = getLastElement(path);
791 791
			String mimeType = getServletContext().getMimeType(name);
792 792
			// FIXME: Add attributes
793
			FileHeaderDTO fileDTO = null;
793 794
			if (exists)
794
				getService().updateFileContents(user.getId(), file.getId(), mimeType, resourceInputStream);
795
				fileDTO = getService().updateFileContents(user.getId(), file.getId(), mimeType, resourceInputStream);
795 796
			else
796
				getService().createFile(user.getId(), folder.getId(), name, mimeType, resourceInputStream);
797
				fileDTO = getService().createFile(user.getId(), folder.getId(), name, mimeType, resourceInputStream);
798
			getService().updateAccounting(user, new Date(), fileDTO.getFileSize());
797 799
		} catch (ObjectNotFoundException e) {
798 800
			result = false;
799 801
		} catch (InsufficientPermissionsException e) {
......
2432 2434
					copy(file, renderResult, ostream, req, null);
2433 2435
				else
2434 2436
					copy(file, renderResult, writer, req, null);
2437
				getService().updateAccounting(user, new Date(), contentLength);
2435 2438
			}
2436 2439
		} else {
2437 2440
			if (ranges == null || ranges.isEmpty())
......
2465 2468
						copy(file, ostream, range, req, null);
2466 2469
					else
2467 2470
						copy(file, writer, range, req, null);
2471
					getService().updateAccounting(user, new Date(), contentLength);
2468 2472
				}
2469 2473

  
2470 2474
			} else {

Also available in: Unified diff