Project

General

Profile

Download (14.8 KB) Statistics
| Branch: | Tag: | Revision:
1 bad845a9 Andreas Müller
/**
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 d41d0a9d Andreas Kohlbecker
import java.awt.Color;
12 bad845a9 Andreas Müller
import java.io.IOException;
13 ff7c0745 Katja Luther
import java.util.ArrayList;
14 bad845a9 Andreas Müller
import java.util.Arrays;
15 d41d0a9d Andreas Kohlbecker
import java.util.EnumSet;
16 bad845a9 Andreas Müller
import java.util.List;
17 d41d0a9d Andreas Kohlbecker
import java.util.Map;
18
import java.util.Set;
19 bad845a9 Andreas Müller
import java.util.UUID;
20 dd4317ec Andreas Müller
import java.util.stream.Collectors;
21 bad845a9 Andreas Müller
22
import javax.servlet.http.HttpServletRequest;
23
import javax.servlet.http.HttpServletResponse;
24
25
import org.springframework.beans.factory.annotation.Autowired;
26 d68e1b58 Andreas Müller
import org.springframework.beans.factory.annotation.Qualifier;
27 bad845a9 Andreas Müller
import org.springframework.stereotype.Controller;
28
import org.springframework.web.bind.WebDataBinder;
29
import org.springframework.web.bind.annotation.InitBinder;
30 d41d0a9d Andreas Kohlbecker
import org.springframework.web.bind.annotation.PathVariable;
31 bad845a9 Andreas Müller
import org.springframework.web.bind.annotation.RequestMapping;
32
import org.springframework.web.bind.annotation.RequestMethod;
33
import org.springframework.web.bind.annotation.RequestParam;
34
import org.springframework.web.servlet.ModelAndView;
35
36 d41d0a9d Andreas Kohlbecker
import com.fasterxml.jackson.core.JsonParseException;
37
import com.fasterxml.jackson.databind.JsonMappingException;
38 bad845a9 Andreas Müller
39 d68e1b58 Andreas Müller
import eu.etaxonomy.cdm.api.application.ICdmRepository;
40 bad845a9 Andreas Müller
import eu.etaxonomy.cdm.api.service.IDescriptionService;
41
import eu.etaxonomy.cdm.api.service.ITermService;
42 5454a90f Andreas Kohlbecker
import eu.etaxonomy.cdm.api.service.IVocabularyService;
43 5ee7595c Andreas Müller
import eu.etaxonomy.cdm.api.service.description.AggregationMode;
44 7ef0f93e Andreas Müller
import eu.etaxonomy.cdm.api.service.description.DistributionAggregation;
45 3bab771f Andreas Müller
import eu.etaxonomy.cdm.api.service.description.DistributionAggregationConfiguration;
46 d41d0a9d Andreas Kohlbecker
import eu.etaxonomy.cdm.api.service.dto.DistributionInfoDTO;
47
import eu.etaxonomy.cdm.api.service.dto.DistributionInfoDTO.InfoPart;
48 06e67090 Andreas Müller
import eu.etaxonomy.cdm.api.service.l10n.LocaleContext;
49 bad845a9 Andreas Müller
import eu.etaxonomy.cdm.api.service.pager.Pager;
50 989daf68 Andreas Müller
import eu.etaxonomy.cdm.api.util.DistributionOrder;
51 9b7db8db Andreas Kohlbecker
import eu.etaxonomy.cdm.common.JvmLimitsException;
52
import eu.etaxonomy.cdm.common.monitor.IRestServiceProgressMonitor;
53 dd4317ec Andreas Müller
import eu.etaxonomy.cdm.ext.geo.CondensedDistributionConfiguration;
54 d41d0a9d Andreas Kohlbecker
import eu.etaxonomy.cdm.ext.geo.CondensedDistributionRecipe;
55
import eu.etaxonomy.cdm.ext.geo.EditGeoServiceUtilities;
56
import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
57 6be3adaa Andreas Müller
import eu.etaxonomy.cdm.filter.TaxonNodeFilter;
58 d41d0a9d Andreas Kohlbecker
import eu.etaxonomy.cdm.model.common.MarkerType;
59 bad845a9 Andreas Müller
import eu.etaxonomy.cdm.model.description.DescriptionBase;
60 d41d0a9d Andreas Kohlbecker
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
61 bad845a9 Andreas Müller
import eu.etaxonomy.cdm.model.location.NamedArea;
62
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
63
import eu.etaxonomy.cdm.model.location.NamedAreaType;
64
import eu.etaxonomy.cdm.model.name.Rank;
65
import eu.etaxonomy.cdm.persistence.dto.TermDto;
66
import eu.etaxonomy.cdm.persistence.query.OrderHint;
67
import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;
68
import eu.etaxonomy.cdm.remote.controller.util.ProgressMonitorUtil;
69
import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
70
import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
71 dc3fd428 Andreas Kohlbecker
import eu.etaxonomy.cdm.remote.editor.TermBasePropertyEditor;
72 9d192006 Andreas Müller
import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;
73 3b1c92ca Andreas Müller
import eu.etaxonomy.cdm.remote.editor.UuidList;
74 7ef0f93e Andreas Müller
import io.swagger.annotations.Api;
75 bad845a9 Andreas Müller
76
/**
77
 * TODO write controller documentation
78
 *
79
 * @author a.kohlbecker
80 7fa325bc Andreas Müller
 * @since 24.03.2009
81 bad845a9 Andreas Müller
 */
82
@Controller
83
@Api("description")
84
@RequestMapping(value = {"/description"})
85 8bbb7d89 Andreas Müller
public class DescriptionListController
86
        extends AbstractIdentifiableListController<DescriptionBase, IDescriptionService> {
87 bad845a9 Andreas Müller
88
    @Autowired
89
    private ITermService termService;
90
91 5454a90f Andreas Kohlbecker
    @Autowired
92
    private IVocabularyService vocabularyService ;
93
94 d41d0a9d Andreas Kohlbecker
    @Autowired
95
    private IEditGeoService geoService;
96 bad845a9 Andreas Müller
97 8bbb7d89 Andreas Müller
    @Autowired
98 d68e1b58 Andreas Müller
    @Qualifier("cdmRepository")
99
    private ICdmRepository repository;
100 bad845a9 Andreas Müller
101
    @Autowired
102
    public ProgressMonitorController progressMonitorController;
103
104
    protected static final List<String> DESCRIPTION_ELEMENT_INIT_STRATEGY = Arrays.asList(new String []{
105
            "$",
106
            "multilanguageText",
107
    });
108
109
    /**
110
     * There should only be one longtime processes
111
     * therefore the according progress monitor uuid is stored in
112
     * this static field.
113
     */
114
    private static UUID transmissionEngineMonitorUuid = null;
115
116
117
    @Override
118
    @Autowired
119
    public void setService(IDescriptionService service) {
120
        this.service = service;
121
    }
122
123
    @InitBinder
124
    @Override
125
    public void initBinder(WebDataBinder binder) {
126
        super.initBinder(binder);
127 029fa839 Andreas Müller
        binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<>(termService));
128
        binder.registerCustomEditor(NamedAreaLevel.class, new TermBasePropertyEditor<>(termService));
129
        binder.registerCustomEditor(Rank.class, new TermBasePropertyEditor<>(termService));
130 9d192006 Andreas Müller
        binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
131 bad845a9 Andreas Müller
    }
132
133 d41d0a9d Andreas Kohlbecker
    protected List<String> getDescriptionInfoInitStrategy(){
134
        return getInitializationStrategy();
135
    }
136
137 bad845a9 Andreas Müller
    /**
138 7ef0f93e Andreas Müller
     * Runs the {@link DistributionAggregation} in a separate Thread and
139 bad845a9 Andreas Müller
     * responds with a redirect to a progress monitor REST service end point.
140
     * <p>
141
     *
142
     * @param mode
143 dc3fd428 Andreas Kohlbecker
     *      one of <code>byAreas</code>, <code>byRanks</code>,
144
     *      <code>byAreasAndRanks</code>
145 bad845a9 Andreas Müller
     * @param frontendBaseUrl
146 dc3fd428 Andreas Kohlbecker
     *      the cdm server instance base URL, this is needed for the a
147
     *      proper redirect URL when the service is running behind a
148
     *      reverse HTTP proxy
149 bad845a9 Andreas Müller
     * @param priority
150 dc3fd428 Andreas Kohlbecker
     *      the priority for the Thread to spawn, see
151
     *      {@link Thread#setPriority(int)}, defaults to 3
152
     * @param targetAreaLevel
153
     *      The level of target areas to project the distributions to.
154
     * @param lowerRank
155
     * @param upperRank
156
     *
157 bad845a9 Andreas Müller
     * @param request
158
     * @param response
159
     * @return
160
     * @throws IOException
161
     */
162
    @RequestMapping(value = { "accumulateDistributions" }, method = RequestMethod.GET)
163
    public ModelAndView doAccumulateDistributions(
164 b37495b9 Andreas Müller
            @RequestParam(value= "mode", required = true) AggregationMode mode,
165
            @RequestParam(value= "mode2", required = true) AggregationMode mode2,
166 58ea183c Andreas Müller
            @RequestParam(value = "targetAreaLevel", required = true) UUID targetAreaLevelUuid,
167 bad845a9 Andreas Müller
            @RequestParam(value = "frontendBaseUrl", required = false) String frontendBaseUrl,
168 f4c1a988 Andreas Müller
            @RequestParam(value = "priority", required = false, defaultValue="3") Integer priority,
169 3b1c92ca Andreas Müller
//            @RequestParam(value = "lowerRank", required = false) Rank lowerRank,
170
//            @RequestParam(value = "upperRank", required = false) Rank upperRank,
171 9d192006 Andreas Müller
            @RequestParam(value = "minRank", required = false) UUID lowerRank,
172 58ea183c Andreas Müller
            @RequestParam(value = "maxRank", required = false) UUID upperRank,
173
            @RequestParam(value = "subtrees", required = false) UuidList subtreeUuids,
174
            @RequestParam(value = "classifications", required = false) UuidList classificationUuids,
175
            @RequestParam(value = "taxa", required = false) UuidList taxonUuids,
176
            @RequestParam(value = "taxonnodes", required = false) UuidList taxonNodeUuids,
177
//            @RequestParam(value = "includeUnpublished", defaultValue="false") Boolean includeUnpublished,  //for now we do not allow unpublished data to be exported via webservice as long as read authentication is not implemented
178
//            @RequestParam(value = "area", required = false) UuidList areaUuids,
179 bad845a9 Andreas Müller
            HttpServletRequest request,
180
            HttpServletResponse response) throws IOException {
181
182
        logger.info("doAccumulateDistributions()" + request.getRequestURI());
183
184
        String processLabel = "accumulating distributions";
185
186
        ProgressMonitorUtil progressUtil = new ProgressMonitorUtil(progressMonitorController);
187
188
        final List<String> term_init_strategy = Arrays.asList(new String []{
189
                "representations"
190
        });
191 58ea183c Andreas Müller
        NamedAreaLevel targetAreaLevel = (NamedAreaLevel)termService.load(targetAreaLevelUuid, term_init_strategy);
192 bad845a9 Andreas Müller
193
        if (!progressMonitorController.isMonitorRunning(transmissionEngineMonitorUuid)) {
194
            transmissionEngineMonitorUuid = progressUtil.registerNewMonitor();
195
            Thread subThread = new Thread() {
196
                @Override
197
                public void run() {
198 dc3fd428 Andreas Kohlbecker
                    Pager<NamedArea> areaPager = termService.list(targetAreaLevel, (NamedAreaType) null,
199 bad845a9 Andreas Müller
                            null, null, (List<OrderHint>) null, term_init_strategy);
200 9b7db8db Andreas Kohlbecker
                    try {
201 7841cf62 Andreas Müller
                        TaxonNodeFilter filter = TaxonNodeFilter.NewInstance(classificationUuids, subtreeUuids,
202
                                taxonNodeUuids, taxonUuids, null, lowerRank, upperRank);
203 b37495b9 Andreas Müller
                        List<AggregationMode> modes = Arrays.asList(new AggregationMode[]{mode, mode2});
204
                        modes.remove(null);
205 feebef03 Andreas Müller
                        List<UUID> areaUuids = new ArrayList<>();
206 ff7c0745 Katja Luther
                        areaPager.getRecords().forEach(p ->areaUuids.add(p.getUuid()));
207 3bab771f Andreas Müller
                        DistributionAggregationConfiguration config = DistributionAggregationConfiguration.NewInstance(
208 ff7c0745 Katja Luther
                                modes, areaUuids, filter, progressMonitorController.getMonitor(transmissionEngineMonitorUuid));
209 3bab771f Andreas Müller
                        DistributionAggregation distrAggr = new DistributionAggregation();
210
                        distrAggr.invoke(config, repository);
211 9b7db8db Andreas Kohlbecker
                    } catch (JvmLimitsException e) {
212
                        IRestServiceProgressMonitor monitor = progressMonitorController.getMonitor(transmissionEngineMonitorUuid);
213
                        monitor.setIsFailed(true);
214
                        monitor.setFeedback(e);
215
                    }
216 bad845a9 Andreas Müller
                }
217
            };
218
            if(priority == null) {
219
                priority = AbstractController.DEFAULT_BATCH_THREAD_PRIORITY;
220
            }
221
            subThread.setPriority(priority);
222
            subThread.start();
223
        }
224
225
        // send redirect "see other"
226 1a5de38d Andreas Kohlbecker
        return progressUtil.respondWithMonitor(frontendBaseUrl, processLabel, transmissionEngineMonitorUuid, false, request, response);
227 bad845a9 Andreas Müller
    }
228
229 d41d0a9d Andreas Kohlbecker
    @RequestMapping(value = "namedAreasInUse", method = RequestMethod.GET)
230
    public Pager<TermDto> doPageNamedAreasInUse(
231
            @RequestParam(value = "includeAllParents", required = false) boolean includeAllParents,
232 bad845a9 Andreas Müller
            @RequestParam(value = "pageSize", required = false) Integer pageSize,
233
            @RequestParam(value = "pageNumber", required = false) Integer pageNumber, HttpServletRequest request,
234
            HttpServletResponse response) throws IOException {
235
236 d41d0a9d Andreas Kohlbecker
        logger.info("doPageNamedAreasInUse : " + requestPathAndQuery(request));
237 bad845a9 Andreas Müller
238
        PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);
239
        pagerParams.normalizeAndValidate(response);
240
241 d41d0a9d Andreas Kohlbecker
        Pager<TermDto> pager = service.pageNamedAreasInUse(includeAllParents, pagerParams.getPageSize(), pagerParams.getPageIndex());
242 bad845a9 Andreas Müller
243 d41d0a9d Andreas Kohlbecker
        localizeTerms(pager);
244 bad845a9 Andreas Müller
245
        return pager;
246
    }
247
248
    /**
249 d41d0a9d Andreas Kohlbecker
     * @param taxonUuid
250
     * @param parts
251
     *            possible values: condensedStatus, tree, mapUriParams,
252
     *            elements,
253
     * @param subAreaPreference
254
     * @param statusOrderPreference
255
     * @param hideMarkedAreasList
256
     * @param omitLevels
257 bad845a9 Andreas Müller
     * @param request
258
     * @param response
259 68c48c6a Andreas Kohlbecker
     * @param distributionOrder
260
     *  Default is  LABEL
261 d41d0a9d Andreas Kohlbecker
     * @param recipe
262
     *  The recipe for creating the condensed distribution status
263 bad845a9 Andreas Müller
     * @return
264
     * @throws IOException
265 d41d0a9d Andreas Kohlbecker
     * @throws JsonMappingException
266
     * @throws JsonParseException
267 bad845a9 Andreas Müller
     */
268 d41d0a9d Andreas Kohlbecker
    @RequestMapping(value = "distributionInfoFor/{uuid}", method = RequestMethod.GET)
269
    public ModelAndView doGetDistributionInfo(
270
            @PathVariable("uuid") UUID taxonUuid,
271
            @RequestParam("part") Set<InfoPart> partSet,
272
            @RequestParam(value = "subAreaPreference", required = false) boolean subAreaPreference,
273
            @RequestParam(value = "statusOrderPreference", required = false) boolean statusOrderPreference,
274 dd4317ec Andreas Müller
            @RequestParam(value = "hiddenAreaMarkerType", required = false) DefinedTermBaseList<MarkerType> hiddenAreaMarkerTypeList,
275 d41d0a9d Andreas Kohlbecker
            @RequestParam(value = "omitLevels", required = false) Set<NamedAreaLevel> omitLevels,
276
            @RequestParam(value = "statusColors", required = false) String statusColorsString,
277 68c48c6a Andreas Kohlbecker
            @RequestParam(value = "distributionOrder", required = false, defaultValue="LABEL") DistributionOrder distributionOrder,
278 d41d0a9d Andreas Kohlbecker
            @RequestParam(value = "recipe", required = false, defaultValue="EuroPlusMed") CondensedDistributionRecipe recipe,
279
            HttpServletRequest request,
280
            HttpServletResponse response) throws JsonParseException, JsonMappingException, IOException {
281 bad845a9 Andreas Müller
282 d41d0a9d Andreas Kohlbecker
            logger.info("doGetDistributionInfo() - " + requestPathAndQuery(request));
283 bad845a9 Andreas Müller
284 d41d0a9d Andreas Kohlbecker
            ModelAndView mv = new ModelAndView();
285 bad845a9 Andreas Müller
286 e657f466 Andreas Müller
            boolean ignoreDistributionStatusUndefined = true;  //workaround until #9500 is fully implemented
287 c160c389 Andreas Müller
            boolean fallbackAsParent = true;  //may become a service parameter in future
288
289 6e509e8f Andreas Müller
            DistributionInfoDTO dto;
290
            try {
291
                CondensedDistributionConfiguration condensedConfig = recipe.toConfiguration();
292
                //hiddenArea markers include markers for fully hidden areas and fallback areas. The later
293
                //are hidden markers on areas that have non-hidden subareas (#4408)
294
                Set<MarkerType> hiddenAreaMarkerTypes = null;
295
                if(hiddenAreaMarkerTypeList != null && !hiddenAreaMarkerTypeList.isEmpty()){
296
                    hiddenAreaMarkerTypes = hiddenAreaMarkerTypeList.asSet();
297
                    condensedConfig.hiddenAndFallbackAreaMarkers = hiddenAreaMarkerTypeList.stream().map(mt->mt.getUuid()).collect(Collectors.toSet());
298
                }
299 bad845a9 Andreas Müller
300 6e509e8f Andreas Müller
                EnumSet<InfoPart> parts = EnumSet.copyOf(partSet);
301 bad845a9 Andreas Müller
302 6e509e8f Andreas Müller
                Map<PresenceAbsenceTerm, Color> distributionStatusColors = EditGeoServiceUtilities.buildStatusColorMap(
303
                        statusColorsString, termService, vocabularyService);
304 bad845a9 Andreas Müller
305 6e509e8f Andreas Müller
                dto = geoService.composeDistributionInfoFor(parts, taxonUuid,
306
                        subAreaPreference, statusOrderPreference, hiddenAreaMarkerTypes, fallbackAsParent,
307
                        omitLevels, distributionStatusColors, LocaleContext.getLanguages(),
308
                        getDescriptionInfoInitStrategy(), condensedConfig, distributionOrder,
309
                        ignoreDistributionStatusUndefined);
310
                mv.addObject(dto);
311 ba676069 Andreas Müller
                return mv;
312 6e509e8f Andreas Müller
            } catch (Exception e) {
313 ba676069 Andreas Müller
                HttpStatusMessage.create("Exception when retrieving distribution info for " + taxonUuid, 500).send(response);
314
                return null;
315 6e509e8f Andreas Müller
            }
316 bad845a9 Andreas Müller
    }
317 dd4317ec Andreas Müller
}