3 * Copyright (C) 2012 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.remote
.controller
;
12 import java
.io
.IOException
;
13 import java
.util
.ArrayList
;
14 import java
.util
.HashMap
;
15 import java
.util
.List
;
17 import java
.util
.UUID
;
19 import javax
.servlet
.http
.HttpServletRequest
;
20 import javax
.servlet
.http
.HttpServletResponse
;
22 import org
.apache
.commons
.io
.FileUtils
;
23 import org
.apache
.commons
.io
.FilenameUtils
;
24 import org
.springframework
.stereotype
.Controller
;
25 import org
.springframework
.web
.bind
.WebDataBinder
;
26 import org
.springframework
.web
.bind
.annotation
.InitBinder
;
27 import org
.springframework
.web
.bind
.annotation
.PathVariable
;
28 import org
.springframework
.web
.bind
.annotation
.RequestMapping
;
29 import org
.springframework
.web
.bind
.annotation
.RequestMethod
;
30 import org
.springframework
.web
.servlet
.ModelAndView
;
32 import eu
.etaxonomy
.cdm
.common
.monitor
.IRestServiceProgressMonitor
;
33 import eu
.etaxonomy
.cdm
.remote
.editor
.UUIDPropertyEditor
;
36 * @author Andreas Kohlbecker
41 @RequestMapping(value
="/progress/")
42 public class ProgressMonitorController
{
44 private Map
<UUID
, IRestServiceProgressMonitor
> monitors
= new HashMap
<UUID
, IRestServiceProgressMonitor
>();
46 private Map
<UUID
, Long
> timeoutMap
= new HashMap
<UUID
, Long
>();
48 private Thread cleanUpThread
= null;
51 * Time out in minutes for monitors which are done.
52 * A monitor which is set done will be removed after this interval.
54 private int cleanUpTimeout
= 1;
59 private int cleanUpInterval
= 1000 * 10; // 10 seconds
62 public void initBinder(WebDataBinder binder
) {
63 binder
.registerCustomEditor(UUID
.class, new UUIDPropertyEditor());
66 public ProgressMonitorController(){
68 this.cleanUpThread
= new Thread(){
73 sleep(cleanUpInterval
);
74 } catch (InterruptedException e
) {
81 cleanUpThread
.start();
86 * run every n minutes clean up monitors which have been marked done x minutes ago
88 private void scheduledCeanUp() {
90 List
<UUID
> timedOutMonitors
= new ArrayList
<UUID
>();
91 IRestServiceProgressMonitor monitor
;
93 long now
= System
.currentTimeMillis();
94 long nextTimeout
= now
+ cleanUpTimeout
* 1000 * 60;
97 // add monitors which are stopped or done to the timeoutMap
98 for(UUID uuid
: monitors
.keySet()){
99 monitor
= monitors
.get(uuid
);
100 if((monitor
.isFailed() || monitor
.isDone())){
101 if(!timeoutMap
.containsKey(uuid
)){
102 timeoutMap
.put(uuid
, nextTimeout
);
107 // check with monitor has timed out
108 for(UUID uuid
: timeoutMap
.keySet()){
109 if(timeoutMap
.get(uuid
) <= now
){
110 timedOutMonitors
.add(uuid
);
114 //finally remove the monitors
115 for(UUID uuid
: timedOutMonitors
){
116 timeoutMap
.remove(uuid
);
117 monitors
.remove(uuid
);
122 public UUID
registerMonitor(IRestServiceProgressMonitor monitor
){
123 UUID uuid
= UUID
.randomUUID();
124 monitors
.put(uuid
, monitor
);
128 public IRestServiceProgressMonitor
getMonitor(UUID uuid
) {
129 return monitors
.get(uuid
);
133 * returns true if the {@link IRestServiceProgressMonitor} identified by the <code>uuid</code>
134 * exists and if it is still indicating a running thread
138 public boolean isMonitorRunning(UUID uuid
) {
139 IRestServiceProgressMonitor monitor
= getMonitor(uuid
);
140 return monitor
!= null && !monitor
.isCanceled() && !monitor
.isDone() && !monitor
.isFailed();
144 * @param request the request for which to create he path for, is needed to read the file extension from.
145 * @param uuid the uuid key of the monitor
148 public String
pathFor(HttpServletRequest request
, UUID uuid
){
149 String fileExtension
= FilenameUtils
.getExtension(request
.getServletPath());
150 return "/progress/" + uuid
.toString() + (fileExtension
.length() > 0 ?
'.': "") + fileExtension
;
153 @RequestMapping(value
= "{uuid}", method
= RequestMethod
.GET
)
154 public ModelAndView
doProgressMonitor(@PathVariable("uuid") UUID uuid
, HttpServletRequest request
, HttpServletResponse response
)
157 ModelAndView mv
= new ModelAndView();
159 if (monitors
.containsKey(uuid
)) {
160 mv
.addObject(monitors
.get(uuid
));
162 response
.sendError(404, "No such progress monitor found. The process being monitored may have been completed and the according monitor may have been removed due to the clean up timepout.");