From a06df64deebe24dffe0278ba71b6f86b86d15f3b Mon Sep 17 00:00:00 2001 From: Tor-Einar Skog <tor-einar.skog@nibio.no> Date: Wed, 24 May 2017 11:05:31 -0700 Subject: [PATCH] Made sure all poi names are unique --- .../servlet/PointOfInterestController.java | 14 +++++++++++++- .../session/PointOfInterestBean.java | 14 ++++++++++++++ .../vips/logic/entity/PointOfInterest.java | 1 + .../vips/logic/service/LogicService.java | 9 +++++++++ .../vips/logic/i18n/vipslogictexts.properties | 1 + .../logic/i18n/vipslogictexts_bs.properties | 1 + .../logic/i18n/vipslogictexts_hr.properties | 1 + .../logic/i18n/vipslogictexts_nb.properties | 1 + .../logic/i18n/vipslogictexts_sr.properties | 1 + .../i18n/vipslogictexts_zh_CN.properties | 1 + src/main/webapp/templates/poiForm.ftl | 19 ++++++++++++++++++- 11 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/PointOfInterestController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/PointOfInterestController.java index 460e8faf..e0c9a16c 100755 --- a/src/main/java/no/nibio/vips/logic/controller/servlet/PointOfInterestController.java +++ b/src/main/java/no/nibio/vips/logic/controller/servlet/PointOfInterestController.java @@ -47,6 +47,7 @@ import no.nibio.vips.logic.util.SessionControllerGetter; import no.nibio.vips.util.ExceptionUtil; import no.nibio.vips.util.ServletUtil; import no.nibio.vips.logic.entity.WeatherForecastProvider; +import no.nibio.vips.logic.i18n.SessionLocaleUtil; import no.nibio.vips.logic.util.GISUtil; import no.nibio.vips.logic.util.Globals; import no.nibio.web.forms.FormField; @@ -593,7 +594,8 @@ public class PointOfInterestController extends HttpServlet { ) { FormValidation formValidation = FormValidator.validateForm("poiForm", request, getServletContext()); - if(formValidation.isValid()) + Boolean poiNameAlreadyExists = SessionControllerGetter.getPointOfInterestBean().getPointOfInterest(formValidation.getFormField("name").getWebValue()) != null; + if(formValidation.isValid() && ! poiNameAlreadyExists) { // Set values poi.setName(formValidation.getFormField("name").getWebValue()); @@ -694,15 +696,25 @@ public class PointOfInterestController extends HttpServlet { } else { + if(poiNameAlreadyExists) + { + FormField poiNameField = formValidation.getFormField("name"); + poiNameField.setValid(false); + poiNameField.setValidationMessage(SessionLocaleUtil.getI18nBundle(request).getString("nameAlreadyExists")); + } request.setAttribute("formValidation", formValidation); request.setAttribute("poi", poi); request.setAttribute("defaultMapCenter",user.getOrganizationId().getDefaultMapCenter()); request.setAttribute("defaultMapZoom", user.getOrganizationId().getDefaultMapZoom()); + request.setAttribute("returnURL","poi?organizationId=" + user.getOrganizationId().getOrganizationId()); + // Finding all external resources where entry is missing + request.setAttribute("unreferencedExternalResources", SessionControllerGetter.getPointOfInterestBean().getUnusedExternalResourcesForPointOfInterest(poi)); request.getSession().setAttribute("availableTimeZones", Globals.availableTimeZones); request.getSession().setAttribute("defaultTimeZoneId", user.getOrganizationId().getDefaultTimeZone()); request.getSession().setAttribute("availableCountries", em.createNamedQuery("Country.findAll").getResultList()); request.getSession().setAttribute("defaultCountryCode", user.getOrganizationId().getCountryCode().getCountryCode()); request.getRequestDispatcher("/poiForm.ftl").forward(request, response); + } } else diff --git a/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java b/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java index c8db2dfe..51e459f7 100755 --- a/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/PointOfInterestBean.java @@ -441,5 +441,19 @@ public class PointOfInterestBean { .getResultList(); } + public PointOfInterest getPointOfInterest(String poiName) { + try + { + return em.createNamedQuery("PointOfInterest.findByNameCaseInsensitive", PointOfInterest.class) + .setParameter("name", poiName) + .getSingleResult(); + } + catch(NoResultException ex) + { + return null; + } + + } + } 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 81088def..1ad8f99e 100755 --- a/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java +++ b/src/main/java/no/nibio/vips/logic/entity/PointOfInterest.java @@ -66,6 +66,7 @@ import no.nibio.vips.logic.util.GISUtil; @NamedQuery(name = "PointOfInterest.findByOrganizationId", query = "SELECT p FROM PointOfInterest p WHERE p.userId IN(SELECT u.userId FROM VipsLogicUser u WHERE u.organizationId=:organizationId OR u.organizationId IN (SELECT o.organizationId FROM Organization o WHERE o.parentOrganizationId = :organizationId)) ORDER BY p.name ASC"), @NamedQuery(name = "PointOfInterest.findForecastLocationsByOrganizationId", query = "SELECT p FROM PointOfInterest p WHERE p.isForecastLocation IS TRUE AND p.userId IN(SELECT u.userId FROM VipsLogicUser u WHERE u.organizationId=:organizationId OR u.organizationId IN (SELECT o.organizationId FROM Organization o WHERE o.parentOrganizationId = :organizationId)) ORDER BY p.name ASC"), @NamedQuery(name = "PointOfInterest.findByName", query = "SELECT p FROM PointOfInterest p WHERE p.name = :name"), + @NamedQuery(name = "PointOfInterest.findByNameCaseInsensitive", query = "SELECT p FROM PointOfInterest p WHERE lower(p.name) = lower(:name)"), //@NamedQuery(name = "PointOfInterest.findByLongitude", query = "SELECT p FROM PointOfInterest p WHERE p.longitude = :longitude"), //@NamedQuery(name = "PointOfInterest.findByLatitude", query = "SELECT p FROM PointOfInterest p WHERE p.latitude = :latitude"), //@NamedQuery(name = "PointOfInterest.findByAltitude", query = "SELECT p FROM PointOfInterest p WHERE p.altitude = :altitude"), 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 fd408e04..c68cfc90 100755 --- a/src/main/java/no/nibio/vips/logic/service/LogicService.java +++ b/src/main/java/no/nibio/vips/logic/service/LogicService.java @@ -369,6 +369,15 @@ public class LogicService { return Response.ok().entity(retVal).build(); } + @GET + @Path("poi/name/{poiName}") + @Produces("application/json;charset=UTF-8") + public Response getPoiByName(@PathParam("poiName") String poiName) + { + PointOfInterest retVal = SessionControllerGetter.getPointOfInterestBean().getPointOfInterest(poiName); + return retVal != null ? Response.ok().entity(retVal).build() : Response.noContent().build(); + } + @GET @Path("poi/user/") @Produces("application/json;charset=UTF-8") 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 1868bb39..373038dc 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties @@ -441,3 +441,4 @@ isRequiredField=Required field crops=Crops unknownOrganismId=Unknown Organism Id vipsLogicRole_7=Organism editor +nameAlreadyExists=The name already exists 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 dc6f450a..b5beee4a 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_bs.properties @@ -441,3 +441,4 @@ isRequiredField=Required field crops=Crops unknownOrganismId=Unknown Organism Id vipsLogicRole_7=Organism editor +nameAlreadyExists=The name already exists 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 0b9d1157..dfc93238 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_hr.properties @@ -440,3 +440,4 @@ isRequiredField=Required field crops=Crops unknownOrganismId=Unknown Organism Id vipsLogicRole_7=Organism editor +nameAlreadyExists=The name already exists 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 216d3ba0..3cea3335 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties @@ -441,3 +441,4 @@ isRequiredField=Obligatorisk felt crops=Kulturer unknownOrganismId=Ukjent organismeId vipsLogicRole_7=Organismeredakt\u00f8r +nameAlreadyExists=Navnet er allerede i bruk 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 8e3b9971..cca159c3 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_sr.properties @@ -441,3 +441,4 @@ isRequiredField=Required field crops=Crops unknownOrganismId=Unknown Organism Id vipsLogicRole_7=Organism editor +nameAlreadyExists=The name already exists diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties index 6c324faa..4dfd6a77 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_zh_CN.properties @@ -438,3 +438,4 @@ isRequiredField=Required field crops=Crops unknownOrganismId=Unknown Organism Id vipsLogicRole_7=Organism editor +nameAlreadyExists=The name already exists diff --git a/src/main/webapp/templates/poiForm.ftl b/src/main/webapp/templates/poiForm.ftl index a72bfaa1..80bc9bd0 100755 --- a/src/main/webapp/templates/poiForm.ftl +++ b/src/main/webapp/templates/poiForm.ftl @@ -41,6 +41,23 @@ initMap([${defaultMapCenter.x?c},${defaultMapCenter.y?c}],${defaultMapZoom},${user.organizationId.organizationId},${poi.pointOfInterestId!"null"}); </#if> }); + + // POI name must be unique + function checkPoiNameAvailability(poiNameField) + { + var poiName = poiNameField.value; + if(poiName.length > 0) + { + $.getJSON( "/rest/poi/name/" + poiName) + .done(function(json, status, jx){ + if(jx.status==200) + { + var theForm = document.getElementById("poiForm"); + invalidizeField(poiNameField, theForm, "${i18nBundle.nameAlreadyExists}",null); + } + }); + } + } </script> </#macro> <#macro page_contents> @@ -61,7 +78,7 @@ <input type="hidden" name="pointOfInterestId" value="${poi.pointOfInterestId!"-1"}"/> <div class="form-group"> <label for="name">${i18nBundle.name}</label> - <input type="text" class="form-control" name="name" placeholder="${i18nBundle.name}" value="${(poi.name)!""}" onblur="validateField(this);"/> + <input type="text" class="form-control" name="name" placeholder="${i18nBundle.name}" value="${(poi.name)!""}" onblur="validateField(this); checkPoiNameAvailability(this);"/> <span class="help-block" id="${formId}_name_validation"></span> </div> <div class="form-group"> -- GitLab