diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/MessageController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/MessageController.java index afb15eee363f69bac4fc9da51d7034de3742c31d..dd5592e4c44b18b1ccbbd2358fd313ec9ce9fac6 100644 --- a/src/main/java/no/nibio/vips/logic/controller/servlet/MessageController.java +++ b/src/main/java/no/nibio/vips/logic/controller/servlet/MessageController.java @@ -158,7 +158,6 @@ public class MessageController extends HttpServlet { { Integer messageId = Integer.valueOf(request.getParameter("messageId")); Message message = em.find(Message.class, messageId); - message.setMessageCropOrganismIds(SessionControllerGetter.getMessageBean().getMessageCropOrganismIds(message)); request.setAttribute("message", message); String messageLocale = request.getParameter("messageLocale") != null ? request.getParameter("messageLocale") @@ -213,7 +212,7 @@ public class MessageController extends HttpServlet { request.setAttribute("unusedTags", tags); request.setAttribute("messageKey", request.getParameter("messageKey")); request.setAttribute("organizations", SessionControllerGetter.getUserBean().getOrganizations()); - request.setAttribute("allCrops", em.createNamedQuery("Organism.findAllCrops").getResultList()); + request.setAttribute("allCropCategoryIds", em.createNamedQuery("CropCategory.findByOrganizationId").setParameter("organizationId",user.getOrganizationId().getOrganizationId()).getResultList()); request.getRequestDispatcher("/messageForm.ftl").forward(request, response); } catch(NullPointerException | NumberFormatException ex) @@ -241,13 +240,18 @@ public class MessageController extends HttpServlet { request.setAttribute("availableLocales", LanguageUtil.getAvailableLocalesWithDistinctLanguage()); request.setAttribute("unusedTags", em.createNamedQuery("MessageTag.findAll").getResultList()); request.setAttribute("organizations", SessionControllerGetter.getUserBean().getOrganizations()); - request.setAttribute("allCrops", em.createNamedQuery("Organism.findAllCrops").getResultList()); + request.setAttribute("allCropCategoryIds", em.createNamedQuery("CropCategory.findByOrganizationId").setParameter("organizationId",user.getOrganizationId().getOrganizationId()).getResultList()); request.getRequestDispatcher("/messageForm.ftl").forward(request, response); } catch(NullPointerException | NumberFormatException ex) { + ex.printStackTrace(); response.sendError(500, ExceptionUtil.getStackTrace(ex)); } + catch(Exception ex) + { + ex.printStackTrace(); + } } else if(action.equals("messageFormSubmit")) { 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 da528cf17523bb4742763de5aca782246603c8b3..e9705b23f1e37c47968e23aaa00323354c8347f7 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 @@ -744,12 +744,18 @@ public class ForecastBean { .append(" TRUNCATE forecast_result_cache;") .append(" INSERT INTO forecast_result_cache ") .append(" SELECT * FROM forecast_result ") - .append(" WHERE to_char(result_valid_time, '").append(dateFormat).append("') = :dateStr ;") + .append(" WHERE to_char(result_valid_time, '").append(dateFormat).append("') = :dateStr ") + .append(" AND forecast_configuration_id IN (") + .append(" SELECT forecast_configuration_id ") + .append(" FROM public.forecast_configuration ") + .append(" WHERE date_start <= :currentDate AND date_end >= :currentDate") + .append(" );") .append("END;") .toString(); Query query = em.createNativeQuery(transactionSQL); query.setParameter("dateStr", format.format(SystemTime.getSystemTime())); + query.setParameter("currentDate", SystemTime.getSystemTime()); query.executeUpdate(); } @@ -761,8 +767,10 @@ public class ForecastBean { { // // Collect all forecasts that are active TODAY - List<ForecastConfiguration> activeForecasts = em.createNamedQuery("ForecastConfiguration.findActiveAtDate") + // This + List<ForecastConfiguration> activeForecasts = em.createNamedQuery("ForecastConfiguration.findAllActiveAtDate") .setParameter("currentDate", currentDate).getResultList(); + // Loop through them List<Long> activeForecastIds = new ArrayList<>(); Query deleteQ = em.createNativeQuery( @@ -921,7 +929,7 @@ public class ForecastBean { (cropOrganismIds != null && ! cropOrganismIds.isEmpty() ? " AND crop_organism_id IN (" + StringUtils.join(cropOrganismIds, ",") + ") " : "") + ")\n" + "AND to_char(result_valid_time, '" + dateFormat + "') = :dateStr"; - + //System.out.println(poi.getName() + " SQL=" + sql); Query q = em.createNativeQuery(sql); q.setParameter("locationPointOfInterestId", poi.getPointOfInterestId()); q.setParameter("dateStr", format.format(theDate)); diff --git a/src/main/java/no/nibio/vips/logic/controller/session/MessageBean.java b/src/main/java/no/nibio/vips/logic/controller/session/MessageBean.java index 15a486d1788870f077cec468150a404330c7f2be..8e3a1f694b68cac13c51012bec76ee20d0743b75 100644 --- a/src/main/java/no/nibio/vips/logic/controller/session/MessageBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/MessageBean.java @@ -95,21 +95,7 @@ public class MessageBean { } - /** - * Crops are not part of persistence scheme for performance reasons. - * Must be added manually - * @param messages - * @return - */ - public List<Message> addMessageOrganismIds(List<Message> messages) - { - // Need to add all crops - for(Message message:messages) - { - message.setMessageCropOrganismIds(this.getMessageCropOrganismIds(message)); - } - return messages; - } + public List<Message> getMessageList(Integer organizationId) { Organization mainOrg = em.find(Organization.class, organizationId); @@ -193,18 +179,16 @@ public class MessageBean { message.setMessageTagSet(tags); // Store message organisms - List<Integer> cropOrganismIds = new ArrayList<>(); - if(formFields.get("cropOrganismIds").getWebValues() != null) + List<Integer> cropCategoryIds = new ArrayList<>(); + if(formFields.get("cropCategoryIds").getWebValues() != null) { - for(String cropOrganismId:formFields.get("cropOrganismIds").getWebValues()) + for(String cropCategoryId:formFields.get("cropCategoryIds").getWebValues()) { - cropOrganismIds.add(Integer.valueOf(cropOrganismId)); + cropCategoryIds.add(Integer.valueOf(cropCategoryId)); } } - message.setMessageCropOrganismIds(cropOrganismIds); - // This property is not part of the automatic persistence scheme, need - // to store manually - this.storeMessageOrganismIds(message); + message.setCropCategoryIds(cropCategoryIds.toArray(new Integer[cropCategoryIds.size()])); + return message; } @@ -455,24 +439,5 @@ public class MessageBean { } } - /** - * - * @param message - */ - public void storeMessageOrganismIds(Message message) - { - if(message.getMessageCropOrganismIds() != null) - { - Query q = em.createNativeQuery("DELETE FROM public.organism_message WHERE message_id = :messageId"); - q.setParameter("messageId", message.getMessageId()); - q.executeUpdate(); - q = em.createNativeQuery("INSERT INTO public.organism_message(organism_id, message_id) VALUES(:organismId,:messageId);"); - q.setParameter("messageId", message.getMessageId()); - for(Integer organismId : message.getMessageCropOrganismIds()) - { - q.setParameter("organismId", organismId); - q.executeUpdate(); - } - } - } + } diff --git a/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java b/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java index 5adfe7915673526377a87ba50b4c6cc62696d16c..b29fac85526c4475857ec8132c3ff9e5b4a9e120 100644 --- a/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java +++ b/src/main/java/no/nibio/vips/logic/controller/session/OrganismBean.java @@ -21,6 +21,7 @@ package no.nibio.vips.logic.controller.session; import com.ibm.icu.util.ULocale; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -29,6 +30,7 @@ import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.PersistenceContext; import javax.persistence.Query; +import no.nibio.vips.logic.entity.CropCategory; import no.nibio.vips.logic.entity.CropPest; import no.nibio.vips.logic.entity.ExternalResource; import no.nibio.vips.logic.entity.ExternalResourceType; @@ -37,6 +39,7 @@ import no.nibio.vips.logic.entity.Organism; import no.nibio.vips.logic.entity.OrganismExternalResource; import no.nibio.vips.logic.entity.OrganismLocale; import no.nibio.vips.logic.entity.OrganismLocalePK; +import no.nibio.vips.logic.entity.Organization; import no.nibio.vips.logic.util.HierarchyCategoryLocaleNames; /** @@ -303,4 +306,34 @@ public class OrganismBean { { return em.merge(cropPest); } + + public List<Integer> getCropCategoryOrganismIds(List<Integer> cropCategoryIds) { + List<CropCategory> cropCategories = em.createNamedQuery("CropCategory.findByCropCategoryIds") + .setParameter("cropCategoryIds", cropCategoryIds) + .getResultList(); + List<Integer> retVal = new ArrayList<>(); + for(CropCategory cc:cropCategories) + { + if(cc.getCropOrganismIds() != null) + { + retVal.addAll(Arrays.asList(cc.getCropOrganismIds())); + } + } + + return retVal; + } + + public List<CropCategory> getCropCategories(Integer organizationId) + { + try + { + return em.createNamedQuery("CropCategory.findByOrganizationId") + .setParameter("organizationId", organizationId) + .getResultList(); + } + catch(NoResultException ex) + { + return new ArrayList<>(); + } + } } diff --git a/src/main/java/no/nibio/vips/logic/entity/CropCategory.java b/src/main/java/no/nibio/vips/logic/entity/CropCategory.java new file mode 100644 index 0000000000000000000000000000000000000000..29300e7815df9b50279aec95b33a50150c9668ba --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/entity/CropCategory.java @@ -0,0 +1,177 @@ +/* + * 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 + * 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; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.io.Serializable; +import java.util.Set; +import javax.persistence.Basic; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; +import no.nibio.vips.logic.util.IntegerArrayUserType; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; + +/** + * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +@Entity +@Table(name = "crop_category") +@XmlRootElement +@TypeDefs( {@TypeDef( name= "IntegerArray", typeClass = IntegerArrayUserType.class)}) +@NamedQueries({ + @NamedQuery(name = "CropCategory.findAll", query = "SELECT c FROM CropCategory c"), + @NamedQuery(name = "CropCategory.findByCropCategoryId", query = "SELECT c FROM CropCategory c WHERE c.cropCategoryId = :cropCategoryId"), + @NamedQuery(name = "CropCategory.findByCropCategoryIds", query = "SELECT c FROM CropCategory c WHERE c.cropCategoryId IN :cropCategoryIds"), + @NamedQuery(name = "CropCategory.findByDefaultName", query = "SELECT c FROM CropCategory c WHERE c.defaultName = :defaultName"), + @NamedQuery(name = "CropCategory.findByCropOrganismIds", query = "SELECT c FROM CropCategory c WHERE c.cropOrganismIds = :cropOrganismIds"), + @NamedQuery(name = "CropCategory.findByOrganizationId", query = "SELECT c FROM CropCategory c WHERE c.organizationId = :organizationId") +}) +public class CropCategory implements Serializable { + + private static final long serialVersionUID = 1L; + @Id + @Basic(optional = false) + @NotNull + @Column(name = "crop_category_id") + private Integer cropCategoryId; + @Size(max = 255) + @Column(name = "default_name") + private String defaultName; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "cropCategoryId", fetch = FetchType.EAGER) + private Set<CropCategoryLocal> cropCategoryLocalSet; + @Type(type = "IntegerArray") + @Column(name = "crop_organism_ids") + private Integer[] cropOrganismIds; + @Column(name = "organization_id") + private Integer organizationId; + + public CropCategory() { + } + + public CropCategory(Integer cropCategoryId) { + this.cropCategoryId = cropCategoryId; + } + + public Integer getCropCategoryId() { + return cropCategoryId; + } + + public void setCropCategoryId(Integer cropCategoryId) { + this.cropCategoryId = cropCategoryId; + } + + public String getDefaultName() { + return defaultName; + } + + public void setDefaultName(String defaultName) { + this.defaultName = defaultName; + } + + public Integer[] getCropOrganismIds() { + return cropOrganismIds; + } + + public void setCropOrganismIds(Integer[] cropOrganismIds) { + this.cropOrganismIds = cropOrganismIds; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (cropCategoryId != null ? cropCategoryId.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof CropCategory)) { + return false; + } + CropCategory other = (CropCategory) object; + if ((this.cropCategoryId == null && other.cropCategoryId != null) || (this.cropCategoryId != null && !this.cropCategoryId.equals(other.cropCategoryId))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "no.nibio.vips.logic.entity.CropCategory[ cropCategoryId=" + cropCategoryId + " ]"; + } + + /** + * @return the organizationId + */ + public Integer getOrganizationId() { + return organizationId; + } + + /** + * @param organizationId the organizationId to set + */ + public void setOrganizationId(Integer organizationId) { + this.organizationId = organizationId; + } + + /** + * @return the cropCategoryLocalSet + */ + public Set<CropCategoryLocal> getCropCategoryLocalSet() { + return cropCategoryLocalSet; + } + + /** + * @param cropCategoryLocalSet the cropCategoryLocalSet to set + */ + public void setCropCategoryLocalSet(Set<CropCategoryLocal> cropCategoryLocalSet) { + this.cropCategoryLocalSet = cropCategoryLocalSet; + } + + @JsonIgnore + public String getLocalName(String language) + { + if(this.cropCategoryLocalSet != null && ! this.getCropCategoryLocalSet().isEmpty()) + { + for(CropCategoryLocal ccl:this.getCropCategoryLocalSet()) + { + if(ccl.getCropCategoryLocalPK().getLocale().equals(language)) + { + return ccl.getLocalName(); + } + } + } + return null; + } +} diff --git a/src/main/java/no/nibio/vips/logic/entity/CropCategoryLocal.java b/src/main/java/no/nibio/vips/logic/entity/CropCategoryLocal.java new file mode 100644 index 0000000000000000000000000000000000000000..32fe771bfdd21aaae601684f14820e219585cb66 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/entity/CropCategoryLocal.java @@ -0,0 +1,123 @@ +/* + * 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 + * 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; + +import java.io.Serializable; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +@Entity +@Table(name = "crop_category_local") +@XmlRootElement +@NamedQueries({ + @NamedQuery(name = "CropCategoryLocal.findAll", query = "SELECT c FROM CropCategoryLocal c"), + @NamedQuery(name = "CropCategoryLocal.findByCropCategoryId", query = "SELECT c FROM CropCategoryLocal c WHERE c.cropCategoryLocalPK.cropCategoryId = :cropCategoryId"), + @NamedQuery(name = "CropCategoryLocal.findByLocale", query = "SELECT c FROM CropCategoryLocal c WHERE c.cropCategoryLocalPK.locale = :locale"), + @NamedQuery(name = "CropCategoryLocal.findByLocalName", query = "SELECT c FROM CropCategoryLocal c WHERE c.localName = :localName")}) +public class CropCategoryLocal implements Serializable { + + private static final long serialVersionUID = 1L; + @EmbeddedId + protected CropCategoryLocalPK cropCategoryLocalPK; + @Size(max = 255) + @Column(name = "local_name") + private String localName; + + // Easy fix for mapping from CropCategory + @Column(name="crop_category_id", insertable = false, updatable = false) + private Integer cropCategoryId; + + public CropCategoryLocal() { + } + + public CropCategoryLocal(CropCategoryLocalPK cropCategoryLocalPK) { + this.cropCategoryLocalPK = cropCategoryLocalPK; + } + + public CropCategoryLocal(int cropCategoryId, String locale) { + this.cropCategoryLocalPK = new CropCategoryLocalPK(cropCategoryId, locale); + } + + public CropCategoryLocalPK getCropCategoryLocalPK() { + return cropCategoryLocalPK; + } + + public void setCropCategoryLocalPK(CropCategoryLocalPK cropCategoryLocalPK) { + this.cropCategoryLocalPK = cropCategoryLocalPK; + } + + public String getLocalName() { + return localName; + } + + public void setLocalName(String localName) { + this.localName = localName; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (cropCategoryLocalPK != null ? cropCategoryLocalPK.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof CropCategoryLocal)) { + return false; + } + CropCategoryLocal other = (CropCategoryLocal) object; + if ((this.cropCategoryLocalPK == null && other.cropCategoryLocalPK != null) || (this.cropCategoryLocalPK != null && !this.cropCategoryLocalPK.equals(other.cropCategoryLocalPK))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "no.nibio.vips.logic.entity.CropCategoryLocal[ cropCategoryLocalPK=" + cropCategoryLocalPK + " ]"; + } + + /** + * @return the cropCategoryId + */ + public Integer getCropCategoryId() { + return cropCategoryId; + } + + /** + * @param cropCategoryId the cropCategoryId to set + */ + public void setCropCategoryId(Integer cropCategoryId) { + this.cropCategoryId = cropCategoryId; + } + +} diff --git a/src/main/java/no/nibio/vips/logic/entity/CropCategoryLocalPK.java b/src/main/java/no/nibio/vips/logic/entity/CropCategoryLocalPK.java new file mode 100644 index 0000000000000000000000000000000000000000..e4c8aa4fb0fdd7d6937f711ea09684b2f03fbbf0 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/entity/CropCategoryLocalPK.java @@ -0,0 +1,99 @@ +/* + * 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 + * 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; + +import java.io.Serializable; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +/** + * @copyright 2016 <a href="http://www.nibio.no/">NIBIO</a> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +@Embeddable +public class CropCategoryLocalPK implements Serializable { + + @Basic(optional = false) + @NotNull + @Column(name = "crop_category_id") + private int cropCategoryId; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 10) + @Column(name = "locale") + private String locale; + + public CropCategoryLocalPK() { + } + + public CropCategoryLocalPK(int cropCategoryId, String locale) { + this.cropCategoryId = cropCategoryId; + this.locale = locale; + } + + public int getCropCategoryId() { + return cropCategoryId; + } + + public void setCropCategoryId(int cropCategoryId) { + this.cropCategoryId = cropCategoryId; + } + + public String getLocale() { + return locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (int) cropCategoryId; + hash += (locale != null ? locale.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof CropCategoryLocalPK)) { + return false; + } + CropCategoryLocalPK other = (CropCategoryLocalPK) object; + if (this.cropCategoryId != other.cropCategoryId) { + return false; + } + if ((this.locale == null && other.locale != null) || (this.locale != null && !this.locale.equals(other.locale))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "no.nibio.vips.logic.entity.CropCategoryLocalPK[ cropCategoryId=" + cropCategoryId + ", locale=" + locale + " ]"; + } + +} 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 6fa0860969cfa571174869654cc4121f393dcd5e..99c8aae8748be308378afa746eac8b7bf2e1998f 100644 --- a/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java +++ b/src/main/java/no/nibio/vips/logic/entity/ForecastConfiguration.java @@ -62,6 +62,7 @@ import no.nibio.vips.util.WeatherUtil; @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.findAllActiveAtDate", 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 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"), diff --git a/src/main/java/no/nibio/vips/logic/entity/Message.java b/src/main/java/no/nibio/vips/logic/entity/Message.java index 1e2a36f0387a26a451cfa82013d206b4344e57c0..4003789ab76c60fb7a18fd50ee0cc91cf5409147 100644 --- a/src/main/java/no/nibio/vips/logic/entity/Message.java +++ b/src/main/java/no/nibio/vips/logic/entity/Message.java @@ -44,6 +44,10 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; import javax.xml.bind.annotation.XmlRootElement; +import no.nibio.vips.logic.util.IntegerArrayUserType; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; /** * @copyright 2014 <a href="http://www.nibio.no/">NIBIO</a> @@ -52,6 +56,7 @@ import javax.xml.bind.annotation.XmlRootElement; @Entity @Table(name = "message") @XmlRootElement +@TypeDefs( {@TypeDef( name= "IntegerArray", typeClass = IntegerArrayUserType.class)}) @NamedQueries({ @NamedQuery(name = "Message.findAll", query = "SELECT m FROM Message m"), @NamedQuery(name = "Message.findByMessageId", query = "SELECT m FROM Message m WHERE m.messageId = :messageId"), @@ -71,7 +76,7 @@ public class Message implements Serializable { private Set<MessageIllustration> messageIllustrationSet; private Set<MessageLocale> messageLocaleSet; private Integer organizationId; - private List<Integer> messageCropOrganismIds; + private Integer[] cropCategoryIds; public Message() { } @@ -270,18 +275,20 @@ public class Message implements Serializable { } /** - * @return the messageCropOrganismIds + * @return the cropCategoryIds */ - @Transient - public List<Integer> getMessageCropOrganismIds() { - return this.messageCropOrganismIds != null ? this.messageCropOrganismIds : new ArrayList<Integer>(); + @Type(type = "IntegerArray") + @Column(name="crop_category_ids") + public Integer[] getCropCategoryIds() { + return cropCategoryIds; } /** - * @param messageCropOrganismIds the messageCropOrganismIds to set + * @param cropCategoryIds the cropCategoryIds to set */ - public void setMessageCropOrganismIds(List<Integer> messageCropOrganismIds) { - this.messageCropOrganismIds = messageCropOrganismIds; + public void setCropCategoryIds(Integer[] cropCategoryIds) { + this.cropCategoryIds = cropCategoryIds; } + } diff --git a/src/main/java/no/nibio/vips/logic/messaging/ForecastEventNotificationSubscription.java b/src/main/java/no/nibio/vips/logic/messaging/ForecastEventNotificationSubscription.java index 0a128b6351f357c796df57b129ac41fc89db8ded..f8291514c654520f9d46663de3245836b2fe58a2 100644 --- a/src/main/java/no/nibio/vips/logic/messaging/ForecastEventNotificationSubscription.java +++ b/src/main/java/no/nibio/vips/logic/messaging/ForecastEventNotificationSubscription.java @@ -54,8 +54,8 @@ public class ForecastEventNotificationSubscription { private Integer[] weatherStationIds; @Type(type = "IntegerArray") - @Column(name = "crop_ids") - private Integer[] cropIds; + @Column(name = "crop_category_ids") + private Integer[] cropCategoryIds; /** * @return the userId @@ -109,21 +109,21 @@ public class ForecastEventNotificationSubscription { } /** - * @return the cropIds + * @return the cropCategoryIds */ - public Integer[] getCropIds() { - return cropIds; + public Integer[] getCropCategoryIds() { + return cropCategoryIds; } /** - * @param cropIds the cropIds to set + * @param cropCategoryIds the cropCategoryIds to set */ - public void setCropIds(Integer[] cropIds) { - this.cropIds = cropIds; + public void setCropCategoryIds(Integer[] cropCategoryIds) { + this.cropCategoryIds = cropCategoryIds; } public void setCropIds(List<Integer> cropIds) { - this.cropIds = cropIds.toArray(new Integer[cropIds.size()]); + this.cropCategoryIds = cropIds.toArray(new Integer[cropIds.size()]); } } diff --git a/src/main/java/no/nibio/vips/logic/messaging/MessageNotificationSubscription.java b/src/main/java/no/nibio/vips/logic/messaging/MessageNotificationSubscription.java index 2e70064f2e4ead1c3bf2ca58e45d20db5ce15cfc..8ee570be8121f53187b4f8bb489f986b5b3f28c4 100644 --- a/src/main/java/no/nibio/vips/logic/messaging/MessageNotificationSubscription.java +++ b/src/main/java/no/nibio/vips/logic/messaging/MessageNotificationSubscription.java @@ -53,8 +53,8 @@ public class MessageNotificationSubscription implements Serializable { private Integer[] messageTagIds; @Type(type = "IntegerArray") - @Column(name = "crop_ids") - private Integer[] cropIds; + @Column(name = "crop_category_ids") + private Integer[] cropCategoryIds; public Integer getUserId() { return this.userId; @@ -127,22 +127,22 @@ public class MessageNotificationSubscription implements Serializable { } /** - * @return the cropIds + * @return the cropCategoryIds */ - public Integer[] getCropIds() { - return cropIds; + public Integer[] getCropCategoryIds() { + return cropCategoryIds; } /** - * @param cropIds the cropIds to set + * @param cropCategoryIds the cropCategoryIds to set */ - public void setCropIds(Integer[] cropIds) { - this.cropIds = cropIds; + public void setCropCategoryIds(Integer[] cropCategoryIds) { + this.cropCategoryIds = cropCategoryIds; } public void setCropIds(List<Integer> cropIds) { - this.cropIds = cropIds.toArray(new Integer[cropIds.size()]); + this.cropCategoryIds = cropIds.toArray(new Integer[cropIds.size()]); } } diff --git a/src/main/java/no/nibio/vips/logic/messaging/MessagingBean.java b/src/main/java/no/nibio/vips/logic/messaging/MessagingBean.java index 5ad2cfdeab402c0a9498d149f3dc34f390ab1def..fb3197edb144b1d4191a7e7d8ace11d8a64b9cca 100644 --- a/src/main/java/no/nibio/vips/logic/messaging/MessagingBean.java +++ b/src/main/java/no/nibio/vips/logic/messaging/MessagingBean.java @@ -321,8 +321,7 @@ public class MessagingBean { public List<MessageRecipient> getForecastEventNotificationSubscribers(ForecastConfiguration config) { - Query q = em.createNativeQuery( - "SELECT \n" + + String sql = "SELECT \n" + " u.preferred_locale,\n" + " umf.format_name AS type,\n" + " CASE fns.universal_message_format_id " + @@ -336,13 +335,13 @@ public class MessagingBean { "WHERE fns.user_id=u.user_id\n" + "AND fns.universal_message_format_id = umf.universal_message_format_id\n" + "AND u.user_id IN (\n" + - " SELECT user_id FROM messaging.forecast_event_notification_subscription fens, public.vips_logic_user u \n" + + " SELECT u.user_id FROM messaging.forecast_event_notification_subscription fens, public.vips_logic_user u \n" + " WHERE :weatherStationId = ANY(fens.weather_station_ids) \n" + - " AND :cropOrganismId = ANY(fens.crop_ids)" + + " AND fens.crop_category_ids && ARRAY(SELECT crop_category_id FROM public.crop_category WHERE :cropOrganismId = ANY(crop_organism_ids))" + " AND fens.user_id = u.user_id \n" + " AND (fens.universal_message_format_id <> " + UniversalMessageFormat.FORMAT_SMS + " OR (fens.universal_message_format_id = " + UniversalMessageFormat.FORMAT_SMS + " AND u.approves_sms_billing IS TRUE))" + - ");\n", - MessageRecipient.class); + ");\n"; + Query q = em.createNativeQuery(sql, MessageRecipient.class); q.setParameter("weatherStationId", config.getWeatherStationPointOfInterestId().getPointOfInterestId()); q.setParameter("cropOrganismId", config.getCropOrganismId().getOrganismId()); @@ -420,7 +419,7 @@ public class MessagingBean { "AND ons.universal_message_format_id = umf.universal_message_format_id\n" + "AND u.user_id IN (\n" + " SELECT ons.user_id FROM messaging.observation_notification_subscription ons, public.vips_logic_user u \n" + - " WHERE :cropOrganismId = ANY(ons.crop_ids) \n" + + " WHERE ons.crop_category_ids && ARRAY(SELECT crop_category_id FROM public.crop_category WHERE :cropOrganismId = ANY(crop_organism_ids)) \n" + " AND ons.user_id = u.user_id \n" + " AND (ons.universal_message_format_id <> " + UniversalMessageFormat.FORMAT_SMS + " OR (ons.universal_message_format_id = " + UniversalMessageFormat.FORMAT_SMS + " AND u.approves_sms_billing IS TRUE))" + ");\n", diff --git a/src/main/java/no/nibio/vips/logic/messaging/ObservationNotificationSubscription.java b/src/main/java/no/nibio/vips/logic/messaging/ObservationNotificationSubscription.java index a477030cfde46bfc053f9064f5e21aab5a6dfdcd..b178320b22e4f3c400205c1f96aefe32d53530ee 100644 --- a/src/main/java/no/nibio/vips/logic/messaging/ObservationNotificationSubscription.java +++ b/src/main/java/no/nibio/vips/logic/messaging/ObservationNotificationSubscription.java @@ -49,8 +49,8 @@ public class ObservationNotificationSubscription implements Serializable { private Integer universalMessageFormatId; @Type(type = "IntegerArray") - @Column(name = "crop_ids") - private Integer[] cropIds; + @Column(name = "crop_category_ids") + private Integer[] cropCategoryIds; public Integer getUserId() { return this.userId; @@ -100,22 +100,22 @@ public class ObservationNotificationSubscription implements Serializable { } /** - * @return the cropIds + * @return the cropCategoryIds */ - public Integer[] getCropIds() { - return cropIds; + public Integer[] getCropCategoryIds() { + return cropCategoryIds; } /** - * @param cropIds the cropIds to set + * @param cropCategoryIds the cropCategoryIds to set */ - public void setCropIds(Integer[] cropIds) { - this.cropIds = cropIds; + public void setCropCategoryIds(Integer[] cropCategoryIds) { + this.cropCategoryIds = cropCategoryIds; } public void setCropIds(List<Integer> cropIds) { - this.cropIds = cropIds.toArray(new Integer[cropIds.size()]); + this.cropCategoryIds = cropIds.toArray(new Integer[cropIds.size()]); } } 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 53a70b1a48adad398bbab9e92b78709f5fba877c..2bf2f79d53e29d7d3d1660ac4d2dc2f89a61b856 100644 --- a/src/main/java/no/nibio/vips/logic/service/LogicService.java +++ b/src/main/java/no/nibio/vips/logic/service/LogicService.java @@ -293,10 +293,18 @@ public class LogicService { @Produces("application/vnd.google-earth.kml+xml;charset=utf-8") public Response getForecastResultsAggregate( @PathParam("organizationId") Integer organizationId, - @QueryParam("cropOrganismId") List<Integer> cropOrganismIds) + @QueryParam("cropCategoryId") List<Integer> cropCategoryIds) { + if(cropCategoryIds == null || cropCategoryIds.isEmpty()) + { + return Response.noContent().build(); + } + else + { + List<Integer> cropOrganismIds = SessionControllerGetter.getOrganismBean().getCropCategoryOrganismIds(cropCategoryIds); Kml retVal = SessionControllerGetter.getForecastBean().getForecastsAggregateKml(organizationId, cropOrganismIds, SystemTime.getSystemTime(), ServletUtil.getServerName(httpServletRequest)); return Response.ok().entity(retVal).build(); + } } @GET @@ -352,7 +360,7 @@ public class LogicService { public Response getMessage(@PathParam("messageId") Integer messageId) { Message message = SessionControllerGetter.getMessageBean().getMessage(messageId); - message.setMessageCropOrganismIds(SessionControllerGetter.getMessageBean().getMessageCropOrganismIds(message)); + return Response.ok().entity(message).build(); } @@ -382,9 +390,6 @@ public class LogicService { } List<Message> messageList = SessionControllerGetter.getMessageBean().getMessageList(organizationId, datePublishedFrom, datePublishedTo); - // Adding the crop connections manually - messageList = SessionControllerGetter.getMessageBean().addMessageOrganismIds(messageList); - return Response.ok().entity(messageList).build(); } catch(ParseException ex){ @@ -398,7 +403,6 @@ public class LogicService { public Response getMessageListWithTags(@QueryParam("tagId") List<Integer> tagIds, @PathParam("organizationId") Integer organizationId) { List<Message> messageListWithTags = SessionControllerGetter.getMessageBean().getCurrentFilteredMessagesForOrganization(tagIds, organizationId); - messageListWithTags = SessionControllerGetter.getMessageBean().addMessageOrganismIds(messageListWithTags); return Response.ok().entity(messageListWithTags).build(); } @@ -684,6 +688,21 @@ public class LogicService { } } + @GET + @Path("organism/cropcategory/{organizationId}") + @Produces("application/json;charset=UTF-8") + public Response getCropCategories(@PathParam("organizationId") Integer organizationId) + { + if(organizationId != null) + { + return Response.ok().entity(SessionControllerGetter.getOrganismBean().getCropCategories(organizationId)).build(); + } + else + { + return Response.noContent().build(); + } + } + private ManagerResource getManagerResource() { Client client = ClientBuilder.newClient(); diff --git a/src/main/java/no/nibio/vips/logic/util/IntegerArrayUserType.java b/src/main/java/no/nibio/vips/logic/util/IntegerArrayUserType.java index 1a765f7047c1592eb7f4507533d8ea223db1c03f..7bdb5d98873374201825f3519277de07972efd8e 100644 --- a/src/main/java/no/nibio/vips/logic/util/IntegerArrayUserType.java +++ b/src/main/java/no/nibio/vips/logic/util/IntegerArrayUserType.java @@ -109,8 +109,15 @@ public class IntegerArrayUserType implements UserType { return null; } - Integer[] array = (Integer[]) rs.getArray(names[0]).getArray(); - return array; + try + { + Integer[] array = (Integer[]) rs.getArray(names[0]).getArray(); + return array; + } + catch(NullPointerException ex) + { + return new Integer[0]; + } } /** 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 d7a88344f520e7fa966b6eca75ddbf8d1f2b7237..3c50ddd93acf527793814beb939ab75b5347029b 100644 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties @@ -345,3 +345,4 @@ noPrivateForecastsFoundForUser=No private forecasts found for user listCrops=List all crops listPests=List all pests allPests=All pests +cropCategoryIds=Crop categories 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 28f283f92ec8fe045d61ad1d297c3b4d83c0b60d..74f4537fe0791a2d3d17f5197ba5b0a0fc70d633 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 @@ -345,3 +345,4 @@ noPrivateForecastsFoundForUser=No private forecasts found for user listCrops=List all crops listPests=List all pests allPests=All pests +cropCategoryIds=Crop categories 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 3c24137038ad283cddfff91a96f6b3a16a77acc3..185b130d5491418bba9f97a3ba7b056f87526435 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 @@ -344,3 +344,4 @@ noPrivateForecastsFoundForUser=No private forecasts found for user listCrops=List all crops listPests=List all pests allPests=All pests +cropCategoryIds=Crop categories 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 a17b91864b96e5e27a88d76e901cdf188d7d6042..0a9e2fd4b5e43723a4791eb02c476a49be1fcdc8 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 @@ -345,3 +345,4 @@ noPrivateForecastsFoundForUser=Fant ingen private varsler for brukeren listCrops=Kulturliste listPests=Skadegj\u00f8rerliste allPests=Alle skadegj\u00f8rere +cropCategoryIds=Kulturgrupper 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 dd6e64359cd5603aaae188a2d31e9e070fbe7e72..8fb755a2e8b923be9426edea8cd9e04672ba639c 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 @@ -345,3 +345,4 @@ noPrivateForecastsFoundForUser=No private forecasts found for user listCrops=List all crops listPests=List all pests allPests=All pests +cropCategoryIds=Crop categories diff --git a/src/main/webapp/formdefinitions/messageForm.json b/src/main/webapp/formdefinitions/messageForm.json index 9e09b1d21326a55e688860ad3e2bce32c2916367..5e7b86b9c16319c421fc6c160cfe44f5a391e133 100644 --- a/src/main/webapp/formdefinitions/messageForm.json +++ b/src/main/webapp/formdefinitions/messageForm.json @@ -37,7 +37,7 @@ "required" : false }, { - "name" : "cropOrganismIds", + "name" : "cropCategoryIds", "dataType" : "INTEGER", "fieldType" : "SELECT_MULTIPLE", "required" : false diff --git a/src/main/webapp/templates/messageForm.ftl b/src/main/webapp/templates/messageForm.ftl index 8b15cd257812fb8356fe0a1cfa9c516b996d5be8..04a08a9fc20f410871244502f1091007270976ca 100644 --- a/src/main/webapp/templates/messageForm.ftl +++ b/src/main/webapp/templates/messageForm.ftl @@ -140,17 +140,15 @@ </select> </div> <div class="form-group"> - <label for="cropOrganismIds">${i18nBundle.cropOrganismIds}</label> - <select class="form-control chosen-select" name="cropOrganismIds" onblur="validateField(this);" multiple="multiple"> - <#list allCrops?sort_by("latinName") as organism> - <option value="${organism.organismId}" - <#list message.messageCropOrganismIds as organismId> - <#if organismId == organism.organismId> - selected="selected" + <label for="cropCategoryIds">${i18nBundle.cropCategoryIds}</label> + <select class="form-control chosen-select" name="cropCategoryIds" onblur="validateField(this);" multiple="multiple"> + <#list allCropCategoryIds as cropCategory> + <option value="${cropCategory.cropCategoryId}" + <#if message.cropCategoryIds?has_content && message.cropCategoryIds?seq_index_of(cropCategory.cropCategoryId) gte 0> + selected="selected" </#if> + >${cropCategory.getLocalName(currentLocale.language)!cropCategory.defaultName}</option> </#list> - >${organism.latinName!""} / ${organism.tradeName!""} / ${organism.getLocalName(currentLocale.language)!""}</option> - </#list> </select> </div>