/**\r
* Copyright (C) 2009 EDIT European Distributed Institute of Taxonomy\r
* http://www.e-taxonomy.eu\r
- * \r
+ *\r
* The contents of this file are subject to the Mozilla Public License Version\r
* 1.1 See LICENSE.TXT at the top of this package for the full license terms.\r
*/\r
import java.io.IOException;\r
import java.util.Arrays;\r
import java.util.List;\r
+import java.util.UUID;\r
\r
import javax.servlet.http.HttpServletRequest;\r
import javax.servlet.http.HttpServletResponse;\r
\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.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.ITaxonService;\r
+import eu.etaxonomy.cdm.api.service.ITermService;\r
+import eu.etaxonomy.cdm.api.service.description.TransmissionEngineDistribution;\r
+import eu.etaxonomy.cdm.api.service.description.TransmissionEngineDistribution.AggregationMode;\r
+import eu.etaxonomy.cdm.api.service.pager.Pager;\r
import eu.etaxonomy.cdm.model.description.DescriptionBase;\r
-import eu.etaxonomy.cdm.model.description.FeatureTree;\r
+import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
+import eu.etaxonomy.cdm.model.description.Feature;\r
+import eu.etaxonomy.cdm.model.location.NamedArea;\r
+import eu.etaxonomy.cdm.model.location.NamedAreaLevel;\r
+import eu.etaxonomy.cdm.model.location.NamedAreaType;\r
+import eu.etaxonomy.cdm.model.name.Rank;\r
+import eu.etaxonomy.cdm.model.taxon.Taxon;\r
+import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
+import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
+import eu.etaxonomy.cdm.remote.controller.util.PagerParameters;\r
+import eu.etaxonomy.cdm.remote.controller.util.ProgressMonitorUtil;\r
+import eu.etaxonomy.cdm.remote.editor.DefinedTermBaseList;\r
+import eu.etaxonomy.cdm.remote.editor.TermBaseListPropertyEditor;\r
\r
/**\r
+ * TODO write controller documentation\r
+ *\r
* @author a.kohlbecker\r
* @date 24.03.2009\r
*/\r
@Controller\r
-@RequestMapping(value = {"/*/description", "/*/featuretree"})\r
-public class DescriptionListController extends BaseListController<DescriptionBase, IDescriptionService> {\r
- \r
- private static final List<String> FEATURETREE_INIT_STRATEGY = Arrays.asList(\r
- new String[]{\r
- "representations",\r
- "root.feature.representations",\r
- "root.children.feature.representations",\r
- });\r
-\r
- /* (non-Javadoc)\r
- * @see eu.etaxonomy.cdm.remote.controller.BaseListController#setService(eu.etaxonomy.cdm.api.service.IService)\r
- */\r
- @Override\r
- @Autowired\r
- public void setService(IDescriptionService service) {\r
- this.service = service;\r
- }\r
- \r
- @RequestMapping(method = RequestMethod.GET, value="/*/featuretree")\r
- public List<FeatureTree> doGetFeatureTrees(HttpServletRequest request, HttpServletResponse response) throws IOException {\r
- \r
- List<FeatureTree> obj = service.getFeatureTreesAll(FEATURETREE_INIT_STRATEGY);\r
- return obj;\r
- }\r
+@RequestMapping(value = {"/description"})\r
+public class DescriptionListController extends IdentifiableListController<DescriptionBase, IDescriptionService> {\r
+\r
+\r
+ @Autowired\r
+ private ITermService termService;\r
+\r
+ @Autowired\r
+ private ITaxonService taxonService;\r
+\r
+\r
+ @Autowired\r
+ public TransmissionEngineDistribution transmissionEngineDistribution;\r
+\r
+ @Autowired\r
+ public ProgressMonitorController progressMonitorController;\r
+\r
+ /**\r
+ * There should only be one longtime processes\r
+ * therefore the according progress monitor uuid is stored in\r
+ * this static field.\r
+ */\r
+ private static UUID transmissionEngineMonitorUuid = null;\r
+\r
+\r
+\r
+ /* (non-Javadoc)\r
+ * @see eu.etaxonomy.cdm.remote.controller.BaseListController#setService(eu.etaxonomy.cdm.api.service.IService)\r
+ */\r
+ @Override\r
+ @Autowired\r
+ public void setService(IDescriptionService service) {\r
+ this.service = service;\r
+ }\r
+\r
+ @InitBinder\r
+ @Override\r
+ public void initBinder(WebDataBinder binder) {\r
+ super.initBinder(binder);\r
+ binder.registerCustomEditor(DefinedTermBaseList.class, new TermBaseListPropertyEditor<Feature>(termService));\r
+ }\r
+\r
+\r
+ /**\r
+ * Runs the {@link TransmissionEngineDistribution} in a separate Thread and\r
+ * responds with a redirect to a progress monitor REST service end point.\r
+ * <p>\r
+ * <b>NOTE</b> this is still a special implementation for the Euro+Med project.\r
+ * The parameters for the <i>superAreas</i>, the areas to which the subordinate areas should be projected,\r
+ * <i>lowerRank</i>, <i>upperRank</i> are hardcoded to: <code>TDWG_LEVEL3 areas, SUBSPECIES, GENUS</code>\r
+ *\r
+ * @param mode\r
+ * one of <code>byAreas</code>, <code>byRanks</code>,\r
+ * <code>byAreasAndRanks</code>\r
+ * @param frontendBaseUrl\r
+ * the cdm server instance base URL, this is needed for the a\r
+ * proper redirect URL when the service is running behind a\r
+ * reverse HTTP proxy\r
+ * @param priority\r
+ * the priority for the Thread to spawn, see\r
+ * {@link Thread#setPriority(int)}, defaults to 3\r
+ * @param request\r
+ * @param response\r
+ * @return\r
+ * @throws IOException\r
+ */\r
+ @RequestMapping(value = { "accumulateDistributions" }, method = RequestMethod.GET)\r
+ public ModelAndView doAccumulateDistributions(\r
+ @RequestParam(value= "mode", required = true) final AggregationMode mode,\r
+ @RequestParam(value = "frontendBaseUrl", required = false) String frontendBaseUrl,\r
+ @RequestParam(value = "priority", required = false) Integer priority,\r
+ HttpServletRequest request,\r
+ HttpServletResponse response) throws IOException {\r
+\r
+ logger.info("doAccumulateDistributions()" + request.getRequestURI());\r
+\r
+// transmissionEngineDistribution.updatePriorities();\r
+\r
+ String processLabel = "accumulating distributions";\r
+\r
+ ProgressMonitorUtil progressUtil = new ProgressMonitorUtil(progressMonitorController);\r
+\r
+ final List<String> term_init_strategy = Arrays.asList(new String []{\r
+ "representations"\r
+ });\r
+\r
+ if (!progressMonitorController.isMonitorRunning(transmissionEngineMonitorUuid)) {\r
+ transmissionEngineMonitorUuid = progressUtil.registerNewMonitor();\r
+ Thread subThread = new Thread() {\r
+ @Override\r
+ public void run() {\r
+ Pager<NamedArea> areaPager = termService.list(NamedAreaLevel.TDWG_LEVEL3(), (NamedAreaType) null,\r
+ null, null, (List<OrderHint>) null, term_init_strategy);\r
+ transmissionEngineDistribution.accumulate(mode, areaPager.getRecords(), Rank.SUBSPECIES(), Rank.GENUS(),\r
+ null, progressMonitorController.getMonitor(transmissionEngineMonitorUuid));\r
+ }\r
+ };\r
+ if(priority == null) {\r
+ priority = AbstractController.DEFAULT_BATCH_THREAD_PRIORITY;\r
+ }\r
+ subThread.setPriority(priority);\r
+ subThread.start();\r
+ }\r
+\r
+ // send redirect "see other"\r
+ return progressUtil.respondWithMonitor(frontendBaseUrl, request, response, processLabel, transmissionEngineMonitorUuid);\r
+ }\r
+\r
+ /**\r
+ *\r
+ * @param queryString\r
+ * @param type\r
+ * @param pageSize\r
+ * @param pageNumber\r
+ * @param matchMode\r
+ * @param request\r
+ * @param response\r
+ * @return\r
+ * @throws IOException\r
+ */\r
+ @RequestMapping(value = "//descriptionElement/find", method = RequestMethod.GET) // mapped as absolute path, see CdmAntPathMatcher\r
+ public Pager<DescriptionElementBase> doFindDescriptionElements(\r
+ @RequestParam(value = "query", required = true) String queryString,\r
+ @RequestParam(value = "type", required = false) Class<? extends DescriptionElementBase> type,\r
+ @RequestParam(value = "pageSize", required = false) Integer pageSize,\r
+ @RequestParam(value = "pageNumber", required = false) Integer pageNumber,\r
+ @RequestParam(value = "matchMode", required = false) MatchMode matchMode,\r
+ HttpServletRequest request,\r
+ HttpServletResponse response\r
+ )\r
+ throws IOException {\r
+\r
+ logger.info("doFindDescriptionElements : " + requestPathAndQuery(request) );\r
+\r
+ PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
+ pagerParams.normalizeAndValidate(response);\r
+\r
+ Pager<DescriptionElementBase> pager = service.searchElements(type, queryString, pageSize, pageNumber, null, getInitializationStrategy());\r
+\r
+ return pager;\r
+ }\r
+\r
+ /**\r
+ * Requires the query parameter "descriptionType" to be present\r
+ *\r
+ * @param features\r
+ * @param descriptionType\r
+ * @param type\r
+ * @param pageSize\r
+ * @param pageNumber\r
+ * @param request\r
+ * @param response\r
+ * @return\r
+ * @throws IOException\r
+ */\r
+ @RequestMapping(value = "//descriptionElement/byFeature", method = RequestMethod.GET) // mapped as absolute path, see CdmAntPathMatcher\r
+ public Pager<DescriptionElementBase> doPageDescriptionElementsByFeature(\r
+ @RequestParam(value = "features", required = false) DefinedTermBaseList<Feature> features,\r
+ @RequestParam(value = "descriptionType", required = true) Class<? extends DescriptionBase> descriptionType,\r
+ @RequestParam(value = "type", required = false) Class<? extends DescriptionElementBase> type,\r
+ @RequestParam(value = "pageSize", required = false) Integer pageSize,\r
+ @RequestParam(value = "pageNumber", required = false) Integer pageNumber, HttpServletRequest request,\r
+ HttpServletResponse response) throws IOException {\r
+\r
+ logger.info("doPageDescriptionElementsByFeature : " + requestPathAndQuery(request));\r
+\r
+ PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
+ pagerParams.normalizeAndValidate(response);\r
+\r
+ if(features == null){\r
+ features = new DefinedTermBaseList<Feature>();\r
+ }\r
+\r
+ Pager<DescriptionElementBase> pager = service.pageDescriptionElements(null, descriptionType, features.asSet(),\r
+ type, pagerParams.getPageSize(), pagerParams.getPageIndex(), getInitializationStrategy());\r
+\r
+ return pager;\r
+ }\r
+\r
+ /**\r
+ * Requires the query parameter "taxon" to be present\r
+ *\r
+ * @param taxon_uuid\r
+ * @param features\r
+ * @param type\r
+ * @param pageSize\r
+ * @param pageNumber\r
+ * @param request\r
+ * @param response\r
+ * @return\r
+ * @throws IOException\r
+ */\r
+ @RequestMapping(value = "//descriptionElement/byTaxon", method = {RequestMethod.GET, RequestMethod.POST}) // mapped as absolute path, see CdmAntPathMatcher\r
+ public <T extends DescriptionElementBase> Pager<T> getDescriptionElementsForTaxon(\r
+ @RequestParam(value = "taxon", required = true) UUID taxon_uuid,\r
+ @RequestParam(value = "features", required = false) DefinedTermBaseList<Feature> features,\r
+ @RequestParam(value = "type", required = false) Class<T> type,\r
+ @RequestParam(value = "pageSize", required = false) Integer pageSize,\r
+ @RequestParam(value = "pageNumber", required = false) Integer pageNumber, HttpServletRequest request,\r
+ HttpServletResponse response) throws IOException {\r
+\r
+ logger.info("getDescriptionElementsForTaxon : " + requestPathAndQuery(request));\r
+\r
+ PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
+ pagerParams.normalizeAndValidate(response);\r
+\r
+ Taxon taxon = null;\r
+ if( taxon_uuid!= null){\r
+ try {\r
+ taxon = (Taxon) taxonService.load(taxon_uuid);\r
+ } catch (Exception e) {\r
+ HttpStatusMessage.UUID_NOT_FOUND.send(response);\r
+ }\r
+ }\r
+\r
+ Pager<T> pager = service.pageDescriptionElementsForTaxon(taxon, features.asSet(), type, pageSize,\r
+ pageNumber, getInitializationStrategy());\r
+\r
+ return pager;\r
+ }\r
+\r
+ @RequestMapping(value = "namedAreasInUse", method = RequestMethod.GET)\r
+ public Pager<NamedArea> doPageNamedAreasInUse(\r
+ @RequestParam(value = "pageSize", required = false) Integer pageSize,\r
+ @RequestParam(value = "pageNumber", required = false) Integer pageNumber, HttpServletRequest request,\r
+ HttpServletResponse response) throws IOException {\r
+\r
+ logger.info("doPageNamedAreasInUse : " + requestPathAndQuery(request));\r
+\r
+ PagerParameters pagerParams = new PagerParameters(pageSize, pageNumber);\r
+ pagerParams.normalizeAndValidate(response);\r
+\r
+ Pager<NamedArea> pager = service.pageNamedAreasInUse(pageSize, pageNumber, getInitializationStrategy());\r
+\r
+ return pager;\r
+ }\r
}
\ No newline at end of file