Skip to content
Snippets Groups Projects
Commit e5e17d7e authored by Tor-Einar Skog's avatar Tor-Einar Skog
Browse files

feat: Polish up logic in place/weather station select

parent a31afdde
Branches
No related tags found
1 merge request!191Add map module and Open-Meteo support
/*
* Copyright (c) 2014 NIBIO <http://www.nibio.no/>.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
* Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program 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
* GNU Affero General Public License for more details.
* This program 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 GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*
*/
package no.nibio.vips.logic.controller.servlet;
import com.ibm.icu.util.Calendar;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
......@@ -35,15 +32,18 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.icu.util.Calendar;
import no.nibio.vips.logic.controller.session.ForecastBean;
import no.nibio.vips.logic.controller.session.OrganismBean;
import no.nibio.vips.logic.controller.session.PointOfInterestBean;
import no.nibio.vips.logic.controller.session.UserBean;
import no.nibio.vips.logic.entity.*;
import no.nibio.vips.logic.entity.ForecastConfiguration;
import no.nibio.vips.logic.entity.ModelInformation;
import no.nibio.vips.logic.entity.Organization;
import no.nibio.vips.logic.entity.VipsLogicRole;
import no.nibio.vips.logic.entity.VipsLogicUser;
import no.nibio.vips.logic.i18n.SessionLocaleUtil;
import no.nibio.vips.logic.util.Globals;
import no.nibio.vips.logic.util.SystemTime;
......@@ -56,6 +56,7 @@ import no.nibio.web.forms.FormValidator;
/**
* Handles form configuration actions
*
* @copyright 2020-2022 <a href="http://www.nibio.no/">NIBIO</a>
* @author Tor-Einar Skog <tor-einar.skog@nibio.no>
*/
......@@ -63,15 +64,15 @@ public class ForecastConfigurationController extends HttpServlet {
private static final Logger LOGGER = LoggerFactory.getLogger(ForecastConfigurationController.class);
@PersistenceContext(unitName="VIPSLogic-PU")
@PersistenceContext(unitName = "VIPSLogic-PU")
EntityManager em;
@EJB
ForecastBean forecastBean;
@EJB
UserBean userBean;
@EJB
OrganismBean organismBean;
......@@ -79,8 +80,7 @@ public class ForecastConfigurationController extends HttpServlet {
PointOfInterestBean pointOfInterestBean;
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
* Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
*
* @param request servlet request
* @param response servlet response
......@@ -90,89 +90,79 @@ public class ForecastConfigurationController extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
String action = request.getParameter("action");
VipsLogicUser user = (VipsLogicUser) request.getSession().getAttribute("user");
// Default: View list of forecast configurations
// for SUPERUSERS and ORGANIZATION ADMINS
if(action == null)
{
if (action == null) {
Map<String, ModelInformation> modelInformationMap = forecastBean.getIndexedBatchableModelInformation();
if(userBean.authorizeUser(user, VipsLogicRole.ORGANIZATION_ADMINISTRATOR, VipsLogicRole.SUPERUSER))
{
if (userBean.authorizeUser(user, VipsLogicRole.ORGANIZATION_ADMINISTRATOR, VipsLogicRole.SUPERUSER)) {
// Check filtering conditions
List<String> selectedModelIds;
try
{
try {
selectedModelIds = Arrays.asList(request.getParameterValues("modelId"));
}
catch(NullPointerException ex)
{
} catch (NullPointerException ex) {
selectedModelIds = new ArrayList(modelInformationMap.keySet());
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date from,to;
try
{
Date from, to;
try {
from = format.parse(request.getParameter("from"));
to = format.parse(request.getParameter("to"));
}
catch(NullPointerException | ParseException ex)
{
} catch (NullPointerException | ParseException ex) {
to = SystemTime.getSystemTime();
Calendar cal = Calendar.getInstance();
cal.setTime(to);
cal.add(Calendar.MONTH, -2);
from = cal.getTime();
}
List<ForecastConfiguration> forecasts;
if(user.isSuperUser())
{
if (user.isSuperUser()) {
// Filtering of organizations
List<Organization> organizations = userBean.getOrganizations();
List<Integer> selectedOrganizationIds;
try
{
selectedOrganizationIds = Arrays.asList(ArrayUtil.stringArrayToIntegerArray(request.getParameterValues("organizationId")));
try {
selectedOrganizationIds = Arrays.asList(
ArrayUtil.stringArrayToIntegerArray(request.getParameterValues("organizationId")));
}
// No filter set -> select all organizations (default)
catch(NullPointerException ex)
{
catch (NullPointerException ex) {
selectedOrganizationIds = new ArrayList<>();
for(Organization o:organizations)
{
for (Organization o : organizations) {
selectedOrganizationIds.add(o.getOrganizationId());
}
}
forecasts = forecastBean.getForecastConfigurations(selectedOrganizationIds, selectedModelIds, from, to);
forecasts =
forecastBean.getForecastConfigurations(selectedOrganizationIds, selectedModelIds, from, to);
request.setAttribute("organizations", organizations);
request.setAttribute("selectedOrganizationIds", selectedOrganizationIds);
request.setAttribute("allUsers", userBean.getAllUsers());
// If super user requests private forecasts for a user
try
{
try {
Integer otherUserId = Integer.valueOf(request.getParameter("otherUserId"));
List<ForecastConfiguration> privateForecastConfigurationsForOtherUser = forecastBean.getPrivateForecastConfigurationsForUser(otherUserId);
request.setAttribute("privateForecastConfigurationsForOtherUser", privateForecastConfigurationsForOtherUser);
List<ForecastConfiguration> privateForecastConfigurationsForOtherUser =
forecastBean.getPrivateForecastConfigurationsForUser(otherUserId);
request.setAttribute("privateForecastConfigurationsForOtherUser",
privateForecastConfigurationsForOtherUser);
request.setAttribute("otherUserId", otherUserId);
} catch (NumberFormatException nfe) {
}
catch(NumberFormatException nfe) {}
}
else
{
forecasts = forecastBean.getForecastConfigurations(user.getOrganizationId(), selectedModelIds, from, to);
} else {
forecasts = forecastBean.getForecastConfigurations(user.getOrganizationId(), selectedModelIds, from,
to);
}
Collections.sort(forecasts);
request.setAttribute("currentLanguage", SessionLocaleUtil.getCurrentLocale(request).getLanguage());
request.setAttribute("forecastConfigurations", forecasts);
List<ForecastConfiguration> privateForecasts;
privateForecasts = forecastBean.getPrivateForecastConfigurationsForUser(user.getUserId());
request.setAttribute("privateForecastConfigurations", privateForecasts);
......@@ -183,9 +173,7 @@ public class ForecastConfigurationController extends HttpServlet {
// If this is a redirect from a controller, with a message to be passed on
request.setAttribute("messageKey", request.getParameter("messageKey"));
request.getRequestDispatcher("/forecastConfigurationList.ftl").forward(request, response);
}
else
{
} else {
List<ForecastConfiguration> privateForecasts;
privateForecasts = forecastBean.getPrivateForecastConfigurationsForUser(user.getUserId());
request.setAttribute("privateForecastConfigurations", privateForecasts);
......@@ -193,244 +181,264 @@ public class ForecastConfigurationController extends HttpServlet {
request.setAttribute("messageKey", request.getParameter("messageKey"));
request.getRequestDispatcher("/forecastConfigurationList.ftl").forward(request, response);
}
}
// View and edit a forecast configuration
else if(action.equals("viewForecastConfiguration"))
{
if(userBean.authorizeUser(user, VipsLogicRole.ORGANIZATION_ADMINISTRATOR, VipsLogicRole.SUPERUSER))
{
try
{
else if (action.equals("viewForecastConfiguration")) {
if (userBean.authorizeUser(user, VipsLogicRole.ORGANIZATION_ADMINISTRATOR, VipsLogicRole.SUPERUSER)) {
try {
Long forecastConfigurationId = Long.valueOf(request.getParameter("forecastConfigurationId"));
ForecastConfiguration forecastConfiguration = em.find(ForecastConfiguration.class, forecastConfigurationId);
ForecastConfiguration forecastConfiguration =
em.find(ForecastConfiguration.class, forecastConfigurationId);
boolean multipleNew = false;
// No forecastconfiguration found, assuming user want to register new
if(forecastConfiguration == null)
{
if (forecastConfiguration == null) {
forecastConfiguration = new ForecastConfiguration();
multipleNew = request.getParameter("multipleNew") != null
&& request.getParameter("multipleNew").equals("true");
multipleNew = request.getParameter("multipleNew") != null
&& request.getParameter("multipleNew").equals("true");
}
// Only superusers can view and edit forecasts from other organizations
if(! user.isSuperUser() && forecastConfiguration.getVipsLogicUserId() != null && !forecastConfiguration.getVipsLogicUserId().getOrganizationId().equals(user.getOrganizationId()))
{
response.sendError(403,"Access not authorized"); // HTTP Forbidden
if (!user.isSuperUser() && forecastConfiguration.getVipsLogicUserId() != null
&& !forecastConfiguration.getVipsLogicUserId().getOrganizationId()
.equals(user.getOrganizationId())) {
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
{
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
if(user.isSuperUser())
{
request.setAttribute("locationPointOfInterests", em.createNamedQuery("PointOfInterest.findAll").getResultList());
request.setAttribute("weatherStationPointOfInterests", em.createNamedQuery("PointOfInterestWeatherStation.findAllByActivity").setParameter("active", Boolean.TRUE).getResultList());
request.setAttribute("vipsLogicUsers", em.createNamedQuery("VipsLogicUser.findAll").getResultList());
}
else
{
request.setAttribute("locationPointOfInterests", em.createNamedQuery("PointOfInterest.findByOrganizationId").setParameter("organizationId", user.getOrganizationId()).getResultList());
request.setAttribute("weatherStationPointOfInterests", em.createNamedQuery("PointOfInterestWeatherStation.findByActivityAndOrganizationId").setParameter("active", Boolean.TRUE).setParameter("organizationId", user.getOrganizationId()).getResultList());
request.setAttribute("vipsLogicUsers", em.createNamedQuery("VipsLogicUser.findByOrganizationId").setParameter("organizationId", user.getOrganizationId()).getResultList());
if (user.isSuperUser()) {
request.setAttribute("locationPointOfInterests",
em.createNamedQuery("PointOfInterest.findAll").getResultList());
request.setAttribute("weatherStationPointOfInterests",
em.createNamedQuery("PointOfInterestWeatherStation.findAllByActivity")
.setParameter("active", Boolean.TRUE).getResultList());
request.setAttribute("vipsLogicUsers",
em.createNamedQuery("VipsLogicUser.findAll").getResultList());
} else {
request.setAttribute("locationPointOfInterests",
em.createNamedQuery("PointOfInterest.findByOrganizationId")
.setParameter("organizationId", user.getOrganizationId()).getResultList());
request.setAttribute("weatherStationPointOfInterests",
em.createNamedQuery("PointOfInterestWeatherStation.findByActivityAndOrganizationId")
.setParameter("active", Boolean.TRUE)
.setParameter("organizationId", user.getOrganizationId()).getResultList());
request.setAttribute("vipsLogicUsers",
em.createNamedQuery("VipsLogicUser.findByOrganizationId")
.setParameter("organizationId", user.getOrganizationId()).getResultList());
}
request.setAttribute("currentLanguage", SessionLocaleUtil.getCurrentLocale(request).getLanguage());
request.setAttribute("currentLanguage",
SessionLocaleUtil.getCurrentLocale(request).getLanguage());
request.setAttribute("forecastConfiguration", forecastConfiguration);
request.setAttribute("formId", multipleNew ? "forecastConfigurationMultipleNewForm" : "forecastConfigurationForm");
request.setAttribute("formId",
multipleNew ? "forecastConfigurationMultipleNewForm" : "forecastConfigurationForm");
request.setAttribute("multipleNew", multipleNew);
request.getSession().setAttribute("availableTimeZones", SystemTime.getAvailableTimeZones());
request.getSession().setAttribute("defaultTimeZoneId", user.getOrganizationId().getDefaultTimeZone());
request.getSession().setAttribute("defaultTimeZoneId",
user.getOrganizationId().getDefaultTimeZone());
// All organisms used for parent organism list
request.setAttribute("allCrops", em.createNamedQuery("Organism.findAllCrops").getResultList());
request.setAttribute("allPests", em.createNamedQuery("Organism.findAllPests").getResultList());
// Hierarchy categories
request.setAttribute("hierarchyCategories", organismBean.getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request)));
request.setAttribute("hierarchyCategories",
organismBean.getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request)));
request.setAttribute("modelInformations", forecastBean.getBatchableModels());
request.setAttribute("messageKey", request.getParameter("messageKey"));
request.getRequestDispatcher("/forecastConfigurationForm.ftl").forward(request, response);
}
} catch (NullPointerException | NumberFormatException ex) {
response.sendError(500,
"Invalid forecast configurationId " + request.getParameter("forecastConfigurationId"));
}
catch(NullPointerException | NumberFormatException ex)
{
response.sendError(500, "Invalid forecast configurationId " + request.getParameter("forecastConfigurationId"));
}
}
else
{
} else {
Long forecastConfigurationId = Long.valueOf(request.getParameter("forecastConfigurationId"));
ForecastConfiguration forecastConfiguration = em.find(ForecastConfiguration.class, forecastConfigurationId);
if(forecastConfiguration == null || forecastConfiguration.getVipsLogicUserId().getUserId().equals(user.getUserId()))
{
if(forecastConfiguration == null)
{
ForecastConfiguration forecastConfiguration =
em.find(ForecastConfiguration.class, forecastConfigurationId);
if (forecastConfiguration == null
|| forecastConfiguration.getVipsLogicUserId().getUserId().equals(user.getUserId())) {
if (forecastConfiguration == null) {
forecastConfiguration = new ForecastConfiguration();
forecastConfiguration.setIsPrivate(Boolean.TRUE);
}
request.setAttribute("currentLanguage", SessionLocaleUtil.getCurrentLocale(request).getLanguage());
request.setAttribute("forecastConfiguration", forecastConfiguration);
request.setAttribute("locationPointOfInterests", em.createNamedQuery("PointOfInterest.findByOrganizationId").setParameter("organizationId", user.getOrganizationId()).getResultList());
request.setAttribute("weatherStationPointOfInterests", em.createNamedQuery("PointOfInterestWeatherStation.findByActivityAndOrganizationId").setParameter("active", Boolean.TRUE).setParameter("organizationId", user.getOrganizationId()).getResultList());
request.setAttribute("formId","forecastConfigurationForm");
request.setAttribute("locationPointOfInterests",
em.createNamedQuery("PointOfInterest.findByOrganizationId")
.setParameter("organizationId", user.getOrganizationId()).getResultList());
request.setAttribute("weatherStationPointOfInterests",
em.createNamedQuery("PointOfInterestWeatherStation.findByActivityAndOrganizationId")
.setParameter("active", Boolean.TRUE)
.setParameter("organizationId", user.getOrganizationId()).getResultList());
request.setAttribute("formId", "forecastConfigurationForm");
request.getSession().setAttribute("availableTimeZones", SystemTime.getAvailableTimeZones());
request.getSession().setAttribute("defaultTimeZoneId", user.getOrganizationId().getDefaultTimeZone());
request.getSession().setAttribute("defaultTimeZoneId",
user.getOrganizationId().getDefaultTimeZone());
request.setAttribute("allCrops", em.createNamedQuery("Organism.findAllCrops").getResultList());
request.setAttribute("allPests", em.createNamedQuery("Organism.findAllPests").getResultList());
// Hierarchy categories
request.setAttribute("hierarchyCategories", organismBean.getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request)));
request.setAttribute("modelInformations", em.createNamedQuery("ModelInformation.findAll").getResultList());
request.setAttribute("hierarchyCategories",
organismBean.getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request)));
request.setAttribute("modelInformations",
em.createNamedQuery("ModelInformation.findAll").getResultList());
request.setAttribute("messageKey", request.getParameter("messageKey"));
request.getRequestDispatcher("/forecastConfigurationForm.ftl").forward(request, response);
}
else
{
response.sendError(403,"Access not authorized");
} else {
response.sendError(403, "Access not authorized");
}
}
}
// Store forecast configuration(s)
// Authorization: SUPERUSERS and ORGANIZATION ADMINS
else if(action.equals("forecastConfigurationFormSubmit"))
{
try
{
else if (action.equals("forecastConfigurationFormSubmit")) {
try {
Long forecastConfigurationId = Long.valueOf(request.getParameter("forecastConfigurationId"));
ForecastConfiguration forecastConfiguration = em.find(ForecastConfiguration.class, forecastConfigurationId);
ForecastConfiguration forecastConfiguration =
em.find(ForecastConfiguration.class, forecastConfigurationId);
// No forecastconfiguration found, assuming user want to register new
if(forecastConfiguration == null)
{
if (forecastConfiguration == null) {
forecastConfiguration = new ForecastConfiguration();
}
// Only superusers can view and edit forecasts from other organizations
// Regular users can only edit own forecasts
if(
(! user.isSuperUser() && forecastConfiguration.getVipsLogicUserId() != null && !forecastConfiguration.getVipsLogicUserId().getOrganizationId().equals(user.getOrganizationId()))
|| (! user.isSuperUser() && ! user.isOrganizationAdmin() && forecastConfiguration.getVipsLogicUserId() != null && !forecastConfiguration.getVipsLogicUserId().getUserId().equals(user.getUserId()))
)
{
response.sendError(403,"Access not authorized"); // HTTP Forbidden
}
else
{
String formId = request.getParameter("multipleNew") != null && request.getParameter("multipleNew").equals("true") ?
"forecastConfigurationMultipleNewForm"
:"forecastConfigurationForm";
FormValidation formValidation = FormValidator.validateForm(formId,request,getServletContext());
if ((!user.isSuperUser() && forecastConfiguration.getVipsLogicUserId() != null
&& !forecastConfiguration.getVipsLogicUserId().getOrganizationId()
.equals(user.getOrganizationId()))
|| (!user.isSuperUser() && !user.isOrganizationAdmin()
&& forecastConfiguration.getVipsLogicUserId() != null
&& !forecastConfiguration.getVipsLogicUserId().getUserId().equals(user.getUserId()))) {
response.sendError(403, "Access not authorized"); // HTTP Forbidden
} else {
String formId = request.getParameter("multipleNew") != null
&& request.getParameter("multipleNew").equals("true")
? "forecastConfigurationMultipleNewForm"
: "forecastConfigurationForm";
FormValidation formValidation = FormValidator.validateForm(formId, request, getServletContext());
LOGGER.debug("formValidation=" + formValidation.isValid());
// Also validation the model specific fields
String modelId = formValidation.getFormField("modelId").getWebValue();
FormValidation modelFieldFormValidation = FormValidator.validateForm("models/" + modelId, request, getServletContext());
FormValidation modelFieldFormValidation =
FormValidator.validateForm("models/" + modelId, request, getServletContext());
// Additional input check: If the Grid data checkbox is not checked, a
if(formValidation.isValid() && modelFieldFormValidation.isValid())
{
if(formId.equals("forecastConfigurationForm"))
{
if (formValidation.isValid() && modelFieldFormValidation.isValid()) {
if (formId.equals("forecastConfigurationForm")) {
// Ensure regular users always enter private forecasts
if(! userBean.authorizeUser(user, VipsLogicRole.ORGANIZATION_ADMINISTRATOR, VipsLogicRole.SUPERUSER))
{
if (!userBean.authorizeUser(user, VipsLogicRole.ORGANIZATION_ADMINISTRATOR,
VipsLogicRole.SUPERUSER)) {
formValidation.getFormField("isPrivate").setWebValue("true");
}
forecastConfiguration = forecastBean.storeForecastConfiguration(forecastConfiguration, formValidation.getFormFields(), modelFieldFormValidation.getFormFields());
forecastConfiguration = forecastBean.storeForecastConfiguration(forecastConfiguration,
formValidation.getFormFields(), modelFieldFormValidation.getFormFields());
// Store form config
//forecastBean.storeForecastModelConfigurations(forecastConfiguration, modelFieldFormValidation.getFormFields());
// forecastBean.storeForecastModelConfigurations(forecastConfiguration,
// modelFieldFormValidation.getFormFields());
// TODO: Store model specific fields
// First: Delete all o
request.setAttribute("messageKey", request.getParameter("formConfigurationUpdated"));
response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://").append(ServletUtil.getServerName(request)).append("/forecastConfiguration?action=viewForecastConfiguration&forecastConfigurationId=").append(forecastConfiguration.getForecastConfigurationId()).append("&messageKey=").append("forecastConfigurationUpdated").toString());
}
else
{
for(String optionVal:formValidation.getFormField("weatherStationPointOfInterestIds").getWebValues())
{
response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://")
.append(ServletUtil.getServerName(request))
.append("/forecastConfiguration?action=viewForecastConfiguration&forecastConfigurationId=")
.append(forecastConfiguration.getForecastConfigurationId()).append("&messageKey=")
.append("forecastConfigurationUpdated").toString());
} else {
for (String optionVal : formValidation.getFormField("weatherStationPointOfInterestIds")
.getWebValues()) {
Integer weatherStationPointOfInterestId = Integer.valueOf(optionVal);
forecastBean.storeNewMultipleForecastConfiguration(weatherStationPointOfInterestId, formValidation.getFormFields(), modelFieldFormValidation.getFormFields());
forecastBean.storeNewMultipleForecastConfiguration(weatherStationPointOfInterestId,
formValidation.getFormFields(), modelFieldFormValidation.getFormFields());
}
request.setAttribute("messageKey", request.getParameter("multipleForecastConfigurationsCreated"));
response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://").append(ServletUtil.getServerName(request)).append("/forecastConfiguration?messageKey=").append("multipleForecastConfigurationsCreated").toString());
request.setAttribute("messageKey",
request.getParameter("multipleForecastConfigurationsCreated"));
response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://")
.append(ServletUtil.getServerName(request))
.append("/forecastConfiguration?messageKey=")
.append("multipleForecastConfigurationsCreated").toString());
}
}
else
{
} else {
// Return to form with error messages
request.setAttribute("formValidation", formValidation);
// We must get date formats!
Map<String, FormField> formFields = FormValidator.getFormFields("forecastConfigurationForm",getServletContext());
Map<String, FormField> formFields =
FormValidator.getFormFields("forecastConfigurationForm", getServletContext());
// TODO: More intelligent selection of locations, weather stations and users
request.setAttribute("locationPointOfInterests", em.createNamedQuery("PointOfInterest.findAll").getResultList());
request.setAttribute("weatherStationPointOfInterests", em.createNamedQuery("PointOfInterestWeatherStation.findAll").getResultList());
request.setAttribute("vipsLogicUsers", em.createNamedQuery("VipsLogicUser.findAll").getResultList());
request.setAttribute("formId", "forecastConfigurationForm");
request.setAttribute("allCrops", em.createNamedQuery("Organism.findAllCrops").getResultList());
request.setAttribute("allPests", em.createNamedQuery("Organism.findAllPests").getResultList());
request.setAttribute("locationPointOfInterests",
em.createNamedQuery("PointOfInterest.findAll").getResultList());
request.setAttribute("weatherStationPointOfInterests",
em.createNamedQuery("PointOfInterestWeatherStation.findAll").getResultList());
request.setAttribute("vipsLogicUsers",
em.createNamedQuery("VipsLogicUser.findAll").getResultList());
request.setAttribute("dateStart_dateFormat", formFields.get("dateStart").getDateFormat());
request.setAttribute("dateEnd_dateFormat", formFields.get("dateEnd").getDateFormat());
request.getSession().setAttribute("availableTimeZones", SystemTime.getAvailableTimeZones());
request.getSession().setAttribute("defaultTimeZoneId", user.getOrganizationId().getDefaultTimeZone());
request.setAttribute("modelInformations", em.createNamedQuery("ModelInformation.findAll").getResultList());
request.setAttribute("currentLanguage", SessionLocaleUtil.getCurrentLocale(request).getLanguage());
request.getSession().setAttribute("defaultTimeZoneId",
user.getOrganizationId().getDefaultTimeZone());
// Hierarchy categories
request.setAttribute("hierarchyCategories",
organismBean.getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request)));
request.setAttribute("modelInformations",
em.createNamedQuery("ModelInformation.findAll").getResultList());
request.setAttribute("currentLanguage",
SessionLocaleUtil.getCurrentLocale(request).getLanguage());
request.setAttribute("forecastConfiguration", forecastConfiguration);
request.getRequestDispatcher("/forecastConfigurationForm.ftl").forward(request, response);
}
}
}
catch(NullPointerException | NumberFormatException | FormValidationException ex)
{
} catch (NullPointerException | NumberFormatException | FormValidationException ex) {
ex.printStackTrace();
if(ex instanceof NumberFormatException)
{
response.sendError(500, "Invalid forecast configurationId " + request.getParameter("forecastConfigurationId"));
}
else
{
if (ex instanceof NumberFormatException) {
response.sendError(500,
"Invalid forecast configurationId " + request.getParameter("forecastConfigurationId"));
} else {
response.sendError(500, ex.getMessage());
}
}
}
// Delete forecast configuration
// Authorization: SUPERUSERS and ORGANIZATION ADMINS OR regular users owning the forecast config
else if(action.equals("deleteForecastConfiguration"))
{
else if (action.equals("deleteForecastConfiguration")) {
Long forecastConfigurationId = Long.valueOf(request.getParameter("forecastConfigurationId"));
ForecastConfiguration forecastConfiguration = em.find(ForecastConfiguration.class, forecastConfigurationId);
if(
userBean.authorizeUser(user, VipsLogicRole.ORGANIZATION_ADMINISTRATOR, VipsLogicRole.SUPERUSER)
|| user.getUserId().equals(forecastConfiguration.getVipsLogicUserId().getUserId())
)
{
if (userBean.authorizeUser(user, VipsLogicRole.ORGANIZATION_ADMINISTRATOR, VipsLogicRole.SUPERUSER)
|| user.getUserId().equals(forecastConfiguration.getVipsLogicUserId().getUserId())) {
// Only superusers can delete forecasts from other organizations
if(! user.isSuperUser() && forecastConfiguration.getVipsLogicUserId() != null && !forecastConfiguration.getVipsLogicUserId().getOrganizationId().equals(user.getOrganizationId()))
{
response.sendError(403,"Access not authorized"); // HTTP Forbidden
if (!user.isSuperUser() && forecastConfiguration.getVipsLogicUserId() != null && !forecastConfiguration
.getVipsLogicUserId().getOrganizationId().equals(user.getOrganizationId())) {
response.sendError(403, "Access not authorized"); // HTTP Forbidden
return;
}
try
{
try {
forecastBean.deleteForecastConfiguration(forecastConfigurationId);
response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://").append(ServletUtil.getServerName(request)).append("/forecastConfiguration?").append("&messageKey=").append("forecastConfigurationDeleted").toString());
}
catch(NullPointerException | NumberFormatException ex)
{
response.sendError(500, "Invalid forecast configurationId " + request.getParameter("forecastConfigurationId"));
response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://")
.append(ServletUtil.getServerName(request)).append("/forecastConfiguration?")
.append("&messageKey=").append("forecastConfigurationDeleted").toString());
} catch (NullPointerException | NumberFormatException ex) {
response.sendError(500,
"Invalid forecast configurationId " + request.getParameter("forecastConfigurationId"));
}
}
else
{
response.sendError(403,"Access not authorized"); // HTTP Forbidden
} else {
response.sendError(403, "Access not authorized"); // HTTP Forbidden
}
}
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the
// code.">
/**
* Handles the HTTP <code>GET</code> method.
*
......
......@@ -38,23 +38,27 @@
<script type="module">
import MapModal from '/js/mapModal.js';
const selectLocationElement = document.querySelector('select[name="locationPointOfInterestId"]');
const selectWeatherstationElement = document.querySelector('select[name="weatherStationPointOfInterestId"]') != null ? document.querySelector('select[name="weatherStationPointOfInterestId"]') : document.querySelector('select[name="weatherStationPointOfInterestIdDisabled"]');
console.info(selectWeatherstationElement);
window.selectedPoiId = <#if forecastConfiguration.locationPointOfInterestId??>${forecastConfiguration.locationPointOfInterestId.pointOfInterestId!"undefined"}<#else>undefined</#if>;
window.selectedWeatherstationId = <#if forecastConfiguration.weatherStationPointOfInterestId??>${forecastConfiguration.weatherStationPointOfInterestId.pointOfInterestId!"undefined"}<#else>undefined</#if>;
// Read the list of locations into javascript array, to be able to dynamically manipulate it
let locationList = [
window.locationList = [
<#list locationPointOfInterests as poi>
{
"pointOfInterestId": "${poi.pointOfInterestId}",
"name": "${poi.name?json_string}"
"name": "${poi.name?json_string}",
"pointOfInterestTypeId": ${poi.pointOfInterestTypeId}
},
</#list>
];
renderPoiSelect(selectLocationElement, locationList);
// Populate select list for point of interest -> NOT GENERAL! Default value is specific to location.
function renderPoiSelect(selectElement, elementList, selectedId) {
selectElement.innerHTML = '';
const createOption = (value, text, isSelected = false) => {
const createOption = (value, text, isSelected = false) => {
const option = document.createElement('option');
option.value = value;
option.textContent = text;
......@@ -62,6 +66,50 @@
return option;
};
renderPoiSelect(selectLocationElement, locationList, selectedPoiId);
renderWeatherstationSelect(selectWeatherstationElement, locationList, selectedWeatherstationId);
// Setting weather station select list state correct on page load
<#if isGridForecastSupported>
handleUseGridWeatherDataClicked(document.getElementById("useGridWeatherData")<#if forecastConfiguration.weatherStationPointOfInterestId?has_content && forecastConfiguration.weatherStationPointOfInterestId.pointOfInterestId?has_content>,${forecastConfiguration.weatherStationPointOfInterestId.pointOfInterestId}</#if>);
</#if>
function renderWeatherstationSelect(selectElement, elementList, selectedId)
{
selectElement.options.length = 0;
<#if isGridForecastSupported>
// Add default option
selectElement.appendChild(createOption(
"-2",
"${i18nBundle.doNotUse} ${i18nBundle.weatherStationPointOfInterestId?lower_case}",
!selectedId
));
</#if>
// Add default option
selectElement.appendChild(createOption(
"-1",
"${i18nBundle.pleaseSelect} ${i18nBundle.weatherStationPointOfInterestId?lower_case}",
!selectedId
));
// Add all locations that are weatherstations
elementList.forEach(poi => {
if(poi.pointOfInterestTypeId == POI_TYPE_WEATHERSTATION)
{
selectElement.appendChild(createOption(
poi.pointOfInterestId,
poi.name,
selectedId && poi.pointOfInterestId == selectedId
));
}
});
}
// Populate select list for point of interest -> NOT GENERAL! Default value is specific to location.
function renderPoiSelect(selectElement, elementList, selectedId) {
selectElement.innerHTML = '';
// Add default option
selectElement.appendChild(createOption(
"-1",
......@@ -79,7 +127,7 @@
});
}
function selectPoi(selectElement, selectedId) {
window.selectPoi = function(selectElement, selectedId) {
if (selectedId) {
const optionIndex = Array.from(selectElement.options).findIndex(option => option.value == selectedId);
if (optionIndex !== -1) {
......@@ -103,6 +151,7 @@
} else {
selectPoi(selectLocationElement, poiData.pointOfInterestId);
}
handleLocationChanged();
}
function persistNewLocation(poiData) {
......@@ -119,6 +168,8 @@
.then(poi => {
locationList.push(poi);
renderPoiSelect(selectLocationElement, locationList, poi.pointOfInterestId);
// Assuming that this is not a weather station, since weather stations cannot be created using the
// map, the user must have created a .... MAYBE HANDLED AUTOMATICALLY?? by the change event??
console.info("Point of interest successfully persisted", poi);
})
.catch(error => {
......@@ -152,6 +203,7 @@
</script>
<script type="text/javascript">
const POI_TYPE_WEATHERSTATION = 1;
$(document).ready(function() {
// Make sure that there is a date picker present for HTML5
// date input fields
......@@ -309,7 +361,7 @@
}
}
};
var handleUseGridWeatherDataClicked = function(theCheckBox, weatherStationPointOfInterestId) {
window.handleUseGridWeatherDataClicked = function(theCheckBox, weatherStationPointOfInterestId) {
weatherStationList = document.getElementById("weatherStationPointOfInterestId");
weatherStationPointOfInterestIdHiddenField = document.getElementById("weatherStationPointOfInterestIdHidden");
if(theCheckBox.checked)
......@@ -347,18 +399,35 @@
}
};
// Setting weather station select list state correct on page load
<#if isGridForecastSupported>
handleUseGridWeatherDataClicked(document.getElementById("useGridWeatherData")<#if forecastConfiguration.weatherStationPointOfInterestId?has_content && forecastConfiguration.weatherStationPointOfInterestId.pointOfInterestId?has_content>,${forecastConfiguration.weatherStationPointOfInterestId.pointOfInterestId}</#if>);
</#if>
let handleLocationChanged = function(){
// Which location has been selected?
let selectedPoiId = document.getElementById("locationPointOfInterestId").options[document.getElementById("locationPointOfInterestId").selectedIndex].value;
if(selectedPoiId <= 0)
{
document.getElementById("weatherDatasourceFieldset").disabled = true;
weatherstationSelect.selectedIndex = 0;
return;
}
// Enable the weather datasource fieldset
document.getElementById("weatherDatasourceFieldset").disabled=false;
// Which location has been selected?
// If weather station -> Preselect weather station, set grid checkbox to false
// Else: Deselect weather station (if any), set grid checkbox to true
let selectedLocation = undefined;
for(let i=0; i<locationList.length;i++)
{
if(locationList[i].pointOfInterestId == selectedPoiId)
{
selectedLocation = locationList[i];
}
}
<#if isGridForecastSupported>
let gridCheckBox = document.getElementById("useGridWeatherData");
gridCheckBox.checked = (selectedLocation.pointOfInterestTypeId != POI_TYPE_WEATHERSTATION);
handleUseGridWeatherDataClicked(gridCheckBox, (selectedLocation.pointOfInterestTypeId == POI_TYPE_WEATHERSTATION ? selectedLocation.pointOfInterestId: undefined));
</#if>
}
</script>
</#macro>
......@@ -451,22 +520,15 @@
</div>
<span class="help-block" id="${formId}_locationPointOfInterestId_validation"></span>
</div>
<fieldset id="weatherDatasourceFieldset" disabled>
<legend>${i18nBundle.weatherDatasource}</legend>
<p>Velg sted ovenfor først, og velg deretter værdatakilde.</p>
<div class="alert alert-info" role="alert">Velg sted ovenfor først, og velg deretter værdatakilde. Du kan enten velge en av de tilgjengelige værstasjonene,
eller at ditt valgte steds plassering brukes til å hente værdata fra en ekstern tjeneste. Hvis ditt sted ligger nær
en av værstasjonene, gir det som oftest den beste kvaliteten på værdata.</div>
<fieldset id="weatherDatasourceFieldset" <#if !forecastConfiguration.weatherStationPointOfInterestId?has_content>disabled</#if>>
<legend style="margin-bottom: 0px;">${i18nBundle.weatherDatasource}</legend>
<div class="form-group">
<label for="weatherStationPointOfInterestId">${i18nBundle.weatherStationPointOfInterestId}</label>
<select class="form-control" id="weatherStationPointOfInterestId" name="weatherStationPointOfInterestId" onblur="if(!document.getElementById('useGridWeatherData').checked) {validateField(this);}">
<#if isGridForecastSupported>
<option value="-2">${i18nBundle.doNotUse} ${i18nBundle.weatherStationPointOfInterestId?lower_case}</option>
</#if>
<option value="-1"<#if !forecastConfiguration.weatherStationPointOfInterestId?has_content && !forecastConfiguration.useGridWeatherData> selected="selected"</#if>>${i18nBundle.pleaseSelect} ${i18nBundle.weatherStationPointOfInterestId?lower_case}</option>
<#list weatherStationPointOfInterests?sort_by("name") as poi>
<option value="${poi.pointOfInterestId}"<#if
forecastConfiguration.weatherStationPointOfInterestId?has_content
&& forecastConfiguration.weatherStationPointOfInterestId.pointOfInterestId?has_content
&& poi.pointOfInterestId == forecastConfiguration.weatherStationPointOfInterestId.pointOfInterestId> selected="selected"</#if>>${poi.name}</option>
</#list>
</select>
<span class="help-block" id="${formId}_weatherStationPointOfInterestId_validation"></span>
</div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment