Merge branch 'release/5.15.0'
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / controller / ext / ExternalGeoController.java
1 /**
2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.remote.controller.ext;
10
11 import java.awt.Color;
12 import java.io.FileReader;
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashMap;
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.apache.log4j.Logger;
26 import org.springframework.beans.factory.annotation.Autowired;
27 import org.springframework.http.HttpStatus;
28 import org.springframework.http.ResponseEntity;
29 import org.springframework.stereotype.Controller;
30 import org.springframework.web.bind.WebDataBinder;
31 import org.springframework.web.bind.annotation.CrossOrigin;
32 import org.springframework.web.bind.annotation.InitBinder;
33 import org.springframework.web.bind.annotation.PathVariable;
34 import org.springframework.web.bind.annotation.RequestMapping;
35 import org.springframework.web.bind.annotation.RequestMethod;
36 import org.springframework.web.bind.annotation.RequestParam;
37 import org.springframework.web.bind.annotation.RestController;
38 import org.springframework.web.servlet.ModelAndView;
39
40 import eu.etaxonomy.cdm.api.service.IDescriptionService;
41 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
42 import eu.etaxonomy.cdm.api.service.ITaxonService;
43 import eu.etaxonomy.cdm.api.service.ITermService;
44 import eu.etaxonomy.cdm.api.service.pager.Pager;
45 import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge;
46 import eu.etaxonomy.cdm.api.utility.DescriptionUtility;
47 import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
48 import eu.etaxonomy.cdm.ext.geo.EditGeoServiceUtilities;
49 import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
50 import eu.etaxonomy.cdm.ext.geo.OccurrenceServiceRequestParameterDto;
51 import eu.etaxonomy.cdm.model.common.Language;
52 import eu.etaxonomy.cdm.model.common.Marker;
53 import eu.etaxonomy.cdm.model.common.MarkerType;
54 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
55 import eu.etaxonomy.cdm.model.description.TaxonDescription;
56 import eu.etaxonomy.cdm.model.location.NamedArea;
57 import eu.etaxonomy.cdm.model.location.Point;
58 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
59 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
60 import eu.etaxonomy.cdm.model.taxon.Taxon;
61 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
62 import eu.etaxonomy.cdm.model.term.DefinedTerm;
63 import eu.etaxonomy.cdm.persistence.query.OrderHint;
64 import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;
65 import eu.etaxonomy.cdm.remote.controller.BaseController;
66 import eu.etaxonomy.cdm.remote.controller.util.ControllerUtils;
67 import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
68 import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
69 import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;
70 import eu.etaxonomy.cdm.remote.editor.UuidList;
71 import eu.etaxonomy.cdm.remote.l10n.LocaleContext;
72 import io.swagger.annotations.Api;
73
74 /**
75 * The ExternalGeoController class is a Spring MVC Controller.
76 * <p>
77 * The syntax of the mapped service URIs contains the the {datasource-name} path element.
78 * The available {datasource-name}s are defined in a configuration file which
79 * is loaded by the {@link UpdatableRoutingDataSource}. If the
80 * UpdatableRoutingDataSource is not being used in the actual application
81 * context any arbitrary {datasource-name} may be used.
82 * <p>
83 * @author a.kohlbecker
84 * @since 18.06.2009
85 *
86 */
87
88 @Controller
89 @Api(value="mapServiceParameters")
90 @RequestMapping(value = { "ext/edit/mapServiceParameters/" })
91 public class ExternalGeoController extends BaseController<TaxonBase, ITaxonService> {
92
93 public static final Logger logger = Logger.getLogger(ExternalGeoController.class);
94
95 @Autowired
96 private IEditGeoService geoservice;
97
98 @Autowired
99 private IDescriptionService descriptionService;
100
101 @Autowired
102 private IOccurrenceService occurrenceService;
103
104 @Autowired
105 private ITermService termService;
106
107 @InitBinder
108 @Override
109 public void initBinder(WebDataBinder binder) {
110 super.initBinder(binder);
111 binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
112 binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<MarkerType>(termService));
113 }
114
115 @Autowired
116 @Override
117 public void setService(ITaxonService service) {
118 this.service = service;
119 }
120
121 /**
122 * Assembles and returns URI parameter Strings for the EDIT Map Service. The distribution areas for the
123 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code> are found and are translated into
124 * an valid URI parameter String. Higher level distribution areas are expanded in order to include all
125 * nested sub-areas.
126 * <p>
127 * URI: <b>&#x002F;{datasource-name}&#x002F;geo&#x002F;map&#x002F;distribution&#x002F;{taxon-uuid}</b>
128 *
129 *
130 * @param subAreaPreference
131 * enables the <b>Sub area preference rule</b> if set to true,
132 * see {@link DescriptionUtility#filterDistributions(Collection, boolean, boolean}
133 * @param statusOrderPreference
134 * enables the <b>Status order preference rule</b> if set to true,
135 * see {@link DescriptionUtility#filterDistributions(Collection, boolean, boolean}
136 * @param hideMarkedAreas
137 * comma separated list of {@link MarkerType} uuids,
138 * distributions where the area has a {@link Marker} with one of
139 * the specified {@link MarkerType}s will be skipped, see
140 * {@link DescriptionUtility#filterDistributions(Collection, boolean, boolean, Set)}
141 * @param request
142 * @param response
143 * @return URI parameter Strings for the EDIT Map Service
144 * @throws IOException
145 */
146 @RequestMapping(value = { "taxonDistributionFor/{uuid}" }, method = RequestMethod.GET)
147 public ModelAndView doGetDistributionMapUriParams(
148 @PathVariable("uuid") UUID uuid,
149 @RequestParam(value = "subAreaPreference", required = false) boolean subAreaPreference,
150 @RequestParam(value = "statusOrderPreference", required = false) boolean statusOrderPreference,
151 @RequestParam(value = "hideMarkedAreas", required = false) DefinedTermBaseList<MarkerType> hideMarkedAreasList,
152 HttpServletRequest request,
153 HttpServletResponse response)
154 throws IOException {
155
156 logger.info("doGetDistributionMapUriParams() " + request.getRequestURI());
157 ModelAndView mv = new ModelAndView();
158
159 // get the descriptions for the taxon
160 Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);
161
162 Map<PresenceAbsenceTerm, Color> presenceAbsenceTermColors = null;
163 //languages
164 List<Language> langs = LocaleContext.getLanguages();
165
166 Set<MarkerType> hideMarkedAreas = null;
167 if(hideMarkedAreasList != null){
168 hideMarkedAreas = hideMarkedAreasList.asSet();
169 }
170
171 Set<DefinedTerm> scopes = null;
172 Set<NamedArea> geographicalScope = null;
173 Integer pageSize = null;
174 Integer pageNumber = null;
175 List<String> propertyPaths = null;
176 Pager<TaxonDescription> page = descriptionService.pageTaxonDescriptions(taxon, scopes, geographicalScope, pageSize, pageNumber, propertyPaths);
177
178 List<TaxonDescription> taxonDescriptions = page.getRecords();
179 String uriParams = geoservice.getDistributionServiceRequestParameterString(taxonDescriptions,
180 subAreaPreference, statusOrderPreference,
181 hideMarkedAreas, presenceAbsenceTermColors, langs);
182 mv.addObject(uriParams);
183
184 return mv;
185 }
186
187
188 /**
189 * Assembles and returns URI parameter Strings for the EDIT Map Service. The distribution areas for the
190 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code> are found and are translated into
191 * an valid URI parameter String. Higher level distribution areas are expanded in order to include all
192 * nested sub-areas.
193 * <p>
194 * URI: <b>&#x002F;{datasource-name}&#x002F;geo&#x002F;map&#x002F;distribution&#x002F;{taxon-uuid}</b>
195 *
196 * @param request
197 * @param response
198 * @return URI parameter Strings for the EDIT Map Service
199 * @throws IOException TODO write controller method documentation
200 */
201 @RequestMapping(value = { "taxonOccurrencesFor/{uuid}" }, method = RequestMethod.GET)
202 public OccurrenceServiceRequestParameterDto doGetOccurrenceMapUriParams(
203 @PathVariable("uuid") UUID uuid,
204 @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
205 @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
206 @RequestParam(value = "maxDepth", required = false) Integer maxDepth,
207 HttpServletRequest request,
208 HttpServletResponse response)
209 throws IOException {
210
211
212 logger.info("doGetOccurrenceMapUriParams() " + requestPathAndQuery(request));
213
214 Map<SpecimenOrObservationType, Color> specimenOrObservationTypeColors = null;
215
216 List<SpecimenOrObservationBase> specimensOrObersvations = occurencesForTaxon(uuid, relationshipUuids,
217 relationshipInversUuids, maxDepth, response);
218
219 OccurrenceServiceRequestParameterDto dto = geoservice.getOccurrenceServiceRequestParameters(specimensOrObersvations,
220 specimenOrObservationTypeColors );
221
222 return dto;
223 }
224
225 private List<SpecimenOrObservationBase> occurencesForTaxon(UUID taxonUuid, UuidList relationshipUuids,
226 UuidList relationshipInversUuids, Integer maxDepth, HttpServletResponse response) throws IOException {
227 Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(
228 relationshipUuids, relationshipInversUuids, termService);
229
230 Taxon taxon = getCdmBaseInstance(Taxon.class, taxonUuid, response, (List<String>)null);
231
232 List<OrderHint> orderHints = new ArrayList<OrderHint>();
233 orderHints.add(new OrderHint("titleCache", SortOrder.DESCENDING));
234
235 List<SpecimenOrObservationBase> specimensOrObersvations = occurrenceService.listByAssociatedTaxon(
236 null, includeRelationships, taxon, maxDepth, null, null, orderHints, null);
237 return specimensOrObersvations;
238 }
239
240 /**
241 * Assembles and returns URI parameter Strings for the EDIT Map Service. The distribution areas for the
242 * {@link Taxon} instance identified by the <code>{taxon-uuid}</code> are found and are translated into
243 * an valid URI parameter String. Higher level distribution areas are expanded in order to include all
244 * nested sub-areas.
245 * <p>
246 * URI: <b>&#x002F;{datasource-name}&#x002F;geo&#x002F;map&#x002F;distribution&#x002F;{taxon-uuid}</b>
247 *
248 * @param request
249 * @param response
250 * @return URI parameter Strings for the EDIT Map Service
251 * @throws IOException TODO write controller method documentation
252 */
253 @RequestMapping(value = { "taxonOccurrencesForX" }, method = RequestMethod.GET)
254 public ModelAndView doGetOccurrenceXMapUriParams(
255 @RequestParam(value = "fieldUnitUuidList", required = false) UuidList fieldUnitUuids,
256 HttpServletRequest request,
257 HttpServletResponse response)
258 throws IOException {
259
260 Map<SpecimenOrObservationType, Color> specimenOrObservationTypeColors = null;
261
262 logger.info("doGetOccurrenceMapUriParams() " + requestPathAndQuery(request));
263 ModelAndView mv = new ModelAndView();
264
265 List<Point> fieldUnitPoints = occurrenceService.findPointsForFieldUnitList(fieldUnitUuids);
266
267 OccurrenceServiceRequestParameterDto dto = EditGeoServiceUtilities.getOccurrenceServiceRequestParameterString(fieldUnitPoints,
268 null, specimenOrObservationTypeColors);
269 mv.addObject(dto);
270 return mv;
271 }
272
273 /**
274 * EXPERIMENTAL !!!!!
275 * DO NOT USE !!!!!
276 *
277 * @param vocabUuid
278 * @param request
279 * @param response
280 * @return
281 * @throws IOException
282 *
283 * @author a.kohlbecker
284 */
285 @RequestMapping(value = { "mapShapeFileToNamedAreas" }, method = RequestMethod.GET)
286 public ModelAndView doMapShapeFileToNamedAreas(
287 @RequestParam(required=false, value="vocabularyUuid") UUID vocabUuid,
288 @RequestParam(required=false, value="namedAreaUuids") UuidList namedAreaUuids,
289 @RequestParam(required=true, value="localFile") String localFile,
290 @RequestParam(required=true, value="idSearchField") List<String> idSearchFields,
291 @RequestParam(required=true, value="wmsLayerName") String wmsLayerName,
292 HttpServletRequest request,
293 HttpServletResponse response)
294 throws IOException {
295
296 logger.info("doMapShapeFileToNamedAreas() " + requestPathAndQuery(request));
297 ModelAndView mv = new ModelAndView();
298
299 FileReader reader = new FileReader(localFile);
300
301 Set<UUID> areaUuidSet = null;
302 if(namedAreaUuids != null) {
303 areaUuidSet = namedAreaUuids.asSet();
304 }
305 Map<NamedArea, String> resultMap = geoservice.mapShapeFileToNamedAreas(
306 reader, idSearchFields , wmsLayerName , vocabUuid, areaUuidSet);
307 Map<String, String> flatResultMap = new HashMap<String, String>(resultMap.size());
308 for(NamedArea area : resultMap.keySet()){
309 flatResultMap.put(area.getTitleCache() + " [" + area.getUuid() + "]", resultMap.get(area));
310 }
311 mv.addObject(flatResultMap);
312 return mv;
313
314 }
315
316
317 }