From e1c4efe92397e3639bcdcc0b08127b5292aee7bf Mon Sep 17 00:00:00 2001 From: Tor-Einar Skog <tor-einar.skog@nibio.no> Date: Fri, 23 Nov 2018 10:08:00 +0100 Subject: [PATCH] Adjusting services to acommodate observations on the VIPSWeb front page --- nb-configuration.xml | 1 + .../controller/session/ObservationBean.java | 13 +- .../nibio/vips/logic/entity/Observation.java | 22 ++ .../vips/logic/entity/PointOfInterest.java | 10 +- .../entity/rest/ObservationListItem.java | 199 ++++++++++++++++++ .../vips/logic/service/LogicService.java | 1 - .../logic/service/ObservationService.java | 99 ++++++++- 7 files changed, 329 insertions(+), 16 deletions(-) create mode 100644 src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java diff --git a/nb-configuration.xml b/nb-configuration.xml index 2f11ad2c..2f83dadc 100755 --- a/nb-configuration.xml +++ b/nb-configuration.xml @@ -27,5 +27,6 @@ Any value defined here will override the pom.xml file value but is only applicab <org-netbeans-modules-projectapi.jsf_2e_language>Facelets</org-netbeans-modules-projectapi.jsf_2e_language> <org-netbeans-modules-maven-jaxws._5f_C_5f_DMIWeatherService_2e_svc>https://dmiweatherservice-plant.dlbr.dk/DMIWeatherService.svc?wsdl</org-netbeans-modules-maven-jaxws._5f_C_5f_DMIWeatherService_2e_svc> <netbeans.compile.on.save>none</netbeans.compile.on.save> + <netbeans.hint.jdkPlatform>JDK_1.8_SUN</netbeans.hint.jdkPlatform> </properties> </project-shared-configuration> diff --git a/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java b/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java index 41fe5408..84296265 100755 --- a/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; +import java.util.stream.Collectors; import javax.ejb.Stateless; import javax.persistence.EntityManager; import javax.persistence.NoResultException; @@ -509,7 +510,7 @@ public class ObservationBean { Integer organizationId, Integer pestId, Integer cropId, - Integer cropCategoryId, + List<Integer> cropCategoryId, Date from, Date to ) @@ -535,12 +536,12 @@ public class ObservationBean { sql += "AND crop_organism_id = :cropOrganismId \n"; parameters.put("cropOrganismId", cropId); } - else if(cropCategoryId != null && cropCategoryId > 0) + else if(cropCategoryId != null && ! cropCategoryId.isEmpty()) { - CropCategory cropCategory = em.createNamedQuery("CropCategory.findByCropCategoryId", CropCategory.class) - .setParameter("cropCategoryId", cropCategoryId) - .getSingleResult(); - List<Integer> cropIds = Arrays.asList(cropCategory.getCropOrganismIds()); + List<CropCategory> cropCategories = em.createNamedQuery("CropCategory.findByCropCategoryIds", CropCategory.class) + .setParameter("cropCategoryIds", cropCategoryId) + .getResultList(); + List<Integer> cropIds = new ArrayList(cropCategories.stream().flatMap(cC->Arrays.asList(cC.getCropOrganismIds()).stream()).collect(Collectors.toSet())); sql += "AND crop_organism_id IN (:cropOrganismIds) \n"; parameters.put("cropOrganismIds", cropIds); diff --git a/src/main/java/no/nibio/vips/logic/entity/Observation.java b/src/main/java/no/nibio/vips/logic/entity/Observation.java index a838635a..c6e4303b 100755 --- a/src/main/java/no/nibio/vips/logic/entity/Observation.java +++ b/src/main/java/no/nibio/vips/logic/entity/Observation.java @@ -48,6 +48,7 @@ import javax.persistence.OneToMany; import javax.validation.constraints.Size; import no.nibio.vips.logic.util.GISEntityUtil; import no.nibio.vips.gis.GISUtil; +import no.nibio.vips.logic.entity.rest.ObservationListItem; import no.nibio.vips.logic.util.StringJsonUserType; import org.hibernate.annotations.Type; import org.hibernate.annotations.TypeDef; @@ -606,4 +607,25 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse this.lastEditedByUser = lastEditedByUser; } + public ObservationListItem getListItem(String locale) + { + // If geoInfo is from POI, need to add observationId + if(this.location != null) + { + this.location.addProperty("observationId", this.getObservationId()); + } + return new ObservationListItem( + this.getObservationId(), + this.getTimeOfObservation(), + this.getOrganismId(), + this.getOrganism().getLocalName(locale), + this.getCropOrganismId(), + this.getCropOrganism().getLocalName(locale), + this.location != null ? this.location.getGeoJSON() : this.getGeoinfo(), + this.getObservationHeading(), + this.getBroadcastMessage(), + this.getLocationIsPrivate() + ); + } + } diff --git a/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java b/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java index e27300e0..d047e6da 100755 --- a/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java +++ b/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java @@ -326,9 +326,13 @@ public class PointOfInterest implements Serializable, Comparable { @Transient public String getGeoJSON() { - Map<String, Object> properties = new HashMap<>(); - properties.put("pointOfInterestId", this.getPointOfInterestId()); - return this.gisUtil.getGeoJSONFromGeometry(this.getGisGeom(), properties); + this.addProperty("pointOfInterestId", this.getPointOfInterestId()); + return this.gisUtil.getGeoJSONFromGeometry(this.getGisGeom(), this.getProperties()); + } + + public void addProperty(String key, Object value) + { + this.getProperties().put(key, value); } /** diff --git a/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java b/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java new file mode 100644 index 00000000..7193b73a --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2018 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + +package no.nibio.vips.logic.entity.rest; + +import java.util.Date; + +/** + * @copyright 2018 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class ObservationListItem { + private Integer observationId, organismId, cropOrganismId; + private Date timeOfObservation; + private String organismName, cropOrganismName; + private String geoInfo; + private String observationHeading; + private Boolean broadcastMessage, locationIsPrivate; + + public ObservationListItem( + Integer observationId, + Date timeOfObservation, + Integer organismId, + String organismName, + Integer cropOrganismId, + String cropOrganismName, + String geoinfo, + String observationHeading, + Boolean broadcastMessage, + Boolean locationIsPrivate + ){ + this.observationId = observationId; + this.timeOfObservation = timeOfObservation; + this.organismId = organismId; + this.organismName = organismName; + this.cropOrganismId = cropOrganismId; + this.cropOrganismName = cropOrganismName; + this.geoInfo = geoinfo; + this.observationHeading = observationHeading; + this.broadcastMessage = broadcastMessage; + this.locationIsPrivate = locationIsPrivate; + } + + /** + * @return the observationId + */ + public Integer getObservationId() { + return observationId; + } + + /** + * @param observationId the observationId to set + */ + public void setObservationId(Integer observationId) { + this.observationId = observationId; + } + + /** + * @return the timeOfObservation + */ + public Date getTimeOfObservation() { + return timeOfObservation; + } + + /** + * @param timeOfObservation the timeOfObservation to set + */ + public void setTimeOfObservation(Date timeOfObservation) { + this.timeOfObservation = timeOfObservation; + } + + /** + * @return the organismName + */ + public String getOrganismName() { + return organismName; + } + + /** + * @param organismName the organismName to set + */ + public void setOrganismName(String organismName) { + this.organismName = organismName; + } + + /** + * @return the cropOrganismName + */ + public String getCropOrganismName() { + return cropOrganismName; + } + + /** + * @param cropOrganismName the cropOrganismName to set + */ + public void setCropOrganismName(String cropOrganismName) { + this.cropOrganismName = cropOrganismName; + } + + /** + * @return the geoInfo + */ + public String getGeoInfo() { + return geoInfo; + } + + /** + * @param geoInfo the geoInfo to set + */ + public void setGeoInfo(String geoInfo) { + this.geoInfo = geoInfo; + } + + /** + * @return the observationHeading + */ + public String getObservationHeading() { + return observationHeading; + } + + /** + * @param observationHeading the observationHeading to set + */ + public void setObservationHeading(String observationHeading) { + this.observationHeading = observationHeading; + } + + /** + * @return the organismId + */ + public Integer getOrganismId() { + return organismId; + } + + /** + * @param organismId the organismId to set + */ + public void setOrganismId(Integer organismId) { + this.organismId = organismId; + } + + /** + * @return the cropOrganismId + */ + public Integer getCropOrganismId() { + return cropOrganismId; + } + + /** + * @param cropOrganismId the cropOrganismId to set + */ + public void setCropOrganismId(Integer cropOrganismId) { + this.cropOrganismId = cropOrganismId; + } + + /** + * @return the broadcastMessage + */ + public Boolean getBroadcastMessage() { + return broadcastMessage; + } + + /** + * @param broadcastMessage the broadcastMessage to set + */ + public void setBroadcastMessage(Boolean broadcastMessage) { + this.broadcastMessage = broadcastMessage; + } + + /** + * @return the locationIsPrivate + */ + public Boolean getLocationIsPrivate() { + return locationIsPrivate; + } + + /** + * @param locationIsPrivate the locationIsPrivate to set + */ + public void setLocationIsPrivate(Boolean locationIsPrivate) { + this.locationIsPrivate = locationIsPrivate; + } +} diff --git a/src/main/java/no/nibio/vips/logic/service/LogicService.java b/src/main/java/no/nibio/vips/logic/service/LogicService.java index c47fed1d..5e171c63 100755 --- a/src/main/java/no/nibio/vips/logic/service/LogicService.java +++ b/src/main/java/no/nibio/vips/logic/service/LogicService.java @@ -56,7 +56,6 @@ import no.nibio.vips.logic.entity.ForecastConfiguration; import no.nibio.vips.logic.entity.ForecastModelConfiguration; import no.nibio.vips.logic.entity.Message; import no.nibio.vips.logic.entity.MessageTag; -import no.nibio.vips.logic.entity.Observation; import no.nibio.vips.logic.entity.Organism; import no.nibio.vips.logic.entity.Organization; import no.nibio.vips.logic.entity.PointOfInterest; diff --git a/src/main/java/no/nibio/vips/logic/service/ObservationService.java b/src/main/java/no/nibio/vips/logic/service/ObservationService.java index 24a81647..7e84c329 100755 --- a/src/main/java/no/nibio/vips/logic/service/ObservationService.java +++ b/src/main/java/no/nibio/vips/logic/service/ObservationService.java @@ -26,6 +26,8 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; @@ -56,20 +58,24 @@ public class ObservationService { @Context private HttpServletRequest httpServletRequest; - /** + /* * NOTE TO SELF * How to query for observations within a bounding box * Select * from gis where ST_Intersects( * ST_SetSRID(ST_MakeBox2D(ST_MakePoint(2.9004, 57.7511), ST_MakePoint(32.4316, 71.3851)),4326), * gis_geom); * First point is SW, last is NE (but could be anything?) + */ + + /** + * * @param organizationId * @param pestId * @param cropId * @param cropCategoryId * @param from * @param to - * @return + * @return Observation objects with all data (full tree) */ @GET @Path("filter/{organizationId}") @@ -79,11 +85,74 @@ public class ObservationService { @PathParam("organizationId") Integer organizationId, @QueryParam("pestId") Integer pestId, @QueryParam("cropId") Integer cropId, - @QueryParam("cropCategoryId") Integer cropCategoryId, + @QueryParam("cropCategoryId") List<Integer> cropCategoryId, @QueryParam("from") String fromStr, @QueryParam("to") String toStr ) + { + return Response.ok().entity(getFilteredObservationsFromBackend( + organizationId, + pestId, + cropId, + cropCategoryId, + fromStr, + toStr + )).build(); + } + + /** + * + * @param organizationId + * @param pestId + * @param cropId + * @param cropCategoryId + * @param from + * @param to + * @return Observation objects for which the user is authorized to observe with properties relevant for lists + */ + @GET + @Path("list/filter/{organizationId}") + @GZIP + @Produces("application/json;charset=UTF-8") + public Response getFilteredObservationListItems( + @PathParam("organizationId") Integer organizationId, + @QueryParam("pestId") Integer pestId, + @QueryParam("cropId") Integer cropId, + @QueryParam("cropCategoryId") List<Integer> cropCategoryId, + @QueryParam("from") String fromStr, + @QueryParam("to") String toStr, + @QueryParam("userUUID") String userUUID + + ) + { + VipsLogicUser user = (VipsLogicUser) httpServletRequest.getSession().getAttribute("user"); + if(user == null && userUUID != null) + { + user = SessionControllerGetter.getUserBean().findVipsLogicUser(UUID.fromString(userUUID)); + } + return Response.ok().entity( + getFilteredObservationsFromBackend( + organizationId, + pestId, + cropId, + cropCategoryId, + fromStr, + toStr, + user + ).stream().map(obs -> obs.getListItem("nb")).collect(Collectors.toList()) + ).build(); + } + + + private List<Observation> getFilteredObservationsFromBackend( + Integer organizationId, + Integer pestId, + Integer cropId, + List<Integer> cropCategoryId, + String fromStr, + String toStr + ) { SimpleDateFormat format = new SimpleDateFormat(Globals.defaultDateFormat); //TODO Set correct timeZone!!! @@ -96,7 +165,7 @@ public class ObservationService { } catch(ParseException ex){ System.out.println("ERROR");} - List<Observation> filteredObservations = SessionControllerGetter.getObservationBean().getFilteredObservations( + return SessionControllerGetter.getObservationBean().getFilteredObservations( organizationId, pestId, cropId, @@ -104,7 +173,7 @@ public class ObservationService { from, to ); - return Response.ok().entity(filteredObservations).build(); + } @GET @@ -115,7 +184,7 @@ public class ObservationService { @PathParam("organizationId") Integer organizationId, @QueryParam("pestId") Integer pestId, @QueryParam("cropId") Integer cropId, - @QueryParam("cropCategoryId") Integer cropCategoryId, + @QueryParam("cropCategoryId") List<Integer> cropCategoryId, @QueryParam("from") String fromStr, @QueryParam("to") String toStr @@ -325,5 +394,23 @@ public class ObservationService { return firstObsTime != null ? Response.ok().entity(firstObsTime).build() : Response.status(404).entity("No observations of organism with id=" + organismId).build(); } + + private List<Observation> getFilteredObservationsFromBackend(Integer organizationId, Integer pestId, Integer cropId, List<Integer> cropCategoryId, String fromStr, String toStr, VipsLogicUser user) { + List<Observation> filteredObservations = this.getFilteredObservationsFromBackend(organizationId, pestId, cropId, cropCategoryId, fromStr, toStr); + // If user is not logged in, return only the publicly available observations + if(user == null) + { + return filteredObservations.stream().filter(obs->obs.getBroadcastMessage()).collect(Collectors.toList()); + } + // Else: If superuser: Return everything + if(user.isSuperUser() || user.isOrganizationAdmin()) + { + return filteredObservations; + } + // Else: This is a registered user without special privileges. Show public observations + user's own + List<Observation> retVal = filteredObservations.stream().filter(obs->obs.getBroadcastMessage()).collect(Collectors.toList()); + retVal.addAll(SessionControllerGetter.getObservationBean().getObservationsForUser(user)); + return retVal; + } } -- GitLab