diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/ForecastConfigurationController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/ForecastConfigurationController.java
index daaeae40511a70eca9d9f2cb4197e0010dd92238..3275c260b6b2996f7556fddb6402e67b6ddcf01a 100644
--- a/src/main/java/no/nibio/vips/logic/controller/servlet/ForecastConfigurationController.java
+++ b/src/main/java/no/nibio/vips/logic/controller/servlet/ForecastConfigurationController.java
@@ -140,13 +140,29 @@ public class ForecastConfigurationController extends HttpServlet {
request.setAttribute("organizations", organizations);
request.setAttribute("selectedOrganizationIds", selectedOrganizationIds);
+
+ request.setAttribute("allUsers", userBean.getAllUsers());
+ // If super user requests private forecasts for a user
+ try
+ {
+ Integer otherUserId = Integer.valueOf(request.getParameter("otherUserId"));
+ List<ForecastConfiguration> privateForecastConfigurationsForOtherUser = forecastBean.getPrivateForecastConfigurationsForUser(otherUserId);
+ request.setAttribute("privateForecastConfigurationsForOtherUser", privateForecastConfigurationsForOtherUser);
+ request.setAttribute("otherUserId", otherUserId);
+ }
+ catch(NumberFormatException nfe) {}
}
else
{
forecasts = forecastBean.getForecastConfigurations(user.getOrganizationId(), selectedModelIds, from, to);
}
Collections.sort(forecasts);
+
request.setAttribute("forecastConfigurations", forecasts);
+
+ List<ForecastConfiguration> privateForecasts;
+ privateForecasts = forecastBean.getPrivateForecastConfigurationsForUser(user.getUserId());
+ request.setAttribute("privateForecastConfigurations", privateForecasts);
request.setAttribute("modelInformation", modelInformationMap);
request.setAttribute("selectedModelIds", selectedModelIds);
request.setAttribute("from", from);
@@ -185,6 +201,11 @@ public class ForecastConfigurationController extends HttpServlet {
{
response.sendError(403,"Access not authorized"); // HTTP Forbidden
}
+ // Only superusers can view and edit private forecasts from other users
+ else if(forecastConfiguration.getIsPrivate() && ! user.isSuperUser() && forecastConfiguration.getVipsLogicUserId() != null && !forecastConfiguration.getVipsLogicUserId().getUserId().equals(user.getUserId()))
+ {
+ response.sendError(403,"Access not authorized"); // HTTP Forbidden
+ }
else
{
// TODO: More intelligent selection of locations, weather stations and users
diff --git a/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java b/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java
index d4f7a713afaaa0525fae2252bf460f5c9646916d..da528cf17523bb4742763de5aca782246603c8b3 100644
--- a/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java
+++ b/src/main/java/no/nibio/vips/logic/controller/session/ForecastBean.java
@@ -41,6 +41,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;
@@ -104,7 +105,26 @@ public class ForecastBean {
Query q = em.createNamedQuery("ForecastResult.findByForecastConfigurationId");
q.setParameter("forecastConfigurationId", forecastConfigurationId);
return q.getResultList();
-
+ }
+
+ public boolean isUserAuthorizedForForecastConfiguration(Long forecastConfigurationId, String userUUID)
+ {
+ // Authentication
+ ForecastConfiguration fc = em.find(ForecastConfiguration.class, forecastConfigurationId);
+ if(fc.getIsPrivate())
+ {
+ if(userUUID == null)
+ {
+ return false;
+ }
+ UUID uUUID = UUID.fromString(userUUID);
+ VipsLogicUser user = SessionControllerGetter.getUserBean().findVipsLogicUser(uUUID);
+ if(user == null || user.getUserId().equals( fc.getVipsLogicUserId()))
+ {
+ return false;
+ }
+ }
+ return true;
}
public List<ForecastResult> getForecastResults(Long forecastConfigurationId, Integer latestDays)
@@ -180,7 +200,7 @@ public class ForecastBean {
/**
- * Get all forecast configurations for one user.
+ * Get all PUBLIC forecast configurations for one user.
* TODO: Should be season based, or possibly based on start/stop date
* @param userId
* @return
@@ -193,6 +213,23 @@ public class ForecastBean {
return q.getResultList();
}
+ /**
+ * Get all PRIVATE forecast configurations for one user.
+ * TODO: Should be season based, or possibly based on start/stop date
+ * @param userId
+ * @return
+ */
+ public List<ForecastConfiguration> getPrivateForecastConfigurationsForUser(Integer userId)
+ {
+ VipsLogicUser user = em.find(VipsLogicUser.class, userId);
+ Query q = em.createNamedQuery("ForecastConfiguration.findPrivateByVipsLogicUserId");
+ q.setParameter("vipsLogicUserId", user);
+ return q.getResultList();
+ }
+
+
+
+
public List<ForecastConfiguration> getForecastConfigurationsForUserAndDate(Integer userId, Date from, Date to)
{
VipsLogicUser user = em.find(VipsLogicUser.class, userId);
@@ -404,6 +441,7 @@ public class ForecastBean {
forecastConfiguration.setModelId(formFields.get("modelId").getWebValue());
forecastConfiguration.setCropOrganismId(em.find(Organism.class, formFields.get("cropOrganismId").getValueAsInteger()));
forecastConfiguration.setPestOrganismId(em.find(Organism.class, formFields.get("pestOrganismId").getValueAsInteger()));
+ forecastConfiguration.setIsPrivate(formFields.get("isPrivate").getWebValue() != null);
PointOfInterest locationPoi = em.find(PointOfInterest.class, formFields.get("locationPointOfInterestId").getValueAsInteger());
forecastConfiguration.setLocationPointOfInterestId(locationPoi);
PointOfInterest weatherStationPoi = em.find(PointOfInterestWeatherStation.class, formFields.get("weatherStationPointOfInterestId").getValueAsInteger());
@@ -878,7 +916,8 @@ public class ForecastBean {
"WHERE forecast_configuration_id IN( \n" +
" SELECT forecast_configuration_id \n" +
" FROM forecast_configuration \n" +
- " WHERE location_point_of_interest_id=:locationPointOfInterestId \n" +
+ " WHERE is_private IS FALSE \n" +
+ " AND location_point_of_interest_id=:locationPointOfInterestId \n" +
(cropOrganismIds != null && ! cropOrganismIds.isEmpty() ? " AND crop_organism_id IN (" + StringUtils.join(cropOrganismIds, ",") + ") " : "") +
")\n" +
"AND to_char(result_valid_time, '" + dateFormat + "') = :dateStr";
@@ -912,6 +951,10 @@ public class ForecastBean {
List<ForecastResult> results = new ArrayList<>();
for(ForecastConfiguration forecastConfiguration:forecastConfigurations)
{
+ if(forecastConfiguration.getIsPrivate())
+ {
+ continue;
+ }
mappedForecastConfigurations.put(forecastConfiguration.getForecastConfigurationId(), forecastConfiguration);
Query q = em.createNativeQuery(
"SELECT * FROM forecast_result WHERE forecast_configuration_id = :forecastConfigurationId "
@@ -968,5 +1011,25 @@ public class ForecastBean {
return forecastConfiguration;
}
+
+ public List<ForecastConfiguration> getPrivateForecastConfigurationSummaries(VipsLogicUser user) {
+ List<ForecastConfiguration> forecastConfigurations = this.getPrivateForecastConfigurationsForUser(user.getUserId());
+ // TODO: Filter forecastconfigurations based on criteria (activity, crops, geography etc)
+ List<ForecastConfiguration> filteredConfigs = new ArrayList<>();
+ Query q = em.createNamedQuery("ForecastSummary.findByForecastConfigurationId");
+ for(ForecastConfiguration config: forecastConfigurations)
+ {
+ config.setForecastSummaries(
+
+ q.setParameter("forecastConfigurationId", config.getForecastConfigurationId())
+ .getResultList()
+ );
+ if(config.getForecastSummaries() != null && !config.getForecastSummaries().isEmpty())
+ {
+ filteredConfigs.add(config);
+ }
+ }
+ return filteredConfigs;
+ }
}
diff --git a/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java b/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java
index 679b66da5309808a7df8cdc060d7d1950332ac07..6fa0860969cfa571174869654cc4121f393dcd5e 100644
--- a/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java
+++ b/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java
@@ -47,31 +47,35 @@ import javax.persistence.Transient;
import no.nibio.vips.util.WeatherUtil;
/**
- * @copyright 2014-2015 <a href="http://www.nibio.no/">NIBIO</a>
+ * @copyright 2014-2016 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
@Entity
@Table(name = "forecast_configuration")
@XmlRootElement
@NamedQueries({
- @NamedQuery(name = "ForecastConfiguration.findAll", query = "SELECT f FROM ForecastConfiguration f"),
+ @NamedQuery(name = "ForecastConfiguration.findAll", query = "SELECT f FROM ForecastConfiguration f WHERE f.isPrivate = FALSE"),
@NamedQuery(name = "ForecastConfiguration.findByForecastConfigurationId", query = "SELECT f FROM ForecastConfiguration f WHERE f.forecastConfigurationId = :forecastConfigurationId"),
@NamedQuery(name = "ForecastConfiguration.findByForecastConfigurationIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.forecastConfigurationId IN(:forecastConfigurationIds)"),
- @NamedQuery(name = "ForecastConfiguration.findByModelId", query = "SELECT f FROM ForecastConfiguration f WHERE f.modelId = :modelId"),
- @NamedQuery(name = "ForecastConfiguration.findByModelIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.modelId IN (:modelIds)"),
- @NamedQuery(name = "ForecastConfiguration.findByDateStart", query = "SELECT f FROM ForecastConfiguration f WHERE f.dateStart = :dateStart"),
- @NamedQuery(name = "ForecastConfiguration.findByDateEnd", query = "SELECT f FROM ForecastConfiguration f WHERE f.dateEnd = :dateEnd"),
- @NamedQuery(name = "ForecastConfiguration.findActiveAtDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.dateStart <= :currentDate AND f.dateEnd >= :currentDate"),
- @NamedQuery(name = "ForecastConfiguration.findByLocationPointOfInterestId", query = "SELECT f FROM ForecastConfiguration f WHERE f.locationPointOfInterestId = :locationPointOfInterestId"),
- @NamedQuery(name = "ForecastConfiguration.findByWeatherStationPointOfInterestId", query = "SELECT f FROM ForecastConfiguration f WHERE f.weatherStationPointOfInterestId = :weatherStationPointOfInterestId"),
- @NamedQuery(name = "ForecastConfiguration.findByWeatherStationPointOfInterestIdAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.weatherStationPointOfInterestId = :weatherStationPointOfInterestId AND f.dateStart <= :to AND f.dateEnd >= :from"),
- @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserId", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId"),
- @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.dateStart <= :to AND f.dateEnd >= :from" ),
- @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdAndCropOrganismId", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.cropOrganismId.organismId IN (:cropOrganismIds)"),
- @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdAndCropOrganismIdsAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.cropOrganismId.organismId IN (:cropOrganismIds) AND f.dateStart <= :to AND f.dateEnd >= :from"),
- @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds)"),
- @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds)"),
- @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIdsAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds) AND f.dateStart <= :to AND f.dateEnd >= :from")})
+ @NamedQuery(name = "ForecastConfiguration.findByModelId", query = "SELECT f FROM ForecastConfiguration f WHERE f.modelId = :modelId AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByModelIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.modelId IN (:modelIds) AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByDateStart", query = "SELECT f FROM ForecastConfiguration f WHERE f.dateStart = :dateStart AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByDateEnd", query = "SELECT f FROM ForecastConfiguration f WHERE f.dateEnd = :dateEnd AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findActiveAtDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.dateStart <= :currentDate AND f.dateEnd >= :currentDate AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByLocationPointOfInterestId", query = "SELECT f FROM ForecastConfiguration f WHERE f.locationPointOfInterestId = :locationPointOfInterestId AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByWeatherStationPointOfInterestId", query = "SELECT f FROM ForecastConfiguration f WHERE f.weatherStationPointOfInterestId = :weatherStationPointOfInterestId AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByWeatherStationPointOfInterestIdAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.weatherStationPointOfInterestId = :weatherStationPointOfInterestId AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserId", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = FALSE" ),
+ @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdAndCropOrganismId", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.cropOrganismId.organismId IN (:cropOrganismIds) AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdAndCropOrganismIdsAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.cropOrganismId.organismId IN (:cropOrganismIds) AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findPrivateByVipsLogicUserId", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.isPrivate = TRUE"),
+ @NamedQuery(name = "ForecastConfiguration.findPrivateByVipsLogicUserIdAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = TRUE" ),
+ @NamedQuery(name = "ForecastConfiguration.findPrivateByVipsLogicUserIdAndCropOrganismId", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.cropOrganismId.organismId IN (:cropOrganismIds) AND f.isPrivate = TRUE"),
+ @NamedQuery(name = "ForecastConfiguration.findPrivateByVipsLogicUserIdAndCropOrganismIdsAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId = :vipsLogicUserId AND f.cropOrganismId.organismId IN (:cropOrganismIds) AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = TRUE"),
+ @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIds", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds) AND f.isPrivate = FALSE"),
+ @NamedQuery(name = "ForecastConfiguration.findByVipsLogicUserIdsAndModelIdsAndDate", query = "SELECT f FROM ForecastConfiguration f WHERE f.vipsLogicUserId IN (:vipsLogicUserIds) AND f.modelId IN (:modelIds) AND f.dateStart <= :to AND f.dateEnd >= :from AND f.isPrivate = FALSE")})
public class ForecastConfiguration implements Serializable, Comparable {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "forecastConfiguration", fetch = FetchType.EAGER)
private Set<ForecastModelConfiguration> forecastModelConfigurationSet;
@@ -109,6 +113,8 @@ public class ForecastConfiguration implements Serializable, Comparable {
@JoinColumn(name = "pest_organism_id", referencedColumnName = "organism_id")
@ManyToOne
private Organism pestOrganismId;
+ @Column(name = "is_private")
+ private Boolean isPrivate;
@Transient
private WeatherUtil weatherUtil;
@@ -370,4 +376,18 @@ public class ForecastConfiguration implements Serializable, Comparable {
format.setTimeZone(timeZone1);
return format.format(this.getDateEnd());
}*/
+
+ /**
+ * @return the isPrivate
+ */
+ public Boolean getIsPrivate() {
+ return isPrivate;
+ }
+
+ /**
+ * @param isPrivate the isPrivate to set
+ */
+ public void setIsPrivate(Boolean isPrivate) {
+ this.isPrivate = isPrivate;
+ }
}
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 07a4764d030c1cf8d65e7a8c01aa68219a8d8c0a..53a70b1a48adad398bbab9e92b78709f5fba877c 100644
--- a/src/main/java/no/nibio/vips/logic/service/LogicService.java
+++ b/src/main/java/no/nibio/vips/logic/service/LogicService.java
@@ -87,14 +87,24 @@ public class LogicService {
@GET
@Path("forecastresults/{forecastConfigurationId}")
@Produces("application/json;charset=UTF-8")
- public Response getForecastResults(@PathParam("forecastConfigurationId") Long forecastConfigurationId)
+ public Response getForecastResults(
+ @PathParam("forecastConfigurationId") Long forecastConfigurationId,
+ @QueryParam("userUUID") String userUUID
+ )
{
- List<ForecastResult> results = SessionControllerGetter.getForecastBean().getForecastResults(forecastConfigurationId);
- if(results == null)
+ if(SessionControllerGetter.getForecastBean().isUserAuthorizedForForecastConfiguration(forecastConfigurationId, userUUID))
+ {
+ List<ForecastResult> results = SessionControllerGetter.getForecastBean().getForecastResults(forecastConfigurationId);
+ if(results == null)
+ {
+ results = new ArrayList<>();
+ }
+ return Response.ok().entity(results).build();
+ }
+ else
{
- results = new ArrayList<>();
+ return Response.status(Response.Status.UNAUTHORIZED).build();
}
- return Response.ok().entity(results).build();
}
@GET
@@ -102,15 +112,23 @@ public class LogicService {
@Produces("application/json;charset=UTF-8")
public Response getForecastResults(
@PathParam("forecastConfigurationId") Long forecastConfigurationId,
- @PathParam("latestDays") Integer latestDays
+ @PathParam("latestDays") Integer latestDays,
+ @QueryParam("userUUID") String userUUID
)
{
- List<ForecastResult> results = SessionControllerGetter.getForecastBean().getForecastResults(forecastConfigurationId, latestDays);
- if(results == null)
+ if(SessionControllerGetter.getForecastBean().isUserAuthorizedForForecastConfiguration(forecastConfigurationId, userUUID))
{
- results = new ArrayList<>();
+ List<ForecastResult> results = SessionControllerGetter.getForecastBean().getForecastResults(forecastConfigurationId, latestDays);
+ if(results == null)
+ {
+ results = new ArrayList<>();
+ }
+ return Response.ok().entity(results).build();
+ }
+ else
+ {
+ return Response.status(Response.Status.UNAUTHORIZED).build();
}
- return Response.ok().entity(results).build();
}
@GET
@@ -125,6 +143,27 @@ public class LogicService {
return Response.ok().entity(summaries).build();
}
+ @GET
+ @Path("forecastconfigurationsummaries/private/{userUUID}")
+ @Produces("application/json;charset=UTF-8")
+ public Response getForecastSummaries(
+ @PathParam("userUUID") String userUUID
+ )
+ {
+ UUID uUUID = UUID.fromString(userUUID);
+ VipsLogicUser user = SessionControllerGetter.getUserBean().findVipsLogicUser(uUUID);
+ if(user != null)
+ {
+ List<ForecastConfiguration> summaries = SessionControllerGetter.getForecastBean().getPrivateForecastConfigurationSummaries(user);
+ return Response.ok().entity(summaries).build();
+ }
+ else
+ {
+ return Response.status(Response.Status.UNAUTHORIZED).build();
+ }
+
+ }
+
/**
* Returns the requested forecast configuration
* @param forecastConfigurationId
@@ -133,15 +172,51 @@ public class LogicService {
@GET
@Path("forecastconfigurations/{forecastConfigurationId}")
@Produces("application/json;charset=UTF-8")
- public Response getForecastConfiguration(@PathParam("forecastConfigurationId") Long forecastConfigurationId)
+ public Response getForecastConfiguration(@PathParam("forecastConfigurationId") Long forecastConfigurationId,@QueryParam("userUUID") String userUUID)
+ {
+ if(SessionControllerGetter.getForecastBean().isUserAuthorizedForForecastConfiguration(forecastConfigurationId, userUUID))
+ {
+ ForecastConfiguration forecastConfiguration = SessionControllerGetter.getForecastBean().getForecastConfiguration(forecastConfigurationId);
+ return Response.ok().entity(forecastConfiguration).build();
+ }
+ else
+ {
+ return Response.status(Response.Status.UNAUTHORIZED).build();
+ }
+ }
+
+ @GET
+ @Path("forecastconfigurations/private/{userUUID}")
+ @Produces("application/json;charset=UTF-8")
+ public Response getPrivateForecastConfigurations(@PathParam("userUUID") String userUUID)
{
- ForecastConfiguration forecastConfiguration = SessionControllerGetter.getForecastBean().getForecastConfiguration(forecastConfigurationId);
- return Response.ok().entity(forecastConfiguration).build();
+ try
+ {
+ UUID uUUID = UUID.fromString(userUUID);
+ VipsLogicUser user = SessionControllerGetter.getUserBean().findVipsLogicUser(uUUID);
+ if(user != null)
+ {
+ List<ForecastConfiguration> retVal = SessionControllerGetter.getForecastBean().getPrivateForecastConfigurationsForUser(user.getUserId());
+ return Response.ok().entity(retVal).build();
+ }
+ else
+ {
+ return Response.status(Response.Status.UNAUTHORIZED).build();
+ }
+ }
+ catch(NullPointerException npe)
+ {
+ return Response.noContent().build();
+ }
+
}
/**
* Returns a list of forecasts for given organization
* @param organizationId
+ * @param cropOrganismIds
+ * @param from
+ * @param to
* @return
*/
@GET
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
index fac5f04c38a74b63cffc3800f9762d0b8ae38cff..829aee3a352d8eb2e36b6b1dd833cff8a8413e37 100644
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties
@@ -338,3 +338,7 @@ includeAllChildCrops=Include all child crops
pestOrganismIds=Pests
cropPestUpdated=Crop pest was updated
surveillanceMessageInformation=If you want to create a message about an observation, please use the observation registration form
+isPrivate=Is private
+privateForecasts=Private forecasts
+privateForecastsForOtherUser=Private forecasts for other user
+noPrivateForecastsFoundForUser=No private forecasts found for user
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
index 5a5afd5e0bc3568952dea52c70812e6f103f3f4b..b707f0fbd7186dbad2a8bbdc6731567068086a4e 100644
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties
@@ -338,3 +338,7 @@ includeAllChildCrops=Include all child crops
pestOrganismIds=Pests
cropPestUpdated=Crop pest was updated
surveillanceMessageInformation=If you want to create a message about an observation, please use the observation registration form
+isPrivate=Is private
+privateForecasts=Private forecasts
+privateForecastsForOtherUser=Private forecasts for other user
+noPrivateForecastsFoundForUser=No private forecasts found for user
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
index 2f79968fd3eb9c4310e0390abcb2e69f3c1433c5..5beb86b7e9c233c42982d19dcf7a0c9ce10873be 100644
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties
@@ -337,3 +337,7 @@ includeAllChildCrops=Include all child crops
pestOrganismIds=Pests
cropPestUpdated=Crop pest was updated
surveillanceMessageInformation=If you want to create a message about an observation, please use the observation registration form
+isPrivate=Is private
+privateForecasts=Private forecasts
+privateForecastsForOtherUser=Private forecasts for other user
+noPrivateForecastsFoundForUser=No private forecasts found for user
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
index 035fda637f46c1f676d9172bfd7e32e20c790a6f..a58b7a01d4a691f3524144c3e847120327e2da13 100644
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties
@@ -338,3 +338,7 @@ includeAllChildCrops=Inkluder alle underarter, sorter og varianter
pestOrganismIds=Skadegj\u00f8rere
cropPestUpdated=Skadegj\u00f8rere for kultur ble lagret
surveillanceMessageInformation=Hvis du \u00f8nsker \u00e5 lage en melding om en observasjon/et f\u00f8rstefunn, vennligst bruk <a href="/observation?action=newObservationForm">observasjonsregistreringsskjemaet</a>
+isPrivate=Er privat
+privateForecasts=Private varsler
+privateForecastsForOtherUser=Private varsler for annen bruker
+noPrivateForecastsFoundForUser=Fant ingen private varsler for brukeren
diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
index fb2ab4d0bdecacd01ebc231561dcf424308694ca..0c0763768b7e97cea5ff5f03fe28c6ca7b45a4ce 100644
--- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
+++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties
@@ -338,3 +338,7 @@ includeAllChildCrops=Include all child crops
pestOrganismIds=Pests
cropPestUpdated=Crop pest was updated
surveillanceMessageInformation=If you want to create a message about an observation, please use the observation registration form
+isPrivate=Is private
+privateForecasts=Private forecasts
+privateForecastsForOtherUser=Private forecasts for other user
+noPrivateForecastsFoundForUser=No private forecasts found for user
diff --git a/src/main/webapp/formdefinitions/forecastConfigurationForm.json b/src/main/webapp/formdefinitions/forecastConfigurationForm.json
index b5b1d23cb75b32248dfdafb30797d0e016b47ed9..0273d045d5898e6c6ca56f872a46bd85f31e2dd6 100644
--- a/src/main/webapp/formdefinitions/forecastConfigurationForm.json
+++ b/src/main/webapp/formdefinitions/forecastConfigurationForm.json
@@ -51,6 +51,11 @@
"nullValue": "-1",
"required" : true
},
+ {
+ "name" : "isPrivate",
+ "dataType" : "STRING",
+ "required" : false
+ },
{
"name" : "locationPointOfInterestId",
"dataType" : "INTEGER",
diff --git a/src/main/webapp/templates/forecastConfigurationForm.ftl b/src/main/webapp/templates/forecastConfigurationForm.ftl
index 376f35a73ad7d8b3fc5abd0c90756a76365897c5..6f3bdf60fa243f6c8b7109ee8ddf8dd27fba7125 100644
--- a/src/main/webapp/templates/forecastConfigurationForm.ftl
+++ b/src/main/webapp/templates/forecastConfigurationForm.ftl
@@ -1,5 +1,5 @@
<#--
- Copyright (c) 2014 NIBIO <http://www.nibio.no/>.
+ Copyright (c) 2016 NIBIO <http://www.nibio.no/>.
This file is part of VIPSLogic.
VIPSLogic is free software: you can redistribute it and/or modify
@@ -16,7 +16,7 @@
along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>.
--><#include "master.ftl">
<#macro page_head>
- <title></title>
+ <title>${i18nBundle.viewForecastConfiguration}</title>
</#macro>
<#macro custom_js>
<script src="/js/resourcebundle.js"></script>
@@ -85,6 +85,14 @@
</select>
<span class="help-block" id="${formId}_cropOrganismId_validation"></span>
</div>
+ <div class="form-group">
+ <div class="checkbox">
+ <label>
+ <input type="checkbox" name="isPrivate"<#if forecastConfiguration.isPrivate?has_content && forecastConfiguration.isPrivate == true> checked="checked"</#if>/>
+ </label>
+ ${i18nBundle.isPrivate}
+ </div>
+ </div>
<div class="form-group">
<label for="pestOrganismId">${i18nBundle.pestOrganismId}</label>
<select class="form-control" id="pestOrganismId" name="pestOrganismId" onblur="validateField(this);" onchange="renderModelSpecificFields('${formId}');">
diff --git a/src/main/webapp/templates/forecastConfigurationList.ftl b/src/main/webapp/templates/forecastConfigurationList.ftl
index 4ba2845c6c6d5c9b75175cb448678ffe4f0cf7c7..5349d69f1be7c2bcbed35d81c0b0c16c599a2e8a 100644
--- a/src/main/webapp/templates/forecastConfigurationList.ftl
+++ b/src/main/webapp/templates/forecastConfigurationList.ftl
@@ -95,6 +95,83 @@
</tbody>
</table>
</div>
+ <h2>${i18nBundle.privateForecasts}</h2>
+ <div class="table-responsive">
+ <table class="table table-striped">
+ <thead>
+ <th>${i18nBundle.modelId}</th>
+ <th>${i18nBundle.poi}</th>
+ <th>${i18nBundle.weatherStationPointOfInterestId}</th>
+ <th>${i18nBundle.dateStart}</th>
+ <th>${i18nBundle.dateEnd}</th>
+ </thead>
+ <tbody>
+ <#list privateForecastConfigurations as forecastConfiguration>
+ <tr style="cursor: pointer;" onclick="window.location.href='/forecastConfiguration?action=viewForecastConfiguration&forecastConfigurationId=${forecastConfiguration.forecastConfigurationId}';">
+ <td>
+ <#if i18nBundle.containsKey(forecastConfiguration.modelId)>
+ ${i18nBundle[forecastConfiguration.modelId]}
+ <#else>
+ ${modelInformation[forecastConfiguration.modelId].defaultName}
+ </#if>
+ </td>
+ <td>${forecastConfiguration.locationPointOfInterestId.name}</td>
+ <td>${forecastConfiguration.weatherStationPointOfInterestId.name}</td>
+ <td>${forecastConfiguration.dateStart}</td>
+ <td>${forecastConfiguration.dateEnd}</td>
+ </tr>
+ </#list>
+ </tbody>
+ </table>
+ </div>
+ <#if user.isSuperUser() >
+ <h2>${i18nBundle.privateForecastsForOtherUser}</h2>
+ <div class="form-group">
+ <label for="otherUserId">${i18nBundle.user}</label>
+ <select class="form-control" name="otherUserId" onchange="window.location.href='/forecastConfiguration?otherUserId=' + this.options[this.options.selectedIndex].value;">
+ <option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.user?lower_case}</option>
+ <#list allUsers?sort_by("lastName") as otherUser>
+ <#if otherUser.userId != user.userId>
+ <option value="${otherUser.userId}"
+ <#if (otherUserId?has_content && otherUserId == otherUser.userId)>selected="selected"</#if>
+ >${otherUser.lastName}, ${otherUser.firstName}</option>
+ </#if>
+ </#list>
+ </select>
+ </div>
+ <#if privateForecastConfigurationsForOtherUser?has_content>
+ <div class="table-responsive">
+ <table class="table table-striped">
+ <thead>
+ <th>${i18nBundle.modelId}</th>
+ <th>${i18nBundle.poi}</th>
+ <th>${i18nBundle.weatherStationPointOfInterestId}</th>
+ <th>${i18nBundle.dateStart}</th>
+ <th>${i18nBundle.dateEnd}</th>
+ </thead>
+ <tbody>
+ <#list privateForecastConfigurations as forecastConfiguration>
+ <tr style="cursor: pointer;" onclick="window.location.href='/forecastConfiguration?action=viewForecastConfiguration&forecastConfigurationId=${forecastConfiguration.forecastConfigurationId}';">
+ <td>
+ <#if i18nBundle.containsKey(forecastConfiguration.modelId)>
+ ${i18nBundle[forecastConfiguration.modelId]}
+ <#else>
+ ${modelInformation[forecastConfiguration.modelId].defaultName}
+ </#if>
+ </td>
+ <td>${forecastConfiguration.locationPointOfInterestId.name}</td>
+ <td>${forecastConfiguration.weatherStationPointOfInterestId.name}</td>
+ <td>${forecastConfiguration.dateStart}</td>
+ <td>${forecastConfiguration.dateEnd}</td>
+ </tr>
+ </#list>
+ </tbody>
+ </table>
+ </div>
+ <#elseif otherUserId?has_content>
+ <div class="alert alert-warning">${i18nBundle.noPrivateForecastsFoundForUser}</div>
+ </#if>
+ </#if>
</div>
</#macro>
<@page_html/>