cleanup
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / controller / DescriptionListController.java
1 /**
2 * Copyright (C) 2009 EDIT European Distributed Institute of Taxonomy
3 * http://www.e-taxonomy.eu
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 See LICENSE.TXT at the top of this package for the full license terms.
7 */
8
9 package eu.etaxonomy.cdm.remote.controller;
10
11 import io.swagger.annotations.Api;
12
13 import java.awt.Color;
14 import java.io.IOException;
15 import java.util.Arrays;
16 import java.util.EnumSet;
17 import java.util.List;
18 import java.util.Map;
19 import java.util.Set;
20 import java.util.UUID;
21
22 import javax.servlet.http.HttpServletRequest;
23 import javax.servlet.http.HttpServletResponse;
24
25 import org.springframework.beans.factory.annotation.Autowired;
26 import org.springframework.stereotype.Controller;
27 import org.springframework.web.bind.WebDataBinder;
28 import org.springframework.web.bind.annotation.InitBinder;
29 import org.springframework.web.bind.annotation.PathVariable;
30 import org.springframework.web.bind.annotation.RequestMapping;
31 import org.springframework.web.bind.annotation.RequestMethod;
32 import org.springframework.web.bind.annotation.RequestParam;
33 import org.springframework.web.servlet.ModelAndView;
34
35 import com.fasterxml.jackson.core.JsonParseException;
36 import com.fasterxml.jackson.databind.JsonMappingException;
37
38 import eu.etaxonomy.cdm.api.service.IDescriptionService;
39 import eu.etaxonomy.cdm.api.service.ITaxonService;
40 import eu.etaxonomy.cdm.api.service.ITermService;
41 import eu.etaxonomy.cdm.api.service.IVocabularyService;
42 import eu.etaxonomy.cdm.api.service.description.TransmissionEngineDistribution;
43 import eu.etaxonomy.cdm.api.service.description.TransmissionEngineDistribution.AggregationMode;
44 import eu.etaxonomy.cdm.api.service.dto.DistributionInfoDTO;
45 import eu.etaxonomy.cdm.api.service.dto.DistributionInfoDTO.InfoPart;
46 import eu.etaxonomy.cdm.api.service.pager.Pager;
47 import eu.etaxonomy.cdm.api.utility.DistributionOrder;
48 import eu.etaxonomy.cdm.common.JvmLimitsException;
49 import eu.etaxonomy.cdm.common.monitor.IRestServiceProgressMonitor;
50 import eu.etaxonomy.cdm.ext.geo.CondensedDistributionRecipe;
51 import eu.etaxonomy.cdm.ext.geo.EditGeoServiceUtilities;
52 import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
53 import eu.etaxonomy.cdm.model.common.MarkerType;
54 import eu.etaxonomy.cdm.model.description.DescriptionBase;
55 import eu.etaxonomy.cdm.model.description.Feature;
56 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
57 import eu.etaxonomy.cdm.model.location.NamedArea;
58 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
59 import eu.etaxonomy.cdm.model.location.NamedAreaType;
60 import eu.etaxonomy.cdm.model.name.Rank;
61 import eu.etaxonomy.cdm.persistence.dto.TermDto;
62 import eu.etaxonomy.cdm.persistence.query.OrderHint;
63 import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;
64 import eu.etaxonomy.cdm.remote.controller.util.ProgressMonitorUtil;
65 import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
66 import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
67 import eu.etaxonomy.cdm.remote.editor.TermBasePropertyEditor;
68 import eu.etaxonomy.cdm.remote.l10n.LocaleContext;
69
70 /**
71 * TODO write controller documentation
72 *
73 * @author a.kohlbecker
74 * @date 24.03.2009
75 */
76 @Controller
77 @Api("description")
78 @RequestMapping(value = {"/description"})
79 public class DescriptionListController extends AbstractIdentifiableListController<DescriptionBase, IDescriptionService> {
80
81
82 @Autowired
83 private ITermService termService;
84
85 @Autowired
86 private IVocabularyService vocabularyService ;
87
88 @Autowired
89 private ITaxonService taxonService;
90
91 @Autowired
92 private IEditGeoService geoService;
93
94 @Autowired
95 public TransmissionEngineDistribution transmissionEngineDistribution;
96
97 @Autowired
98 public ProgressMonitorController progressMonitorController;
99
100 protected static final List<String> DESCRIPTION_ELEMENT_INIT_STRATEGY = Arrays.asList(new String []{
101 "$",
102 "multilanguageText",
103 });
104
105 /**
106 * There should only be one longtime processes
107 * therefore the according progress monitor uuid is stored in
108 * this static field.
109 */
110 private static UUID transmissionEngineMonitorUuid = null;
111
112
113 @Override
114 @Autowired
115 public void setService(IDescriptionService service) {
116 this.service = service;
117 }
118
119 @InitBinder
120 @Override
121 public void initBinder(WebDataBinder binder) {
122 super.initBinder(binder);
123 binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<Feature>(termService));
124 binder.registerCustomEditor(NamedAreaLevel.class, new TermBasePropertyEditor<NamedAreaLevel>(termService));
125 binder.registerCustomEditor(Rank.class, new TermBasePropertyEditor<Rank>(termService));
126 }
127
128 protected List<String> getDescriptionInfoInitStrategy(){
129 return getInitializationStrategy();
130 }
131
132
133 /**
134 * Runs the {@link TransmissionEngineDistribution} in a separate Thread and
135 * responds with a redirect to a progress monitor REST service end point.
136 * <p>
137 *
138 * @param mode
139 * one of <code>byAreas</code>, <code>byRanks</code>,
140 * <code>byAreasAndRanks</code>
141 * @param frontendBaseUrl
142 * the cdm server instance base URL, this is needed for the a
143 * proper redirect URL when the service is running behind a
144 * reverse HTTP proxy
145 * @param priority
146 * the priority for the Thread to spawn, see
147 * {@link Thread#setPriority(int)}, defaults to 3
148 * @param targetAreaLevel
149 * The level of target areas to project the distributions to.
150 * @param lowerRank
151 * @param upperRank
152 *
153 * @param request
154 * @param response
155 * @return
156 * @throws IOException
157 */
158 @RequestMapping(value = { "accumulateDistributions" }, method = RequestMethod.GET)
159 public ModelAndView doAccumulateDistributions(
160 @RequestParam(value= "mode", required = true) final AggregationMode mode,
161 @RequestParam(value = "frontendBaseUrl", required = false) String frontendBaseUrl,
162 @RequestParam(value = "priority", required = false) Integer priority,
163 @RequestParam(value = "targetAreaLevel", required = true) final NamedAreaLevel targetAreaLevel,
164 @RequestParam(value = "lowerRank", required = false) Rank lowerRank,
165 @RequestParam(value = "upperRank", required = false) Rank upperRank,
166 HttpServletRequest request,
167 HttpServletResponse response) throws IOException {
168
169 logger.info("doAccumulateDistributions()" + request.getRequestURI());
170
171 // transmissionEngineDistribution.updatePriorities();
172
173 String processLabel = "accumulating distributions";
174
175 final Rank _lowerRank = lowerRank != null ? lowerRank : Rank.UNKNOWN_RANK(); // this is the lowest rank
176 final Rank _upperRank = upperRank != null ? upperRank : Rank.GENUS();
177
178 ProgressMonitorUtil progressUtil = new ProgressMonitorUtil(progressMonitorController);
179
180 final List<String> term_init_strategy = Arrays.asList(new String []{
181 "representations"
182 });
183
184 if (!progressMonitorController.isMonitorRunning(transmissionEngineMonitorUuid)) {
185 transmissionEngineMonitorUuid = progressUtil.registerNewMonitor();
186 Thread subThread = new Thread() {
187 @Override
188 public void run() {
189 Pager<NamedArea> areaPager = termService.list(targetAreaLevel, (NamedAreaType) null,
190 null, null, (List<OrderHint>) null, term_init_strategy);
191 try {
192 transmissionEngineDistribution.accumulate(mode, areaPager.getRecords(), _lowerRank, _upperRank,
193 null, progressMonitorController.getMonitor(transmissionEngineMonitorUuid));
194 } catch (JvmLimitsException e) {
195 IRestServiceProgressMonitor monitor = progressMonitorController.getMonitor(transmissionEngineMonitorUuid);
196 monitor.setIsFailed(true);
197 monitor.setFeedback(e);
198 }
199 }
200 };
201 if(priority == null) {
202 priority = AbstractController.DEFAULT_BATCH_THREAD_PRIORITY;
203 }
204 subThread.setPriority(priority);
205 subThread.start();
206 }
207
208 // send redirect "see other"
209 return progressUtil.respondWithMonitor(frontendBaseUrl, processLabel, transmissionEngineMonitorUuid, false, request, response);
210 }
211
212 @RequestMapping(value = "namedAreasInUse", method = RequestMethod.GET)
213 public Pager<TermDto> doPageNamedAreasInUse(
214 @RequestParam(value = "includeAllParents", required = false) boolean includeAllParents,
215 @RequestParam(value = "pageSize", required = false) Integer pageSize,
216 @RequestParam(value = "pageNumber", required = false) Integer pageNumber, HttpServletRequest request,
217 HttpServletResponse response) throws IOException {
218
219 logger.info("doPageNamedAreasInUse : " + requestPathAndQuery(request));
220
221 PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
222 pagerParams.normalizeAndValidate(response);
223
224 Pager<TermDto> pager = service.pageNamedAreasInUse(includeAllParents, pagerParams.getPageSize(), pagerParams.getPageIndex());
225
226 localizeTerms(pager);
227
228 return pager;
229 }
230
231 /**
232 * @param taxonUuid
233 * @param parts
234 * possible values: condensedStatus, tree, mapUriParams,
235 * elements,
236 * @param subAreaPreference
237 * @param statusOrderPreference
238 * @param hideMarkedAreasList
239 * @param omitLevels
240 * @param request
241 * @param response
242 * @param distributionOrder
243 * Default is LABEL
244 * @param recipe
245 * The recipe for creating the condensed distribution status
246 * @return
247 * @throws IOException
248 * @throws JsonMappingException
249 * @throws JsonParseException
250 */
251 @RequestMapping(value = "distributionInfoFor/{uuid}", method = RequestMethod.GET)
252 public ModelAndView doGetDistributionInfo(
253 @PathVariable("uuid") UUID taxonUuid,
254 @RequestParam("part") Set<InfoPart> partSet,
255 @RequestParam(value = "subAreaPreference", required = false) boolean subAreaPreference,
256 @RequestParam(value = "statusOrderPreference", required = false) boolean statusOrderPreference,
257 @RequestParam(value = "hiddenAreaMarkerType", required = false) DefinedTermBaseList<MarkerType> hideMarkedAreasList,
258 @RequestParam(value = "omitLevels", required = false) Set<NamedAreaLevel> omitLevels,
259 @RequestParam(value = "statusColors", required = false) String statusColorsString,
260 @RequestParam(value = "distributionOrder", required = false, defaultValue="LABEL") DistributionOrder distributionOrder,
261 @RequestParam(value = "recipe", required = false, defaultValue="EuroPlusMed") CondensedDistributionRecipe recipe,
262 HttpServletRequest request,
263 HttpServletResponse response) throws JsonParseException, JsonMappingException, IOException {
264
265 logger.info("doGetDistributionInfo() - " + requestPathAndQuery(request));
266
267 ModelAndView mv = new ModelAndView();
268
269 Set<MarkerType> hideMarkedAreas = null;
270 if(hideMarkedAreasList != null){
271 hideMarkedAreas = hideMarkedAreasList.asSet();
272 }
273
274 EnumSet<InfoPart> parts = EnumSet.copyOf(partSet);
275
276 Map<PresenceAbsenceTerm, Color> presenceAbsenceTermColors = EditGeoServiceUtilities.buildStatusColorMap(statusColorsString, termService, vocabularyService);
277
278 DistributionInfoDTO dto = geoService.composeDistributionInfoFor(parts, taxonUuid,
279 subAreaPreference, statusOrderPreference, hideMarkedAreas, omitLevels,
280 presenceAbsenceTermColors, LocaleContext.getLanguages(),
281 getDescriptionInfoInitStrategy(), recipe, distributionOrder);
282
283 mv.addObject(dto);
284
285 return mv;
286 }
287
288 }