ref #10334 further handle include unpublished in webservices
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / controller / ext / ExternalGeoController.java
index e0dc917a405dff4e4a2c1ea1820eeecec7550efb..5569ed378c821b99da710ca6925ad77a63160996 100644 (file)
-// $Id$\r
-/**\r
- * Copyright (C) 2009 EDIT\r
- * European Distributed Institute of Taxonomy\r
- * http://www.e-taxonomy.eu\r
- *\r
- * The contents of this file are subject to the Mozilla Public License Version 1.1\r
- * See LICENSE.TXT at the top of this package for the full license terms.\r
- */\r
-package eu.etaxonomy.cdm.remote.controller.ext;\r
-\r
-import java.awt.Color;\r
-import java.io.FileReader;\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.UUID;\r
-\r
-import javax.servlet.http.HttpServletRequest;\r
-import javax.servlet.http.HttpServletResponse;\r
-\r
-import org.apache.log4j.Logger;\r
-import org.springframework.beans.factory.annotation.Autowired;\r
-import org.springframework.stereotype.Controller;\r
-import org.springframework.web.bind.WebDataBinder;\r
-import org.springframework.web.bind.annotation.InitBinder;\r
-import org.springframework.web.bind.annotation.PathVariable;\r
-import org.springframework.web.bind.annotation.RequestMapping;\r
-import org.springframework.web.bind.annotation.RequestMethod;\r
-import org.springframework.web.bind.annotation.RequestParam;\r
-import org.springframework.web.servlet.ModelAndView;\r
-\r
-import eu.etaxonomy.cdm.api.service.IDescriptionService;\r
-import eu.etaxonomy.cdm.api.service.IOccurrenceService;\r
-import eu.etaxonomy.cdm.api.service.ITaxonService;\r
-import eu.etaxonomy.cdm.api.service.ITermService;\r
-import eu.etaxonomy.cdm.api.service.pager.Pager;\r
-import eu.etaxonomy.cdm.api.service.util.TaxonRelationshipEdge;\r
-import eu.etaxonomy.cdm.api.utility.DescriptionUtility;\r
-import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;\r
-import eu.etaxonomy.cdm.ext.geo.IEditGeoService;\r
-import eu.etaxonomy.cdm.model.common.DefinedTerm;\r
-import eu.etaxonomy.cdm.model.common.Language;\r
-import eu.etaxonomy.cdm.model.common.Marker;\r
-import eu.etaxonomy.cdm.model.common.MarkerType;\r
-import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;\r
-import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
-import eu.etaxonomy.cdm.model.location.NamedArea;\r
-import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;\r
-import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;\r
-import eu.etaxonomy.cdm.model.taxon.Taxon;\r
-import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
-import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
-import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;\r
-import eu.etaxonomy.cdm.remote.controller.BaseController;\r
-import eu.etaxonomy.cdm.remote.controller.util.ControllerUtils;\r
-import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;\r
-import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;\r
-import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;\r
-import eu.etaxonomy.cdm.remote.editor.UuidList;\r
-import eu.etaxonomy.cdm.remote.l10n.LocaleContext;\r
-\r
-/**\r
- * The ExternalGeoController class is a Spring MVC Controller.\r
- * <p>\r
- * The syntax of the mapped service URIs contains the the {datasource-name} path element.\r
- * The available {datasource-name}s are defined in a configuration file which\r
- * is loaded by the {@link UpdatableRoutingDataSource}. If the\r
- * UpdatableRoutingDataSource is not being used in the actual application\r
- * context any arbitrary {datasource-name} may be used.\r
- * <p>\r
- * @author a.kohlbecker\r
- * @date 18.06.2009\r
- *\r
- */\r
-@Controller\r
-@RequestMapping(value = { "ext/edit/mapServiceParameters/" })\r
-public class ExternalGeoController extends BaseController<TaxonBase, ITaxonService> {\r
-\r
-    public static final Logger logger = Logger.getLogger(ExternalGeoController.class);\r
-\r
-    @Autowired\r
-    private IEditGeoService geoservice;\r
-\r
-    @Autowired\r
-    private IDescriptionService descriptionService;\r
-\r
-    @Autowired\r
-    private IOccurrenceService occurrenceService;\r
-\r
-    @Autowired\r
-    private ITermService termService;\r
-\r
-    @InitBinder\r
-    @Override\r
-    public void initBinder(WebDataBinder binder) {\r
-        super.initBinder(binder);\r
-        binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());\r
-        binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<MarkerType>(termService));\r
-    }\r
-\r
-    @Autowired\r
-    @Override\r
-    public void setService(ITaxonService service) {\r
-        this.service = service;\r
-    }\r
-\r
-    /**\r
-     * Assembles and returns URI parameter Strings for the EDIT Map Service. The distribution areas for the\r
-     * {@link Taxon} instance identified by the <code>{taxon-uuid}</code> are found and are translated into\r
-     * an valid URI parameter String. Higher level distribution areas are expanded in order to include all\r
-     * nested sub-areas.\r
-     * <p>\r
-     * URI: <b>&#x002F;{datasource-name}&#x002F;geo&#x002F;map&#x002F;distribution&#x002F;{taxon-uuid}</b>\r
-     *\r
-     *\r
-     * @param subAreaPreference\r
-     *            enables the <b>Sub area preference rule</b> if set to true,\r
-     *            see {@link DescriptionUtility#filterDistributions(Collection, boolean, boolean}\r
-     * @param statusOrderPreference\r
-     *            enables the <b>Status order preference rule</b> if set to true,\r
-     *            see {@link DescriptionUtility#filterDistributions(Collection, boolean, boolean}\r
-     * @param hideMarkedAreas\r
-     *            comma separated list of {@link MarkerType} uuids,\r
-     *            distributions where the area has a {@link Marker} with one of\r
-     *            the specified {@link MarkerType}s will be skipped, see\r
-     *            {@link DescriptionUtility#filterDistributions(Collection, boolean, boolean, Set)}\r
-     * @param request\r
-     * @param response\r
-     * @return URI parameter Strings for the EDIT Map Service\r
-     * @throws IOException\r
-     */\r
-    @RequestMapping(value = { "taxonDistributionFor/{uuid}" }, method = RequestMethod.GET)\r
-    public ModelAndView doGetDistributionMapUriParams(\r
-            @PathVariable("uuid") UUID uuid,\r
-            @RequestParam(value = "subAreaPreference", required = false) boolean subAreaPreference,\r
-            @RequestParam(value = "statusOrderPreference", required = false) boolean statusOrderPreference,\r
-            @RequestParam(value = "hideMarkedAreas", required = false) DefinedTermBaseList<MarkerType> hideMarkedAreasList,\r
-            HttpServletRequest request,\r
-            HttpServletResponse response)\r
-            throws IOException {\r
-\r
-        logger.info("doGetDistributionMapUriParams() " + request.getRequestURI());\r
-        ModelAndView mv = new ModelAndView();\r
-\r
-        // get the descriptions for the taxon\r
-        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);\r
-\r
-        Map<PresenceAbsenceTerm, Color> presenceAbsenceTermColors = null;\r
-        //languages\r
-        List<Language> langs = LocaleContext.getLanguages();\r
-\r
-        Set<MarkerType> hideMarkedAreas = null;\r
-        if(hideMarkedAreasList != null){\r
-            hideMarkedAreas = hideMarkedAreasList.asSet();\r
-        }\r
-\r
-        Set<DefinedTerm> scopes = null;\r
-        Set<NamedArea> geographicalScope = null;\r
-        Integer pageSize = null;\r
-        Integer pageNumber = null;\r
-        List<String> propertyPaths = null;\r
-        Pager<TaxonDescription> page = descriptionService.pageTaxonDescriptions(taxon, scopes, geographicalScope, pageSize, pageNumber, propertyPaths);\r
-\r
-        List<TaxonDescription> taxonDescriptions = page.getRecords();\r
-        String uriParams = geoservice.getDistributionServiceRequestParameterString(taxonDescriptions,\r
-                subAreaPreference, statusOrderPreference,\r
-                hideMarkedAreas, presenceAbsenceTermColors, langs);\r
-        mv.addObject(uriParams);\r
-\r
-        return mv;\r
-    }\r
-\r
-\r
-    /**\r
-     * Assembles and returns URI parameter Strings for the EDIT Map Service. The distribution areas for the\r
-     * {@link Taxon} instance identified by the <code>{taxon-uuid}</code> are found and are translated into\r
-     * an valid URI parameter String. Higher level distribution areas are expanded in order to include all\r
-     * nested sub-areas.\r
-     * <p>\r
-     * URI: <b>&#x002F;{datasource-name}&#x002F;geo&#x002F;map&#x002F;distribution&#x002F;{taxon-uuid}</b>\r
-     *\r
-     * @param request\r
-     * @param response\r
-     * @return URI parameter Strings for the EDIT Map Service\r
-     * @throws IOException TODO write controller method documentation\r
-     */\r
-    @RequestMapping(value = { "taxonOccurrencesFor/{uuid}" }, method = RequestMethod.GET)\r
-    public ModelAndView doGetOccurrenceMapUriParams(\r
-            @PathVariable("uuid") UUID uuid,\r
-            @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,\r
-            @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,\r
-            @RequestParam(value = "maxDepth", required = false) Integer maxDepth,\r
-            HttpServletRequest request,\r
-            HttpServletResponse response)\r
-            throws IOException {\r
-\r
-        Map<SpecimenOrObservationType, Color> specimenOrObservationTypeColors = null;\r
-\r
-        logger.info("doGetOccurrenceMapUriParams() " + requestPathAndQuery(request));\r
-        ModelAndView mv = new ModelAndView();\r
-\r
-        Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(\r
-                relationshipUuids, relationshipInversUuids, termService);\r
-\r
-        Taxon taxon = getCdmBaseInstance(Taxon.class, uuid, response, (List<String>)null);\r
-\r
-        List<OrderHint> orderHints = new ArrayList<OrderHint>();\r
-        orderHints.add(new OrderHint("titleCache", SortOrder.DESCENDING));\r
-\r
-        List<SpecimenOrObservationBase> specimensOrObersvations = occurrenceService.listByAssociatedTaxon(\r
-                null, includeRelationships, taxon, maxDepth, null, null, orderHints, null);\r
-\r
-        String uriParams = geoservice.getOccurrenceServiceRequestParameterString(specimensOrObersvations,\r
-                specimenOrObservationTypeColors );\r
-        mv.addObject(uriParams);\r
-        return mv;\r
-    }\r
-\r
-    /**\r
-     * EXPERIMENTAL !!!!!\r
-     * DO NOT USE   !!!!!\r
-     *\r
-     * @param vocabUuid\r
-     * @param request\r
-     * @param response\r
-     * @return\r
-     * @throws IOException\r
-     *\r
-     * @author a.kohlbecker\r
-     */\r
-    @RequestMapping(value = { "mapShapeFileToNamedAreas" }, method = RequestMethod.GET)\r
-    public ModelAndView doMapShapeFileToNamedAreas(\r
-            @RequestParam(required=false, value="vocabularyUuid") UUID vocabUuid,\r
-            @RequestParam(required=false, value="namedAreaUuids") UuidList namedAreaUuids,\r
-            @RequestParam(required=true, value="localFile") String localFile,\r
-            @RequestParam(required=true, value="idSearchField") List<String> idSearchFields,\r
-            @RequestParam(required=true, value="wmsLayerName") String wmsLayerName,\r
-            HttpServletRequest request,\r
-            HttpServletResponse response)\r
-            throws IOException {\r
-\r
-        logger.info("doMapShapeFileToNamedAreas() " + requestPathAndQuery(request));\r
-        ModelAndView mv = new ModelAndView();\r
-\r
-        FileReader reader = new FileReader(localFile);\r
-\r
-        Set<UUID> areaUuidSet = null;\r
-        if(namedAreaUuids != null) {\r
-            areaUuidSet = namedAreaUuids.asSet();\r
-        }\r
-        Map<NamedArea, String> resultMap = geoservice.mapShapeFileToNamedAreas(\r
-                reader, idSearchFields , wmsLayerName , vocabUuid, areaUuidSet);\r
-        Map<String, String> flatResultMap = new HashMap<String, String>(resultMap.size());\r
-        for(NamedArea area : resultMap.keySet()){\r
-            flatResultMap.put(area.getTitleCache() + " [" + area.getUuid() + "]", resultMap.get(area));\r
-        }\r
-        mv.addObject(flatResultMap);\r
-        return mv;\r
-\r
-    }\r
-\r
-\r
-}\r
+/**
+ * Copyright (C) 2009 EDIT
+ * European Distributed Institute of Taxonomy
+ * http://www.e-taxonomy.eu
+ *
+ * The contents of this file are subject to the Mozilla Public License Version 1.1
+ * See LICENSE.TXT at the top of this package for the full license terms.
+ */
+package eu.etaxonomy.cdm.remote.controller.ext;
+
+import java.awt.Color;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.ModelAndView;
+
+import eu.etaxonomy.cdm.api.service.IDescriptionService;
+import eu.etaxonomy.cdm.api.service.IOccurrenceService;
+import eu.etaxonomy.cdm.api.service.ITaxonService;
+import eu.etaxonomy.cdm.api.service.ITermService;
+import eu.etaxonomy.cdm.api.service.geo.IDistributionService;
+import eu.etaxonomy.cdm.api.util.TaxonRelationshipEdge;
+import eu.etaxonomy.cdm.database.UpdatableRoutingDataSource;
+import eu.etaxonomy.cdm.ext.geo.EditGeoServiceUtilities;
+import eu.etaxonomy.cdm.ext.geo.IEditGeoService;
+import eu.etaxonomy.cdm.ext.geo.OccurrenceServiceRequestParameterDto;
+import eu.etaxonomy.cdm.model.common.MarkerType;
+import eu.etaxonomy.cdm.model.location.NamedArea;
+import eu.etaxonomy.cdm.model.location.Point;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
+import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;
+import eu.etaxonomy.cdm.persistence.query.OrderHint;
+import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;
+import eu.etaxonomy.cdm.remote.controller.BaseController;
+import eu.etaxonomy.cdm.remote.controller.util.ControllerUtils;
+import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;
+import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;
+import eu.etaxonomy.cdm.remote.editor.UUIDListPropertyEditor;
+import eu.etaxonomy.cdm.remote.editor.UuidList;
+import io.swagger.annotations.Api;
+
+/**
+ * The ExternalGeoController class is a Spring MVC Controller.
+ * <p>
+ * The syntax of the mapped service URIs contains the the {datasource-name} path element.
+ * The available {datasource-name}s are defined in a configuration file which
+ * is loaded by the {@link UpdatableRoutingDataSource}. If the
+ * UpdatableRoutingDataSource is not being used in the actual application
+ * context any arbitrary {datasource-name} may be used.
+ * <p>
+ * @author a.kohlbecker
+ * @since 18.06.2009
+ *
+ */
+
+@Controller
+@Api(value="mapServiceParameters")
+@RequestMapping(value = { "ext/edit/mapServiceParameters/" })
+public class ExternalGeoController extends BaseController<TaxonBase, ITaxonService> {
+
+    private static final Logger logger = LogManager.getLogger();
+
+    @Autowired
+    private IEditGeoService geoService;
+
+    @Autowired
+    private IDistributionService distributionService;
+
+    @Autowired
+    private IDescriptionService descriptionService;
+
+    @Autowired
+    private IOccurrenceService occurrenceService;
+
+    @Autowired
+    private ITermService termService;
+
+    @InitBinder
+    @Override
+    public void initBinder(WebDataBinder binder) {
+        super.initBinder(binder);
+        binder.registerCustomEditor(UuidList.class, new UUIDListPropertyEditor());
+        binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<MarkerType>(termService));
+    }
+
+    @Autowired
+    @Override
+    public void setService(ITaxonService service) {
+        this.service = service;
+    }
+
+    /**
+     * Assembles and returns URI parameter Strings for the EDIT Map Service. The distribution areas for the
+     * {@link Taxon} instance identified by the <code>{taxon-uuid}</code> are found and are translated into
+     * an valid URI parameter String. Higher level distribution areas are expanded in order to include all
+     * nested sub-areas.
+     * <p>
+     * URI: <b>&#x002F;{datasource-name}&#x002F;geo&#x002F;map&#x002F;distribution&#x002F;{taxon-uuid}</b>
+     *
+     * @param request
+     * @param response
+     * @return URI parameter Strings for the EDIT Map Service
+     * @throws IOException TODO write controller method documentation
+     */
+    @RequestMapping(value = { "taxonOccurrencesFor/{uuid}" }, method = RequestMethod.GET)
+    public OccurrenceServiceRequestParameterDto doGetOccurrenceMapUriParams(
+            @PathVariable("uuid") UUID uuid,
+            @RequestParam(value = "relationships", required = false) UuidList relationshipUuids,
+            @RequestParam(value = "relationshipsInvers", required = false) UuidList relationshipInversUuids,
+            @RequestParam(value = "maxDepth", required = false) Integer maxDepth,
+            HttpServletRequest request,
+            HttpServletResponse response)
+            throws IOException {
+
+        logger.info("doGetOccurrenceMapUriParams() " + requestPathAndQuery(request));
+        boolean includeUnpublished = NO_UNPUBLISHED;
+
+        Map<SpecimenOrObservationType, Color> specimenOrObservationTypeColors = null;
+
+        List<SpecimenOrObservationBase> specimensOrObersvations = occurencesForTaxon(uuid, relationshipUuids,
+                               relationshipInversUuids, includeUnpublished, maxDepth, response);
+
+        OccurrenceServiceRequestParameterDto dto = geoService.getOccurrenceServiceRequestParameters(specimensOrObersvations,
+                specimenOrObservationTypeColors );
+
+        return dto;
+    }
+
+       private List<SpecimenOrObservationBase> occurencesForTaxon(UUID taxonUuid, UuidList relationshipUuids,
+                       UuidList relationshipInversUuids, boolean includeUnpublished, Integer maxDepth,
+                       HttpServletResponse response) throws IOException {
+
+           Set<TaxonRelationshipEdge> includeRelationships = ControllerUtils.loadIncludeRelationships(
+                relationshipUuids, relationshipInversUuids, termService);
+
+        Taxon taxon = getCdmBaseInstance(Taxon.class, taxonUuid, response, (List<String>)null);
+
+        List<OrderHint> orderHints = new ArrayList<>();
+        orderHints.add(new OrderHint("titleCache", SortOrder.DESCENDING));
+
+        List<SpecimenOrObservationBase> specimensOrObersvations = occurrenceService.listByAssociatedTaxon(
+                null, includeRelationships, taxon, includeUnpublished, maxDepth, null, null, orderHints, null);
+               return specimensOrObersvations;
+       }
+
+    /**
+     * Assembles and returns URI parameter Strings for the EDIT Map Service. The distribution areas for the
+     * {@link Taxon} instance identified by the <code>{taxon-uuid}</code> are found and are translated into
+     * an valid URI parameter String. Higher level distribution areas are expanded in order to include all
+     * nested sub-areas.
+     * <p>
+     * URI: <b>&#x002F;{datasource-name}&#x002F;geo&#x002F;map&#x002F;distribution&#x002F;{taxon-uuid}</b>
+     *
+     * @param request
+     * @param response
+     * @return URI parameter Strings for the EDIT Map Service
+     * @throws IOException TODO write controller method documentation
+     */
+    @RequestMapping(value = { "taxonOccurrencesForX" }, method = RequestMethod.GET)
+    public ModelAndView doGetOccurrenceXMapUriParams(
+            @RequestParam(value = "fieldUnitUuidList", required = false) UuidList fieldUnitUuids,
+            HttpServletRequest request,
+            HttpServletResponse response)
+            throws IOException {
+
+        Map<SpecimenOrObservationType, Color> specimenOrObservationTypeColors = null;
+
+        logger.info("doGetOccurrenceMapUriParams() " + requestPathAndQuery(request));
+        ModelAndView mv = new ModelAndView();
+
+        List<Point> fieldUnitPoints = occurrenceService.findPointsForFieldUnitList(fieldUnitUuids);
+
+        OccurrenceServiceRequestParameterDto dto = EditGeoServiceUtilities.getOccurrenceServiceRequestParameterString(fieldUnitPoints,
+                null, specimenOrObservationTypeColors);
+        mv.addObject(dto);
+        return mv;
+    }
+
+    /**
+     * EXPERIMENTAL !!!!!
+     * DO NOT USE   !!!!!
+     *
+     * @param vocabUuid
+     * @param request
+     * @param response
+     * @return
+     * @throws IOException
+     *
+     * @author a.kohlbecker
+     */
+    @RequestMapping(value = { "mapShapeFileToNamedAreas" }, method = RequestMethod.GET)
+    public ModelAndView doMapShapeFileToNamedAreas(
+            @RequestParam(required=false, value="vocabularyUuid") UUID vocabUuid,
+            @RequestParam(required=false, value="namedAreaUuids") UuidList namedAreaUuids,
+            @RequestParam(required=true, value="localFile") String localFile,
+            @RequestParam(required=true, value="idSearchField") List<String> idSearchFields,
+            @RequestParam(required=true, value="wmsLayerName") String wmsLayerName,
+            HttpServletRequest request,
+            HttpServletResponse response)
+            throws IOException {
+
+        logger.info("doMapShapeFileToNamedAreas() " + requestPathAndQuery(request));
+        ModelAndView mv = new ModelAndView();
+
+        FileReader reader = new FileReader(localFile);
+
+        Set<UUID> areaUuidSet = null;
+        if(namedAreaUuids != null) {
+            areaUuidSet = namedAreaUuids.asSet();
+        }
+        Map<NamedArea, String> resultMap = distributionService.mapShapeFileToNamedAreas(
+                reader, idSearchFields , wmsLayerName , vocabUuid, areaUuidSet);
+        Map<String, String> flatResultMap = new HashMap<String, String>(resultMap.size());
+        for(NamedArea area : resultMap.keySet()){
+            flatResultMap.put(area.getTitleCache() + " [" + area.getUuid() + "]", resultMap.get(area));
+        }
+        mv.addObject(flatResultMap);
+        return mv;
+
+    }
+
+
+}