diff --git a/src/main/java/no/bioforsk/vips/logic/controller/servlet/ForecastConfigurationController.java b/src/main/java/no/bioforsk/vips/logic/controller/servlet/ForecastConfigurationController.java index e1139b0a3a55ce7bd66ff4896969cff828f4f09b..8f287be2f1bd618599a874d1866dbd3cc6403c1b 100644 --- a/src/main/java/no/bioforsk/vips/logic/controller/servlet/ForecastConfigurationController.java +++ b/src/main/java/no/bioforsk/vips/logic/controller/servlet/ForecastConfigurationController.java @@ -18,6 +18,7 @@ import no.bioforsk.vips.logic.util.SessionControllerGetter; import no.bioforsk.vips.util.ServletUtil; import no.bioforsk.web.forms.FormField; import no.bioforsk.web.forms.FormValidation; +import no.bioforsk.web.forms.FormValidationException; import no.bioforsk.web.forms.FormValidator; /** @@ -182,9 +183,16 @@ public class ForecastConfigurationController extends HttpServlet { } } } - catch(NullPointerException | NumberFormatException ex) + catch(NullPointerException | NumberFormatException | FormValidationException ex) { - response.sendError(500, "Invalid forecast configurationId " + request.getParameter("forecastConfigurationId")); + if(ex instanceof NumberFormatException) + { + response.sendError(500, "Invalid forecast configurationId " + request.getParameter("forecastConfigurationId")); + } + else + { + response.sendError(500, ex.getMessage()); + } } } else diff --git a/src/main/java/no/bioforsk/vips/logic/controller/servlet/OrganismController.java b/src/main/java/no/bioforsk/vips/logic/controller/servlet/OrganismController.java new file mode 100644 index 0000000000000000000000000000000000000000..9c2a1b1bb1665a67f7b1ddb403fa5007803d604b --- /dev/null +++ b/src/main/java/no/bioforsk/vips/logic/controller/servlet/OrganismController.java @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package no.bioforsk.vips.logic.controller.servlet; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import no.bioforsk.vips.logic.controller.session.UserBean; +import no.bioforsk.vips.logic.entity.Organism; +import no.bioforsk.vips.logic.entity.OrganismExternalResource; +import no.bioforsk.vips.logic.entity.OrganismExternalResourcePK; +import no.bioforsk.vips.logic.entity.VipsLogicUser; +import no.bioforsk.vips.logic.i18n.SessionLocaleUtil; +import no.bioforsk.vips.logic.util.SessionControllerGetter; +import no.bioforsk.vips.util.ServletUtil; +import no.bioforsk.web.forms.FormField; +import no.bioforsk.web.forms.FormValidation; +import no.bioforsk.web.forms.FormValidationException; +import no.bioforsk.web.forms.FormValidator; + +/** + * @copyright 2014 <a href="http://www.bioforsk.no/">Bioforsk</a> + * @author Tor-Einar Skog <tor-einar.skog@bioforsk.no> + */ +public class OrganismController extends HttpServlet { + + @PersistenceContext(unitName="VIPSLogic-PU") + EntityManager em; + + /** + * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. + * @param request servlet request + * @param response servlet response + * @throws ServletException if a servlet-specific error occurs + * @throws IOException if an I/O error occurs + */ + 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"); + UserBean userBean = SessionControllerGetter.getUserBean(); + + // Default: View top organisms + // for everyone + if(action == null || action.equals("listChildOrganisms")) + { + try + { + Organism organism; + if( action == null + || (request.getParameter("organismId") != null && (request.getParameter("organismId").isEmpty() || request.getParameter("organismId").equals("null"))) + ) + { + organism = new Organism(); + organism.setChildOrganisms(SessionControllerGetter.getOrganismBean().getTopLevelOrganisms()); + } + else + { + Integer organismId = Integer.valueOf(request.getParameter("organismId")); + organism = SessionControllerGetter.getOrganismBean().getOrganismAndChildrenTwoLevels(organismId); + } + request.setAttribute("organism", organism); + // Check if any of the child organisms has trade name + Boolean tradeNamePresent = Boolean.FALSE; + for(Organism child:organism.getChildOrganisms()) + { + if(child.getTradeName() != null && !child.getTradeName().isEmpty()) + { + tradeNamePresent = Boolean.TRUE; + } + } + request.setAttribute("tradeNamePresent", tradeNamePresent); + // Check if message has been passed on + request.setAttribute("messageKey", request.getParameter("messageKey")); + // Delegate to template + request.getRequestDispatcher("/organismList.ftl").forward(request, response); + } + catch(NullPointerException | NumberFormatException ex) + { + if(ex instanceof NumberFormatException) + { + response.sendError(500, "Invalid organism id " + request.getParameter("organismId")); + } + else + { + response.sendError(500, ex.getMessage()); + } + } + } + else if(action.equals("viewOrganism")) + { + try + { + + Integer organismId = Integer.valueOf(request.getParameter("organismId")); + Organism organism = em.find(Organism.class, organismId); + request.setAttribute("organism", organism); + // Hierarchy categories + request.setAttribute("hierarchyCategories", SessionControllerGetter.getOrganismBean().getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request))); + request.setAttribute("parentOrganism", organism.getParentOrganismId() != null ? em.find(Organism.class, organism.getParentOrganismId()) : null); + request.getRequestDispatcher("/organismDetails.ftl").forward(request, response); + } + catch(NullPointerException | NumberFormatException ex) + { + response.sendError(500, "Invalid organism id " + request.getParameter("organismId")); + } + } + else if(action.equals("editOrganismForm")) + { + try + { + + Integer organismId = Integer.valueOf(request.getParameter("organismId")); + Organism organism = em.find(Organism.class, organismId); + request.setAttribute("organism", organism); + // All organisms used for parent organism list + List<Organism> allOrganisms = em.createNamedQuery("Organism.findAll").getResultList(); + request.setAttribute("allOrganisms", allOrganisms); + // Hierarchy categories + request.setAttribute("hierarchyCategories", SessionControllerGetter.getOrganismBean().getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request))); + // Finding all external resources where entry is missing + request.setAttribute("unreferencedExternalResources", SessionControllerGetter.getOrganismBean().getUnusedExternalResourcesForOrganism(organism)); + request.getRequestDispatcher("/organismForm.ftl").forward(request, response); + } + catch(NullPointerException | NumberFormatException ex) + { + response.sendError(500, "Invalid organism id " + request.getParameter("organismId")); + } + } + else if(action.equals("newOrganismForm")) + { + try + { + Integer parentOrganismId = null; + if(request.getParameter("parentOrganismId") != null && !request.getParameter("parentOrganismId").equals("null") && ! request.getParameter("parentOrganismId").isEmpty()) + { + parentOrganismId = Integer.valueOf(request.getParameter("parentOrganismId")); + } + request.setAttribute("parentOrganismId", parentOrganismId); + Organism organism = new Organism(); + request.setAttribute("organism", organism); + request.setAttribute("allOrganisms", em.createNamedQuery("Organism.findAll").getResultList()); + // Hierarchy categories + request.setAttribute("hierarchyCategories", SessionControllerGetter.getOrganismBean().getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request))); + + // Finding all external resources where entry is missing + request.setAttribute("unreferencedExternalResources", SessionControllerGetter.getOrganismBean().getUnusedExternalResourcesForOrganism(organism)); + + request.getRequestDispatcher("/organismForm.ftl").forward(request, response); + } + catch(NullPointerException | NumberFormatException ex) + { + response.sendError(500, "Invalid organism id " + request.getParameter("organismId")); + } + } + else if(action.equals("organismFormSubmit")) + { + try + { + Integer organismId = Integer.valueOf(request.getParameter("organismId")); + Organism organism = organismId > 0 ? em.find(Organism.class, organismId) : new Organism(); + FormValidation formValidation = FormValidator.validateForm("organismForm",request,getServletContext()); + if(formValidation.isValid()) + { + organism.setLatinName(formValidation.getFormField("latinName").getWebValue()); + organism.setTradeName(formValidation.getFormField("tradeName").getWebValue()); + organism.setHierarchyCategoryId(formValidation.getFormField("hierarchyCategoryId").getValueAsInteger()); + organism.setParentOrganismId(formValidation.getFormField("parentOrganismId").getValueAsInteger()); + organism = SessionControllerGetter.getOrganismBean().storeOrganism(organism); + + // Adding local name + if(!formValidation.getFormField("localName").getWebValue().isEmpty()) + { + SessionControllerGetter.getOrganismBean().storeOrganismLocalName(organism, formValidation.getFormField("localName").getWebValue(), SessionLocaleUtil.getCurrentLocale(request)); + } + //System.out.println(formValidation.getFormFields().toString()); + Map<String, FormField> externalResourceIdentifiers = formValidation.getMultipleMapFormFields().get("externalResourceIdentifier"); + for(String key:externalResourceIdentifiers.keySet()) + { + FormField identifierField = externalResourceIdentifiers.get(key); + if(identifierField.getWebValue() == null || identifierField.getWebValue().isEmpty()) + { + continue; + } + Integer externalResourceId = Integer.valueOf(key); + OrganismExternalResource organismExternalResource = new OrganismExternalResource(); + OrganismExternalResourcePK pk = new OrganismExternalResourcePK(organism.getOrganismId(), externalResourceId); + organismExternalResource.setOrganismExternalResourcePK(pk); + organismExternalResource.setResourceIdentifier(identifierField.getWebValue()); + SessionControllerGetter.getOrganismBean().storeOrganismExternalResource(organismExternalResource); + } + // Need to refresh organism after storing the external resources + Organism refreshedOrganism = em.find(Organism.class, organism.getOrganismId()); + request.setAttribute("organism", refreshedOrganism); + request.setAttribute("allOrganisms", em.createNamedQuery("Organism.findAll").getResultList()); + // Hierarchy categories + request.setAttribute("hierarchyCategories", SessionControllerGetter.getOrganismBean().getHierarchyCategoryNames(SessionLocaleUtil.getCurrentLocale(request))); + // Finding all external resources where entry is missing + request.setAttribute("unreferencedExternalResources", SessionControllerGetter.getOrganismBean().getUnusedExternalResourcesForOrganism(refreshedOrganism)); + request.setAttribute("messageKey", organismId > 0 ? "organismUpdated" : "organismRegistered"); + request.getRequestDispatcher("/organismForm.ftl").forward(request, response); + } + else + { + request.setAttribute("formValidation", formValidation); + request.setAttribute("organism", organism); + // Finding all external resources where entry is missing + request.setAttribute("unreferencedExternalResources", SessionControllerGetter.getOrganismBean().getUnusedExternalResourcesForOrganism(organism)); + request.getRequestDispatcher("/organismForm.ftl").forward(request, response); + } + } + catch(NullPointerException | NumberFormatException | FormValidationException ex) + { + if(ex instanceof NumberFormatException) + { + response.sendError(500, "Invalid organism id " + request.getParameter("organismId")); + } + else if(ex instanceof FormValidationException) + { + response.sendError(500, "Form validation exception: " + ex.getMessage()); + } + else + { + ex.printStackTrace(); + response.sendError(500, ex.getMessage()); + } + } + } + else if(action.equals("deleteOrganism")) + { + try + { + Integer organismId = Integer.valueOf(request.getParameter("organismId")); + Organism organism = em.find(Organism.class, organismId); + String parentOrganismId = organism.getParentOrganismId() != null ? String.valueOf(organism.getParentOrganismId()) : "null"; + if(SessionControllerGetter.getOrganismBean().deleteOrganism(organismId)) + { + // Route back to where we were with confirmation message + response.sendRedirect(new StringBuilder("http://").append(ServletUtil.getServerName(request)).append("/organism?action=listChildOrganisms&organismId=").append(parentOrganismId).append("&messageKey=organismDeleted").toString()); + } + else + { + // Route back to where we were with error message + response.sendRedirect("/organism?action=listChildOrganisms&organismId=" + parentOrganismId + "&errorMessageKey=organismNotDeleted"); + } + } + catch(NullPointerException | NumberFormatException ex) + { + if(ex instanceof NumberFormatException) + { + response.sendError(500, "Invalid organism id " + request.getParameter("organismId")); + } + else + { + response.sendError(500, ex.getMessage()); + } + } + } + } + + // <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. + * @param request servlet request + * @param response servlet response + * @throws ServletException if a servlet-specific error occurs + * @throws IOException if an I/O error occurs + */ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + processRequest(request, response); + } + + /** + * Handles the HTTP <code>POST</code> method. + * @param request servlet request + * @param response servlet response + * @throws ServletException if a servlet-specific error occurs + * @throws IOException if an I/O error occurs + */ + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + processRequest(request, response); + } + + /** + * Returns a short description of the servlet. + * @return a String containing servlet description + */ + @Override + public String getServletInfo() { + return "Short description"; + }// </editor-fold> + +} diff --git a/src/main/java/no/bioforsk/vips/logic/controller/servlet/SchedulingController.java b/src/main/java/no/bioforsk/vips/logic/controller/servlet/SchedulingController.java index faa1b0fe0bc01d94782bd087635932a141a741b2..b26e8741bef98a72345b0cf9e785b00d7a36eb7a 100644 --- a/src/main/java/no/bioforsk/vips/logic/controller/servlet/SchedulingController.java +++ b/src/main/java/no/bioforsk/vips/logic/controller/servlet/SchedulingController.java @@ -26,6 +26,7 @@ import no.bioforsk.vips.logic.scheduling.VipsLogicTaskFactory; import no.bioforsk.vips.logic.util.SessionControllerGetter; import no.bioforsk.vips.util.ServletUtil; import no.bioforsk.web.forms.FormValidation; +import no.bioforsk.web.forms.FormValidationException; import no.bioforsk.web.forms.FormValidator; import no.bioforsk.web.forms.HTMLFormGenerator; @@ -63,32 +64,39 @@ public class SchedulingController extends HttpServlet { { if(userBean.authorizeUser(user, VipsLogicRole.ORGANIZATION_ADMINISTRATOR, VipsLogicRole.SUPERUSER)) { - FormValidation formValidation = FormValidator.validateForm("taskHistoryDateForm", request, getServletContext()); - Date taskHistoryDate = new Date(); - if(formValidation.isValid()) + try { - if(! formValidation.getFormField("taskHistoryDate").isEmpty()) + FormValidation formValidation = FormValidator.validateForm("taskHistoryDateForm", request, getServletContext()); + Date taskHistoryDate = new Date(); + if(formValidation.isValid()) + { + if(! formValidation.getFormField("taskHistoryDate").isEmpty()) + { + taskHistoryDate = formValidation.getFormField("taskHistoryDate").getValueAsDate(); + } + } + else { - taskHistoryDate = formValidation.getFormField("taskHistoryDate").getValueAsDate(); + request.setAttribute("formValidation", formValidation); } + + + TaskExecutor[] taskExecutors = schedulingBean.getRunningTasks(); + request.setAttribute("taskExecutors", taskExecutors); + request.setAttribute("schedulingStarted", Boolean.valueOf(schedulingBean.getSystemScheduler().isStarted())); + request.setAttribute("orderedScheduledTasks", schedulingBean.getOrderedScheduledTasks()); + request.setAttribute("taskHistoryDate",taskHistoryDate); + request.setAttribute("taskHistory",schedulingBean.getTaskHistory(taskHistoryDate)); + request.setAttribute("allTasksMap", VipsLogicTaskFactory.getAllVipsLogicTasksMap()); + // If this is a redirect from a controller, with a message to be passed on + request.setAttribute("messageKey", request.getParameter("messageKey")); + request.setAttribute("message", request.getParameter("message")); + request.getRequestDispatcher("/schedulingOverview.ftl").forward(request, response); } - else + catch(FormValidationException ex) { - request.setAttribute("formValidation", formValidation); + response.sendError(500, ex.getMessage()); } - - - TaskExecutor[] taskExecutors = schedulingBean.getRunningTasks(); - request.setAttribute("taskExecutors", taskExecutors); - request.setAttribute("schedulingStarted", Boolean.valueOf(schedulingBean.getSystemScheduler().isStarted())); - request.setAttribute("orderedScheduledTasks", schedulingBean.getOrderedScheduledTasks()); - request.setAttribute("taskHistoryDate",taskHistoryDate); - request.setAttribute("taskHistory",schedulingBean.getTaskHistory(taskHistoryDate)); - request.setAttribute("allTasksMap", VipsLogicTaskFactory.getAllVipsLogicTasksMap()); - // If this is a redirect from a controller, with a message to be passed on - request.setAttribute("messageKey", request.getParameter("messageKey")); - request.setAttribute("message", request.getParameter("message")); - request.getRequestDispatcher("/schedulingOverview.ftl").forward(request, response); } else { @@ -192,7 +200,7 @@ public class SchedulingController extends HttpServlet { request.getRequestDispatcher("/runTaskManuallyForm.ftl").forward(request, response); } } - catch(NullPointerException | NumberFormatException ex) + catch(NullPointerException | NumberFormatException | FormValidationException ex) { response.sendError(500, "ERROR: " + ex.getMessage()); } diff --git a/src/main/java/no/bioforsk/vips/logic/controller/servlet/UserController.java b/src/main/java/no/bioforsk/vips/logic/controller/servlet/UserController.java index 6910a8e0b02d633e307396daf6d24fdf57bc0d12..1837943f41a7edfa9b4e67d8f739256c1c64719b 100644 --- a/src/main/java/no/bioforsk/vips/logic/controller/servlet/UserController.java +++ b/src/main/java/no/bioforsk/vips/logic/controller/servlet/UserController.java @@ -44,6 +44,7 @@ import no.bioforsk.vips.logic.util.SessionControllerGetter; import no.bioforsk.vips.util.ServletUtil; import no.bioforsk.web.forms.FormField; import no.bioforsk.web.forms.FormValidation; +import no.bioforsk.web.forms.FormValidationException; import no.bioforsk.web.forms.FormValidator; /** @@ -195,9 +196,8 @@ public class UserController extends HttpServlet { } } - catch(NullPointerException | NumberFormatException ex) + catch(NullPointerException | NumberFormatException | FormValidationException ex) { - ex.printStackTrace(); response.sendError(500, ex.getMessage()); } } @@ -289,55 +289,62 @@ public class UserController extends HttpServlet { } // Standard form validation - FormValidation formValidation = FormValidator.validateForm( - "userRegistrationFormType" + userAuthenticationType.getUserAuthenticationTypeId(), - request,getServletContext() - ); - // Extra check: That user's email is not already in use - FormField emailField = formValidation.getFormField("email"); - if(userBean.getUserByEmail(emailField.getWebValue()) != null) + try { - emailField.setValid(false); - emailField.setValidationMessage(SessionLocaleUtil.getI18nText(request, "emailAddressIsAlreadyInUse")); - } - - if(formValidation.isValid()) - { - - // Setting authentication info first - auth.setUserAuthenticationType(userAuthenticationType); - if(userAuthenticationType.getUserAuthenticationTypeId().equals(UserAuthenticationType.TYPE_PASSWORD)) + FormValidation formValidation = FormValidator.validateForm( + "userRegistrationFormType" + userAuthenticationType.getUserAuthenticationTypeId(), + request,getServletContext() + ); + // Extra check: That user's email is not already in use + FormField emailField = formValidation.getFormField("email"); + if(userBean.getUserByEmail(emailField.getWebValue()) != null) { - auth.setUsername(formValidation.getFormField("username").getWebValue()); - auth.setPassword(userBean.getMD5EncryptedString(formValidation.getFormField("password").getWebValue())); + emailField.setValid(false); + emailField.setValidationMessage(SessionLocaleUtil.getI18nText(request, "emailAddressIsAlreadyInUse")); } - // For OpenId and GoogleId - else + + if(formValidation.isValid()) { - auth.setUsername((String)request.getSession().getAttribute("openId")); + + // Setting authentication info first + auth.setUserAuthenticationType(userAuthenticationType); + if(userAuthenticationType.getUserAuthenticationTypeId().equals(UserAuthenticationType.TYPE_PASSWORD)) + { + auth.setUsername(formValidation.getFormField("username").getWebValue()); + auth.setPassword(userBean.getMD5EncryptedString(formValidation.getFormField("password").getWebValue())); + } + // For OpenId and GoogleId + else + { + auth.setUsername((String)request.getSession().getAttribute("openId")); + } + // Adding user info + newUser.setEmail(formValidation.getFormField("email").getWebValue()); + newUser.setFirstName(formValidation.getFormField("firstName").getWebValue()); + newUser.setLastName(formValidation.getFormField("lastName").getWebValue()); + Organization organization = em.find(Organization.class, formValidation.getFormField("organizationId").getValueAsInteger()); + newUser.setOrganizationId(organization); + newUser.setApprovalApplication(formValidation.getFormField("approvalApplication").getWebValue()); + newUser.setUserStatusId(Globals.USER_STATUS_AWAITING_EMAIL_VERIFICATION); + userBean.storeUserFirstTime(newUser, auth); + // Send email about user verification + if(newUser.getUserStatusId().equals(Globals.USER_STATUS_AWAITING_EMAIL_VERIFICATION)) + { + userBean.sendUserEmailVerification(newUser, SessionLocaleUtil.getI18nBundle(request), ServletUtil.getServerName(request)); + } + response.sendRedirect(new StringBuilder("http://").append(ServletUtil.getServerName(request)).append("/user?action=registerNewUserFormReceipt").toString()); } - // Adding user info - newUser.setEmail(formValidation.getFormField("email").getWebValue()); - newUser.setFirstName(formValidation.getFormField("firstName").getWebValue()); - newUser.setLastName(formValidation.getFormField("lastName").getWebValue()); - Organization organization = em.find(Organization.class, formValidation.getFormField("organizationId").getValueAsInteger()); - newUser.setOrganizationId(organization); - newUser.setApprovalApplication(formValidation.getFormField("approvalApplication").getWebValue()); - newUser.setUserStatusId(Globals.USER_STATUS_AWAITING_EMAIL_VERIFICATION); - userBean.storeUserFirstTime(newUser, auth); - // Send email about user verification - if(newUser.getUserStatusId().equals(Globals.USER_STATUS_AWAITING_EMAIL_VERIFICATION)) + else { - userBean.sendUserEmailVerification(newUser, SessionLocaleUtil.getI18nBundle(request), ServletUtil.getServerName(request)); + request.setAttribute("formValidation", formValidation); + request.setAttribute("organizations", em.createNamedQuery("Organization.findAll").getResultList()); + request.setAttribute("userAuthenticationTypeId", userAuthenticationType.getUserAuthenticationTypeId()); + request.getRequestDispatcher("/userRegistrationForm.ftl").forward(request, response); } - response.sendRedirect(new StringBuilder("http://").append(ServletUtil.getServerName(request)).append("/user?action=registerNewUserFormReceipt").toString()); } - else + catch(FormValidationException ex) { - request.setAttribute("formValidation", formValidation); - request.setAttribute("organizations", em.createNamedQuery("Organization.findAll").getResultList()); - request.setAttribute("userAuthenticationTypeId", userAuthenticationType.getUserAuthenticationTypeId()); - request.getRequestDispatcher("/userRegistrationForm.ftl").forward(request, response); + response.sendError(500, ex.getMessage()); } } else if(action.equals("registerNewUserFormReceipt")) diff --git a/src/main/java/no/bioforsk/vips/logic/controller/session/OrganismBean.java b/src/main/java/no/bioforsk/vips/logic/controller/session/OrganismBean.java new file mode 100644 index 0000000000000000000000000000000000000000..69bc10d427be8659645ba0235f3b89078f78221f --- /dev/null +++ b/src/main/java/no/bioforsk/vips/logic/controller/session/OrganismBean.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package no.bioforsk.vips.logic.controller.session; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import javax.ejb.Stateless; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; +import no.bioforsk.vips.logic.entity.ExternalResource; +import no.bioforsk.vips.logic.entity.ExternalResourceType; +import no.bioforsk.vips.logic.entity.HierarchyCategory; +import no.bioforsk.vips.logic.entity.Organism; +import no.bioforsk.vips.logic.entity.OrganismExternalResource; +import no.bioforsk.vips.logic.entity.OrganismLocale; +import no.bioforsk.vips.logic.entity.OrganismLocalePK; +import no.bioforsk.vips.logic.util.HierarchyCategoryLocaleNames; + +/** + * @copyright 2014 <a href="http://www.bioforsk.no/">Bioforsk</a> + * @author Tor-Einar Skog <tor-einar.skog@bioforsk.no> + */ +@Stateless +public class OrganismBean { + @PersistenceContext(unitName="VIPSLogic-PU") + EntityManager em; + + + /** + * + * @param parentOrganismId Id of the parent organism you start the tree from. If NULL, all top nodes are selected + * @return All child nodes of given organism, organized in tree + */ + public List<Organism> getOrganismSubTree(Integer parentOrganismId){ + List<Organism> retVal; + if(parentOrganismId == null) + { + retVal = em.createNativeQuery("SELECT * FROM Organism o WHERE o.parent_organism_id IS NULL", Organism.class).getResultList(); + } + else + { + retVal = em.createNamedQuery("Organism.findByParentOrganismId").setParameter("parentOrganismId", parentOrganismId).getResultList(); + } + + for(Organism organism : retVal) + { + organism.setChildOrganisms(this.getOrganismSubTree(organism.getOrganismId())); + } + return retVal; + + } + + /** + * + * @param organismId + * @return the requested organism and its children AND their children again + */ + public Organism getOrganismAndChildrenTwoLevels(Integer organismId) + { + Organism retVal = em.find(Organism.class, organismId); + retVal.setChildOrganisms(em.createNamedQuery("Organism.findByParentOrganismId").setParameter("parentOrganismId", organismId).getResultList()); + // Iterate and set children of next level (to decide if the child is deletable) + for(Organism child: retVal.getChildOrganisms()) + { + List<Organism> grandChildren = em.createNamedQuery("Organism.findByParentOrganismId").setParameter("parentOrganismId", child.getOrganismId()).getResultList(); + child.setChildOrganisms(grandChildren); + } + return retVal; + } + + /** + * + * @return top level organisms and direct children + */ + public List<Organism> getTopLevelOrganisms() + { + List<Organism> retVal = em.createNativeQuery("SELECT * FROM Organism o WHERE o.parent_organism_id IS NULL", Organism.class).getResultList(); + for(Organism organism: retVal) + { + List<Organism> children = em.createNamedQuery("Organism.findByParentOrganismId").setParameter("parentOrganismId", organism.getOrganismId()).getResultList(); + organism.setChildOrganisms(children); + } + return retVal; + } + + public List<ExternalResource> getUnusedExternalResourcesForOrganism(Organism organism) { + StringBuilder sql = new StringBuilder() + .append("SELECT * FROM external_resource ") + .append("WHERE external_resource_type_id=") + .append(ExternalResourceType.ORGANISM_DATABASE).append(" \n"); + if(organism.getOrganismExternalResourceSet() == null || organism.getOrganismExternalResourceSet().isEmpty()) + { + return em.createNativeQuery(sql.toString(), ExternalResource.class).getResultList(); + } + else + { + sql.append("AND external_resource_id NOT IN (:externalResourceIds)"); + List<Integer> ids = new ArrayList<>(); + for(OrganismExternalResource ore : organism.getOrganismExternalResourceSet()) + { + ids.add(ore.getExternalResource().getExternalResourceId()); + } + + Query q = em.createNativeQuery(sql.toString(), ExternalResource.class); + q.setParameter("externalResourceIds", ids); + return q.getResultList(); + } + } + + public Organism storeOrganism(Organism organism) { + // Ensure that parentOrganismId = -1 => null + if(organism.getParentOrganismId().equals(-1)) + { + organism.setParentOrganismId(null); + } + return em.merge(organism); + } + + public void storeOrganismExternalResource(OrganismExternalResource organismExternalResource) { + em.merge(organismExternalResource); + } + + public HierarchyCategoryLocaleNames getHierarchyCategoryNames(Locale locale) { + Map<Integer, String> map = new HashMap<>(); + for(HierarchyCategory cat:em.createNamedQuery("HierarchyCategory.findAll", HierarchyCategory.class).getResultList()) + { + map.put(cat.getHierarchyCategoryId(), cat.getLocalName(locale.getLanguage())); + } + + HierarchyCategoryLocaleNames retVal = new HierarchyCategoryLocaleNames(); + retVal.setNameMap(map); + return retVal; + } + + /** + * Removes an organism from database. Does this only if it has no children + * @param organismId + */ + public boolean deleteOrganism(Integer organismId) { + List<Organism> children = em.createNamedQuery("Organism.findByParentOrganismId").setParameter("parentOrganismId", organismId).getResultList(); + if(children == null || children.isEmpty()) + { + Organism organism = em.find(Organism.class, organismId); + em.remove(organism); + return true; + } + else + { + return false; + } + } + + /** + * Adds local name in given locale to organism + * @param organism + * @param localName + * @param currentLocale + */ + public void storeOrganismLocalName(Organism organism, String localName, Locale currentLocale) { + + if(organism.getOrganismLocale(currentLocale.getLanguage()) == null) + { + + OrganismLocalePK pk = new OrganismLocalePK(organism.getOrganismId(), currentLocale.getLanguage()); + OrganismLocale oLocale = new OrganismLocale(pk); + oLocale.setLocalName(localName); + em.persist(oLocale); + } + else + { + OrganismLocale oLocale = organism.getOrganismLocale(currentLocale.getLanguage()); + oLocale.setLocalName(localName); + } + } + +} diff --git a/src/main/java/no/bioforsk/vips/logic/entity/ExternalResource.java b/src/main/java/no/bioforsk/vips/logic/entity/ExternalResource.java index 52430f0302f51fad52b2aee9362eedd726b4e988..d766d6cee5376287af7b14080969a5751cdee7cc 100644 --- a/src/main/java/no/bioforsk/vips/logic/entity/ExternalResource.java +++ b/src/main/java/no/bioforsk/vips/logic/entity/ExternalResource.java @@ -1,6 +1,20 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * Copyright (c) 2013-2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * */ package no.bioforsk.vips.logic.entity; diff --git a/src/main/java/no/bioforsk/vips/logic/entity/ExternalResourceType.java b/src/main/java/no/bioforsk/vips/logic/entity/ExternalResourceType.java index ff296be51349d501b632d1c9cc6e3e5f25596321..fbe7aed129ae63b3081a976f90706e6e79419740 100644 --- a/src/main/java/no/bioforsk/vips/logic/entity/ExternalResourceType.java +++ b/src/main/java/no/bioforsk/vips/logic/entity/ExternalResourceType.java @@ -1,8 +1,21 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * Copyright (c) 2013-2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * */ - package no.bioforsk.vips.logic.entity; import java.io.Serializable; @@ -33,6 +46,9 @@ import org.codehaus.jackson.annotate.JsonIgnore; @NamedQuery(name = "ExternalResourceType.findByExternalResourceTypeId", query = "SELECT e FROM ExternalResourceType e WHERE e.externalResourceTypeId = :externalResourceTypeId"), @NamedQuery(name = "ExternalResourceType.findByDefaultName", query = "SELECT e FROM ExternalResourceType e WHERE e.defaultName = :defaultName")}) public class ExternalResourceType implements Serializable { + + public static final int ORGANISM_DATABASE = 2; + private static final long serialVersionUID = 1L; @Id @Basic(optional = false) diff --git a/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategory.java b/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategory.java index ec1d5d8e3a22b362776d1d4324d86510d0af3b84..537c3ada7ee08b21089cb97d545a9b203b801dad 100644 --- a/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategory.java +++ b/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategory.java @@ -8,6 +8,7 @@ package no.bioforsk.vips.logic.entity; 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.Id; @@ -15,6 +16,7 @@ import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; import javax.persistence.Table; +import javax.persistence.Transient; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; @@ -34,6 +36,8 @@ import org.codehaus.jackson.annotate.JsonIgnore; @NamedQuery(name = "HierarchyCategory.findByDefaultName", query = "SELECT h FROM HierarchyCategory h WHERE h.defaultName = :defaultName"), @NamedQuery(name = "HierarchyCategory.findByLogicallyDeleted", query = "SELECT h FROM HierarchyCategory h WHERE h.logicallyDeleted = :logicallyDeleted")}) public class HierarchyCategory implements Serializable { + @OneToMany(cascade = CascadeType.ALL, mappedBy = "hierarchyCategoryId") + private Set<HierarchyCategoryLocale> hierarchyCategoryLocaleSet; private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @@ -121,4 +125,27 @@ public class HierarchyCategory implements Serializable { return "no.bioforsk.vips.logic.entity.HierarchyCategory[ hierarchyCategoryId=" + hierarchyCategoryId + " ]"; } + @XmlTransient + @JsonIgnore + public Set<HierarchyCategoryLocale> getHierarchyCategoryLocaleSet() { + return hierarchyCategoryLocaleSet; + } + + public void setHierarchyCategoryLocaleSet(Set<HierarchyCategoryLocale> hierarchyCategoryLocaleSet) { + this.hierarchyCategoryLocaleSet = hierarchyCategoryLocaleSet; + } + + @Transient + public String getLocalName(String locale) + { + for(HierarchyCategoryLocale hLocale: this.getHierarchyCategoryLocaleSet()) + { + if(hLocale.getHierarchyCategoryLocalePK().getLocale().equals(locale)) + { + return hLocale.getLocalName(); + } + } + + return ""; + } } diff --git a/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategoryLocale.java b/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategoryLocale.java new file mode 100644 index 0000000000000000000000000000000000000000..84942351fa4d17761afae713282b013cb74e1ddd --- /dev/null +++ b/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategoryLocale.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package no.bioforsk.vips.logic.entity; + +import java.io.Serializable; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @copyright 2014 <a href="http://www.bioforsk.no/">Bioforsk</a> + * @author Tor-Einar Skog <tor-einar.skog@bioforsk.no> + */ +@Entity +@Table(name = "hierarchy_category_locale") +@XmlRootElement +@NamedQueries({ + @NamedQuery(name = "HierarchyCategoryLocale.findAll", query = "SELECT h FROM HierarchyCategoryLocale h"), + @NamedQuery(name = "HierarchyCategoryLocale.findByHierarchyCategoryId", query = "SELECT h FROM HierarchyCategoryLocale h WHERE h.hierarchyCategoryLocalePK.hierarchyCategoryId = :hierarchyCategoryId"), + @NamedQuery(name = "HierarchyCategoryLocale.findByLocale", query = "SELECT h FROM HierarchyCategoryLocale h WHERE h.hierarchyCategoryLocalePK.locale = :locale"), + @NamedQuery(name = "HierarchyCategoryLocale.findByLocalName", query = "SELECT h FROM HierarchyCategoryLocale h WHERE h.localName = :localName")}) +public class HierarchyCategoryLocale implements Serializable { + private static final long serialVersionUID = 1L; + @EmbeddedId + protected HierarchyCategoryLocalePK hierarchyCategoryLocalePK; + @Size(max = 255) + @Column(name = "local_name") + private String localName; + @Column(name = "hierarchy_category_id", insertable = false, updatable = false) + private Integer hierarchyCategoryId; + + public HierarchyCategoryLocale() { + } + + public HierarchyCategoryLocale(HierarchyCategoryLocalePK hierarchyCategoryLocalePK) { + this.hierarchyCategoryLocalePK = hierarchyCategoryLocalePK; + } + + public HierarchyCategoryLocale(int hierarchyCategoryId, String locale) { + this.hierarchyCategoryLocalePK = new HierarchyCategoryLocalePK(hierarchyCategoryId, locale); + } + + public HierarchyCategoryLocalePK getHierarchyCategoryLocalePK() { + return hierarchyCategoryLocalePK; + } + + public void setHierarchyCategoryLocalePK(HierarchyCategoryLocalePK hierarchyCategoryLocalePK) { + this.hierarchyCategoryLocalePK = hierarchyCategoryLocalePK; + } + + public String getLocalName() { + return localName; + } + + public void setLocalName(String localName) { + this.localName = localName; + } + + + @Override + public int hashCode() { + int hash = 0; + hash += (hierarchyCategoryLocalePK != null ? hierarchyCategoryLocalePK.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 HierarchyCategoryLocale)) { + return false; + } + HierarchyCategoryLocale other = (HierarchyCategoryLocale) object; + if ((this.hierarchyCategoryLocalePK == null && other.hierarchyCategoryLocalePK != null) || (this.hierarchyCategoryLocalePK != null && !this.hierarchyCategoryLocalePK.equals(other.hierarchyCategoryLocalePK))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "no.bioforsk.vips.logic.entity.HierarchyCategoryLocale[ hierarchyCategoryLocalePK=" + hierarchyCategoryLocalePK + " ]"; + } + +} diff --git a/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategoryLocalePK.java b/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategoryLocalePK.java new file mode 100644 index 0000000000000000000000000000000000000000..8566fa1665ae993d68f81c56cadb4871a1b94a00 --- /dev/null +++ b/src/main/java/no/bioforsk/vips/logic/entity/HierarchyCategoryLocalePK.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package no.bioforsk.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 2014 <a href="http://www.bioforsk.no/">Bioforsk</a> + * @author Tor-Einar Skog <tor-einar.skog@bioforsk.no> + */ +@Embeddable +public class HierarchyCategoryLocalePK implements Serializable { + @Basic(optional = false) + @NotNull + @Column(name = "hierarchy_category_id") + private int hierarchyCategoryId; + @Basic(optional = false) + @NotNull + @Size(min = 1, max = 10) + @Column(name = "locale") + private String locale; + + public HierarchyCategoryLocalePK() { + } + + public HierarchyCategoryLocalePK(int hierarchyCategoryId, String locale) { + this.hierarchyCategoryId = hierarchyCategoryId; + this.locale = locale; + } + + public int getHierarchyCategoryId() { + return hierarchyCategoryId; + } + + public void setHierarchyCategoryId(int hierarchyCategoryId) { + this.hierarchyCategoryId = hierarchyCategoryId; + } + + public String getLocale() { + return locale; + } + + public void setLocale(String locale) { + this.locale = locale; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (int) hierarchyCategoryId; + 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 HierarchyCategoryLocalePK)) { + return false; + } + HierarchyCategoryLocalePK other = (HierarchyCategoryLocalePK) object; + if (this.hierarchyCategoryId != other.hierarchyCategoryId) { + 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.bioforsk.vips.logic.entity.HierarchyCategoryLocalePK[ hierarchyCategoryId=" + hierarchyCategoryId + ", locale=" + locale + " ]"; + } + +} diff --git a/src/main/java/no/bioforsk/vips/logic/entity/Organism.java b/src/main/java/no/bioforsk/vips/logic/entity/Organism.java index edd0dc7d727566f5abfa72464686127d0e7f803c..3ea50f35754926139ec6d55f1d102367148ca50a 100644 --- a/src/main/java/no/bioforsk/vips/logic/entity/Organism.java +++ b/src/main/java/no/bioforsk/vips/logic/entity/Organism.java @@ -1,33 +1,46 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * Copyright (c) 2013-2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * */ package no.bioforsk.vips.logic.entity; import java.io.Serializable; +import java.util.List; 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.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; import javax.persistence.Table; +import javax.persistence.Transient; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlTransient; -import org.codehaus.jackson.annotate.JsonIgnore; /** - * @copyright 2013 <a href="http://www.bioforsk.no/">Bioforsk</a> + * @copyright 2013-2014 <a href="http://www.bioforsk.no/">Bioforsk</a> * @author Tor-Einar Skog <tor-einar.skog@bioforsk.no> */ @Entity @@ -36,6 +49,7 @@ import org.codehaus.jackson.annotate.JsonIgnore; @NamedQueries({ @NamedQuery(name = "Organism.findAll", query = "SELECT o FROM Organism o"), @NamedQuery(name = "Organism.findByOrganismId", query = "SELECT o FROM Organism o WHERE o.organismId = :organismId"), + @NamedQuery(name = "Organism.findByParentOrganismId", query = "SELECT o FROM Organism o WHERE o.parentOrganismId = :parentOrganismId"), @NamedQuery(name = "Organism.findByLatinName", query = "SELECT o FROM Organism o WHERE o.latinName = :latinName"), @NamedQuery(name = "Organism.findByTradeName", query = "SELECT o FROM Organism o WHERE o.tradeName = :tradeName"), @NamedQuery(name = "Organism.findByLogicallyDeleted", query = "SELECT o FROM Organism o WHERE o.logicallyDeleted = :logicallyDeleted")}) @@ -56,18 +70,33 @@ public class Organism implements Serializable { @NotNull @Column(name = "logically_deleted") private boolean logicallyDeleted; - @OneToMany(cascade = CascadeType.ALL, mappedBy = "organism") + + // We simplify this to avoid very large queries + @Column(name = "parent_organism_id") + private Integer parentOrganismId; + @Column(name = "hierarchy_category_id") + private Integer hierarchyCategoryId; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "organismId", fetch = FetchType.EAGER) + private Set<OrganismLocale> organismLocaleSet; + @OneToMany(cascade = CascadeType.ALL, mappedBy = "organism", fetch = FetchType.EAGER) + private Set<OrganismExternalResource> organismExternalResourceSet; + + @Transient + private List<Organism> childOrganisms; + + /*@OneToMany(cascade = CascadeType.ALL, mappedBy = "organism") private Set<OrganismLocale> organismLocaleSet; @OneToMany(cascade = CascadeType.ALL, mappedBy = "organism") private Set<OrganismExternalResource> organismExternalResourceSet; - @OneToMany(mappedBy = "parentOrganismId") + @OneToMany(mappedBy = "parentOrganismId", fetch = FetchType.EAGER) private Set<Organism> organismSet; @JoinColumn(name = "parent_organism_id", referencedColumnName = "organism_id") - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) private Organism parentOrganismId; @JoinColumn(name = "hierarchy_category_id", referencedColumnName = "hierarchy_category_id") @ManyToOne private HierarchyCategory hierarchyCategoryId; + */ public Organism() { } @@ -113,8 +142,7 @@ public class Organism implements Serializable { this.logicallyDeleted = logicallyDeleted; } - @XmlTransient - @JsonIgnore + public Set<OrganismLocale> getOrganismLocaleSet() { return organismLocaleSet; } @@ -123,8 +151,6 @@ public class Organism implements Serializable { this.organismLocaleSet = organismLocaleSet; } - @XmlTransient - @JsonIgnore public Set<OrganismExternalResource> getOrganismExternalResourceSet() { return organismExternalResourceSet; } @@ -133,8 +159,7 @@ public class Organism implements Serializable { this.organismExternalResourceSet = organismExternalResourceSet; } - @XmlTransient - @JsonIgnore + /* public Set<Organism> getOrganismSet() { return organismSet; } @@ -143,6 +168,7 @@ public class Organism implements Serializable { this.organismSet = organismSet; } + @JsonIgnore public Organism getParentOrganismId() { return parentOrganismId; } @@ -158,6 +184,7 @@ public class Organism implements Serializable { public void setHierarchyCategoryId(HierarchyCategory hierarchyCategoryId) { this.hierarchyCategoryId = hierarchyCategoryId; } + */ @Override public int hashCode() { @@ -184,4 +211,75 @@ public class Organism implements Serializable { return "no.bioforsk.vips.logic.entity.Organism[ organismId=" + organismId + " ]"; } + /** + * @return the parentOrganismId + */ + public Integer getParentOrganismId() { + return parentOrganismId; + } + + /** + * @param parentOrganismId the parentOrganismId to set + */ + public void setParentOrganismId(Integer parentOrganismId) { + this.parentOrganismId = parentOrganismId; + } + + /** + * @return the hierarchyCategoryId + */ + public Integer getHierarchyCategoryId() { + return hierarchyCategoryId; + } + + /** + * @param hierarchyCategoryId the hierarchyCategoryId to set + */ + public void setHierarchyCategoryId(Integer hierarchyCategoryId) { + this.hierarchyCategoryId = hierarchyCategoryId; + } + + @Transient + public List<Organism> getChildOrganisms() + { + return this.childOrganisms; + } + + /** + * @param childOrganisms the childOrganisms to set + */ + @Transient + public void setChildOrganisms(List<Organism> childOrganisms) { + this.childOrganisms = childOrganisms; + } + + @Transient + public String getLocalName(String locale) + { + for(OrganismLocale oLocale: this.getOrganismLocaleSet()) + { + if(oLocale.getOrganismLocalePK().getLocale().equals(locale)) + { + return oLocale.getLocalName(); + } + } + + return ""; + } + + @Transient + public OrganismLocale getOrganismLocale(String language) { + if(this.getOrganismLocaleSet() == null) + { + return null; + } + for(OrganismLocale oLocale:this.getOrganismLocaleSet()) + { + if(oLocale.getOrganismLocalePK().getLocale().equals(language)) + { + return oLocale; + } + } + return null; + } } diff --git a/src/main/java/no/bioforsk/vips/logic/entity/OrganismExternalResource.java b/src/main/java/no/bioforsk/vips/logic/entity/OrganismExternalResource.java index 6b3858656c76b4d289db52e076674cae97246648..5426d7bd3a0138b11d20c290f1322220a2a613ee 100644 --- a/src/main/java/no/bioforsk/vips/logic/entity/OrganismExternalResource.java +++ b/src/main/java/no/bioforsk/vips/logic/entity/OrganismExternalResource.java @@ -14,6 +14,7 @@ import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; +import javax.persistence.Transient; import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; @@ -111,4 +112,12 @@ public class OrganismExternalResource implements Serializable { return "no.bioforsk.vips.logic.entity.OrganismExternalResource[ organismExternalResourcePK=" + organismExternalResourcePK + " ]"; } + @Transient + public String getResourceUrl() + { + StringBuilder retVal = new StringBuilder() + .append(this.getExternalResource().getUri()) + .append(this.getExternalResource().getIdentifierTemplate()); + return String.format(retVal.toString(), this.getResourceIdentifier()); + } } diff --git a/src/main/java/no/bioforsk/vips/logic/entity/OrganismLocale.java b/src/main/java/no/bioforsk/vips/logic/entity/OrganismLocale.java index 2ba06c284b66a38417d313bc4229cf2a15bf8801..69cd61975edd7a7061e1ddfc59343532e5162a26 100644 --- a/src/main/java/no/bioforsk/vips/logic/entity/OrganismLocale.java +++ b/src/main/java/no/bioforsk/vips/logic/entity/OrganismLocale.java @@ -1,6 +1,20 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * Copyright (c) 2013-2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * */ package no.bioforsk.vips.logic.entity; @@ -9,8 +23,6 @@ import java.io.Serializable; import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; @@ -18,7 +30,7 @@ import javax.validation.constraints.Size; import javax.xml.bind.annotation.XmlRootElement; /** - * @copyright 2013 <a href="http://www.bioforsk.no/">Bioforsk</a> + * @copyright 2013-2014 <a href="http://www.bioforsk.no/">Bioforsk</a> * @author Tor-Einar Skog <tor-einar.skog@bioforsk.no> */ @Entity @@ -36,10 +48,9 @@ public class OrganismLocale implements Serializable { @Size(max = 255) @Column(name = "local_name") private String localName; - @JoinColumn(name = "organism_id", referencedColumnName = "organism_id", insertable = false, updatable = false) - @ManyToOne(optional = false) - private Organism organism; - + @Column(name = "organism_id", insertable = false, updatable = false) + private Integer organismId; + public OrganismLocale() { } @@ -67,13 +78,7 @@ public class OrganismLocale implements Serializable { this.localName = localName; } - public Organism getOrganism() { - return organism; - } - - public void setOrganism(Organism organism) { - this.organism = organism; - } + @Override public int hashCode() { diff --git a/src/main/java/no/bioforsk/vips/logic/entity/OrganismLocalePK.java b/src/main/java/no/bioforsk/vips/logic/entity/OrganismLocalePK.java index bd89b4d8231f5d71843268b0d2262cd097d26d0b..5b290fc2621ef58e2007db055d6a0c8de683af92 100644 --- a/src/main/java/no/bioforsk/vips/logic/entity/OrganismLocalePK.java +++ b/src/main/java/no/bioforsk/vips/logic/entity/OrganismLocalePK.java @@ -1,6 +1,20 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * Copyright (c) 2013-2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * */ package no.bioforsk.vips.logic.entity; diff --git a/src/main/java/no/bioforsk/vips/logic/i18n/LocalizationFilter.java b/src/main/java/no/bioforsk/vips/logic/i18n/LocalizationFilter.java index 133de6dad04bf560ccba6ea45d7a1046f751a36e..5eb93874d92b72620831ad4c07eae2fca6c2783c 100644 --- a/src/main/java/no/bioforsk/vips/logic/i18n/LocalizationFilter.java +++ b/src/main/java/no/bioforsk/vips/logic/i18n/LocalizationFilter.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2013-2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * + */ + package no.bioforsk.vips.logic.i18n; import java.io.IOException; diff --git a/src/main/java/no/bioforsk/vips/logic/i18n/SessionLocaleUtil.java b/src/main/java/no/bioforsk/vips/logic/i18n/SessionLocaleUtil.java index e4fe4430cf37f65de5de0d2e660019c1e6379e22..318048abd7cb355e6ec5db600ab7f3cc0afbb6eb 100644 --- a/src/main/java/no/bioforsk/vips/logic/i18n/SessionLocaleUtil.java +++ b/src/main/java/no/bioforsk/vips/logic/i18n/SessionLocaleUtil.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2013-2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * + */ + package no.bioforsk.vips.logic.i18n; import java.util.Locale; diff --git a/src/main/java/no/bioforsk/vips/logic/util/HierarchyCategoryLocaleNames.java b/src/main/java/no/bioforsk/vips/logic/util/HierarchyCategoryLocaleNames.java new file mode 100644 index 0000000000000000000000000000000000000000..6905fc2bb60a24a0a180dadd58f6f38c0c19cc7f --- /dev/null +++ b/src/main/java/no/bioforsk/vips/logic/util/HierarchyCategoryLocaleNames.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package no.bioforsk.vips.logic.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * @copyright 2014 <a href="http://www.bioforsk.no/">Bioforsk</a> + * @author Tor-Einar Skog <tor-einar.skog@bioforsk.no> + */ +public class HierarchyCategoryLocaleNames { + + private Map<Integer, String> nameMap; + + public String getName(Integer hierarchyCategoryId) + { + return this.nameMap.get(hierarchyCategoryId); + } + + public List<Integer> getHierarchyCategoryIds() + { + List<Integer> retVal = new ArrayList(this.getNameMap().keySet()); + Collections.sort(retVal); + return retVal; + } + + /** + * @return the nameMap + */ + public Map<Integer, String> getNameMap() { + return nameMap; + } + + /** + * @param nameMap the nameMap to set + */ + public void setNameMap(Map<Integer, String> nameMap) { + this.nameMap = nameMap; + } + + +} diff --git a/src/main/java/no/bioforsk/web/forms/FormField.java b/src/main/java/no/bioforsk/web/forms/FormField.java index b4ac5068f935c209e785910ce59047805602fc3e..1b07115f8ebcd8d0658f05cc25dc4cb9458467c1 100644 --- a/src/main/java/no/bioforsk/web/forms/FormField.java +++ b/src/main/java/no/bioforsk/web/forms/FormField.java @@ -22,7 +22,9 @@ package no.bioforsk.web.forms; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.codehaus.jackson.annotate.JsonIgnore; /** @@ -49,6 +51,8 @@ public class FormField { public final static String FIELD_TYPE_HIDDEN = "HIDDEN"; public final static String FIELD_TYPE_SELECT_SINGLE = "SELECT_SINGLE"; public final static String FIELD_TYPE_SELECT_MULTIPLE = "SELECT_MULTIPLE"; + // Multiple inputs for map. (e.g. <input type="text" name="relatedItem_25" value="Foo"/>,<input type="text" name="relatedItem_3" value="Bar"/> + public final static String FIELD_TYPE_MULTIPLE_MAP = "MULTIPLE_MAP"; // Standard format for dates is the ISO-8861-format public final static String DATE_DEFAULT_FORMAT = "yyyy-MM-dd"; @@ -369,5 +373,5 @@ public class FormField { { return this.getWebValue() == null || this.getWebValue().trim().isEmpty(); } - + } diff --git a/src/main/java/no/bioforsk/web/forms/FormValidation.java b/src/main/java/no/bioforsk/web/forms/FormValidation.java index aa4bcd10f45dead2af73184a383c2690c50ee4b1..e740d2fa9d76a172181ebd63c6b4fe813106b3c1 100644 --- a/src/main/java/no/bioforsk/web/forms/FormValidation.java +++ b/src/main/java/no/bioforsk/web/forms/FormValidation.java @@ -12,6 +12,7 @@ public class FormValidation { private Map<String,FormField> formFields; + private Map<String,Map<String,FormField>> multipleMapFormFields; /** * @return the valid If at least one field is not valid @@ -67,5 +68,37 @@ public class FormValidation { public void setFormFields(Map<String,FormField> formFields) { this.formFields = formFields; } + + /** + * @return the multipleMapFormFields + */ + public Map<String,Map<String,FormField>> getMultipleMapFormFields() { + if(this.multipleMapFormFields == null) + { + this.multipleMapFormFields = new HashMap<>(); + } + return multipleMapFormFields; + } + + /** + * @param multipleMapFormFields the multipleMapFormFields to set + */ + public void setMultipleMapFormFields(Map<String,Map<String,FormField>> multipleMapFormFields) { + this.multipleMapFormFields = multipleMapFormFields; + } + public void addMultipleMapFormField(String fieldName, String key, FormField formField) + { + if(this.multipleMapFormFields == null) + { + this.multipleMapFormFields = new HashMap<>(); + } + Map<String, FormField> fieldMap = this.multipleMapFormFields.get(fieldName); + if(fieldMap == null) + { + fieldMap = new HashMap<>(); + this.multipleMapFormFields.put(fieldName, fieldMap); + } + fieldMap.put(key, formField); + } } diff --git a/src/main/java/no/bioforsk/web/forms/FormValidationException.java b/src/main/java/no/bioforsk/web/forms/FormValidationException.java new file mode 100644 index 0000000000000000000000000000000000000000..16289cbe2ac7abf7e595e716d4467b4e86db221a --- /dev/null +++ b/src/main/java/no/bioforsk/web/forms/FormValidationException.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package no.bioforsk.web.forms; + +/** + * @copyright 2014 <a href="http://www.bioforsk.no/">Bioforsk</a> + * @author Tor-Einar Skog <tor-einar.skog@bioforsk.no> + */ +public class FormValidationException extends Exception { + + /** + * Creates a new instance of <code>FormValidationException</code> without detail message. + */ + public FormValidationException() { + } + + + /** + * Constructs an instance of <code>FormValidationException</code> with the specified detail message. + * @param msg the detail message. + */ + public FormValidationException(String msg) { + super(msg); + } +} diff --git a/src/main/java/no/bioforsk/web/forms/FormValidator.java b/src/main/java/no/bioforsk/web/forms/FormValidator.java index d9162601be4b33f2ae6852952654eed868372b90..8d1b01174df84afdcf5e1a07cbd2ba5cabfc466c 100644 --- a/src/main/java/no/bioforsk/web/forms/FormValidator.java +++ b/src/main/java/no/bioforsk/web/forms/FormValidator.java @@ -1,3 +1,22 @@ +/* + * Copyright (c) 2013-2014 Bioforsk <http://www.bioforsk.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic 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. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + * + */ + package no.bioforsk.web.forms; import java.io.IOException; @@ -5,11 +24,14 @@ import java.io.InputStream; import java.text.MessageFormat; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; +import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.MissingResourceException; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import no.bioforsk.vips.logic.authenticate.PasswordValidationException; @@ -38,27 +60,77 @@ public class FormValidator { public static String RELATION_TYPE_EQUALS = "EQUALS"; public static String RELATION_TYPE_AFTER = "AFTER"; - public static FormValidation validateForm(String formName, HttpServletRequest request, ServletContext servletContext) throws IOException { + public static FormValidation validateForm(String formName, HttpServletRequest request, ServletContext servletContext) throws IOException, FormValidationException { JsonNode formDefinition = getFormDefinition(formName, servletContext); return validateForm(formDefinition, request); } - public static FormValidation validateForm(String formDefinitionStr, HttpServletRequest request) throws IOException + public static FormValidation validateForm(String formDefinitionStr, HttpServletRequest request) throws IOException, FormValidationException { JsonNode formDefinition = getFormDefinition(formDefinitionStr); return validateForm(formDefinition, request); } - public static FormValidation validateForm(JsonNode formDefinition, HttpServletRequest request) + public static FormValidation validateForm(JsonNode formDefinition, HttpServletRequest request) throws FormValidationException { List<FormField> fields = new ObjectMapper().convertValue(formDefinition.findValue("fields"), new TypeReference<List<FormField>>(){}); FormValidation retVal = new FormValidation(); + // If one of the fields is a multiple map, we must get them from the form and add them + List<FormField> multipleMapFields = new ArrayList<>(); + for(FormField field: fields) + { + if(field.getFieldType().equals(FormField.FIELD_TYPE_MULTIPLE_MAP)) + { + // By convention, these fields always end with "_*", where * denotes the key. + // So we loop through the requests and stores all that matches (begins with) fieldName + + for(Enumeration en = request.getParameterNames();en.hasMoreElements();) + { + String parameterName = (String) en.nextElement(); + if(parameterName.startsWith(field.getName())) + { + FormField newField = new FormField(); + newField.setName(parameterName); + newField.setDataType(field.getDataType()); + newField.setRequired(field.isRequired()); + newField.setWebValue(request.getParameter(parameterName)); + multipleMapFields.add(newField); + retVal.addMultipleMapFormField(field.getName(), parameterName.substring(field.getName().length() + 1), newField); + } + } + } + } + fields.addAll(multipleMapFields); + for(FormField field: fields) { + // Check for NULL fieldType + if(field.getDataType() == null) + { + throw new FormValidationException("Missing datatype definition for field " + field.getName()); + } + + // Skip multiple map fields, as they've been exploded in the loop above. + if(field.getFieldType().equals(FormField.FIELD_TYPE_MULTIPLE_MAP)) + { + continue; + } + + + retVal.addFormField(field); - field.setLabel(SessionLocaleUtil.getI18nText(request, field.getName())); + try + { + field.setLabel(SessionLocaleUtil.getI18nText(request, field.getName())); + } + catch(MissingResourceException ex) + { + field.setLabel(field.getName()); + } + field.setWebValue(request.getParameterValues(field.getName())); + if(field.getWebValue() == null || field.getWebValue().isEmpty()) { if(field.isRequired()) diff --git a/src/main/resources/no/bioforsk/vips/logic/i18n/vipslogictexts.properties b/src/main/resources/no/bioforsk/vips/logic/i18n/vipslogictexts.properties index bc146e28a296f3bc73cca6447e10d0ba92e0c6e2..cb9d09df328eda554c8e20a95f0a1c7844711bab 100644 --- a/src/main/resources/no/bioforsk/vips/logic/i18n/vipslogictexts.properties +++ b/src/main/resources/no/bioforsk/vips/logic/i18n/vipslogictexts.properties @@ -144,3 +144,13 @@ attachIdToExistingUser=Add this login to my existing user confirmEmailReceipt=Your email was successfully confirmed. You will be notified as soon as the organization administrator approves your application. confirmEmailFailure=Your email address was not confirmed. Please contact the system administrator. attachIdToExistingUserReceipt=The id was successfully connected to the user. You may now log in with it +externalResources=External resources +externalResourceIdentifier=External resource identifier +organismId=Organism id +parentOrganismId=Parent organism +newOrganism=New organism +hierarchyCategoryId=Hierarchy category +organismUpdated=Organism was updated +organismRegistered=Organism was registered +organismDeleted=Organism was deleted +organismNotDeleted=Organism was not deleted diff --git a/src/main/resources/no/bioforsk/vips/logic/i18n/vipslogictexts_no.properties b/src/main/resources/no/bioforsk/vips/logic/i18n/vipslogictexts_no.properties index 7080b1085e1afd8e4c14b55aca33c5b913226e49..53b6a771ed1820f960ac39e39bf6a55f77a59bac 100644 --- a/src/main/resources/no/bioforsk/vips/logic/i18n/vipslogictexts_no.properties +++ b/src/main/resources/no/bioforsk/vips/logic/i18n/vipslogictexts_no.properties @@ -144,3 +144,13 @@ attachIdToExistingUser=Add this login to my existing user confirmEmailReceipt=Din e-postadresse ble bekreftet. Du blir varslet s\u00e5 snart organisasjonens administrator godtar din s\u00f8knad. confirmEmailFailure=E-postadressen din ble ikke bekreftet. Vennligst kontakt systemadministrator. attachIdToExistingUserReceipt=Id'en ble koblet til brukeren. Du kan n\u00e5 logge inn med denne id'en. +externalResources=Eksterne kilder +externalResourceIdentifier=Identifikator for ekstern kilde +organismId=Organisme-id +parentOrganismId=Foreldreorganisme +newOrganism=Ny organisme +hierarchyCategoryId=Hierarkikategori +organismUpdated=Organismen ble oppdatert +organismRegistered=Organismen ble registrert +organismDeleted=Organismen ble slettet +organismNotDeleted=Organismen ble ikke slettet diff --git a/src/main/webapp/formdefinitions/organismForm.json b/src/main/webapp/formdefinitions/organismForm.json index 0d708cd1c31362eba57fd8aa4f3baa53267cd557..39f994459a2b8b1e3c0e4d52f2bfa823af12a5fd 100644 --- a/src/main/webapp/formdefinitions/organismForm.json +++ b/src/main/webapp/formdefinitions/organismForm.json @@ -9,7 +9,16 @@ { "name" : "parentOrganismId", "dataType" : "INTEGER", - "required" : false + "fieldType" : "SELECT_SINGLE", + "required" : false, + "nullValue" : "-1" + }, + { + "name" : "hierarchyCategoryId", + "dataType" : "INTEGER", + "fieldType" : "SELECT_SINGLE", + "required" : true, + "nullValue" : "-1" }, { "name" : "latinName", @@ -25,6 +34,12 @@ "name" : "localName", "dataType" : "STRING", "required" : false + }, + { + "name" : "externalResourceIdentifier", + "dataType" : "STRING", + "fieldType" : "MULTIPLE_MAP", + "required" : false } ] diff --git a/src/main/webapp/templates/organism.ftl b/src/main/webapp/templates/organism.ftl new file mode 100644 index 0000000000000000000000000000000000000000..b794e11a7be92ef5bd042afd5484c6941e74b46d --- /dev/null +++ b/src/main/webapp/templates/organism.ftl @@ -0,0 +1,62 @@ +<#include "master.ftl"> +<#macro page_head> + <title>${i18nBundle.organisms}</title> + +</#macro> +<#macro custom_css> + <link href="/css/selectize.bootstrap3.css" rel="stylesheet" media="screen" /> +</#macro> +<#macro custom_js> +<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script> +<script src="/js/selectize.min.js"></script> +<script type="text/javascript"> +$(document).ready(function() { + $('#organismSearch').selectize({ + diacritics: true, // Support for international characters + maxItems: 1, + valueField: 'organismId', + labelField: 'organismName', + preload: true, + onType: function(value){ + // Filter options on typed value + console.log("Type value:" + value); + }, + load: function(query, callback) { + // Load all options + // If options is empty, load all + //if (!query.length) return callback(); + + $.ajax({ + url: '/rest/organism/list' + encodeURIComponent(query), + type: 'GET', + error: function() { + callback(); + }, + success: function(res) { + callback(res.repositories.slice(0, 10)); + } + }); + + console.log("Load query: " + query); + } + // Render: add breadcrumb to search result + }); +}); +</script> +</#macro> + +<#macro page_contents> + <h1>${i18nBundle.organisms}</h1> + <div class="row"> + <div class="col-md-6"> + <select id="organismSearch"> + + </select> + Søkefelt og organismetre + </div> + <div class="col-md-6"> + Skjema for redigering av organisme + </div> + </div> +</#macro> +<@page_html/> diff --git a/src/main/webapp/templates/organismDetails.ftl b/src/main/webapp/templates/organismDetails.ftl new file mode 100644 index 0000000000000000000000000000000000000000..e9416f39b5937dda3e771dfcb9c94a2c5fbe5519 --- /dev/null +++ b/src/main/webapp/templates/organismDetails.ftl @@ -0,0 +1,42 @@ +<#include "master.ftl"> +<#macro page_head> + <title>${organism.getLocalName(currentLocale.language)!""}<#if organism.tradeName?has_content> / ${organism.tradeName}</#if> (${organism.latinName!""})</title> +</#macro> + +<#macro page_contents> + <h1>${organism.getLocalName(currentLocale.language)!""}/${organism.tradeName!""}/${organism.latinName!""}</h1> + <dl class="dl-horizontal"> + + <#if parentOrganism?has_content> + <dt>${i18nBundle.parentOrganismId}</dt> + <dd><a href="/organism?action=viewOrganism&organismId=${parentOrganism.organismId}">${parentOrganism.getLocalName(currentLocale.language)!""}/${parentOrganism.tradeName!""}/${parentOrganism.latinName!""}</a></dd> + </#if> + + + <dt>${i18nBundle.latinName}</dt> + <dd>${organism.latinName!""}</dd> + + <dt>${i18nBundle.tradeName}</dt> + <dd>${organism.tradeName!""}</dd> + + <dt>${i18nBundle.localName} (${currentLocale.getDisplayLanguage(currentLocale)})</dt> + <dd>${organism.getLocalName(currentLocale.language)!""}</dd> + + <dt>${i18nBundle.hierarchyCategoryId}</dt> + <dd>${hierarchyCategories.getName(organism.hierarchyCategoryId)}</dd> + + <dt>${i18nBundle.externalResources}</dt> + <dd> + <#list organism.organismExternalResourceSet as organismExternalResource> + <a href="${organismExternalResource.resourceUrl}" target="new">${organismExternalResource.externalResource.name}</a><br/> + </#list> + </dd> + + </dl> + <#if user.isSuperUser()> + <a href="/organism?action=editOrganismForm&organismId=${organism.organismId}" class="btn btn-default" role="button">${i18nBundle.edit}</a> + </#if> + <a href="/organism?action=listChildOrganisms&organismId=${organism.parentOrganismId!"null"}" class="btn btn-default" role="button">${i18nBundle.back}</a> + +</#macro> +<@page_html/> diff --git a/src/main/webapp/templates/organismForm.ftl b/src/main/webapp/templates/organismForm.ftl new file mode 100644 index 0000000000000000000000000000000000000000..478ef66d142a72586cef609b2fd4830b485dc414 --- /dev/null +++ b/src/main/webapp/templates/organismForm.ftl @@ -0,0 +1,115 @@ +<#-- + Copyright (c) 2014 Bioforsk <http://www.bioforsk.no/>. + + This file is part of VIPSLogic. + VIPSLogic 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. + + 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 + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + +--><#include "master.ftl"> +<#macro page_head> + <#if organism.organismId?has_content> + <title>${i18nBundle.edit} - ${organism.latinName!organism.tradeName}</title> + <#else> + <title>${i18nBundle.newOrganism}</title> + </#if> +</#macro> +<#macro custom_js> + <script src="/js/resourcebundle.js"></script> + <script src="/js/validateForm.js"></script> + <script type="text/javascript"> + // Load main form definition (for validation) + loadFormDefinition("organismForm"); + </script> + +</#macro> +<#macro page_contents> + <#if organism.organismId?has_content> + <h1>${i18nBundle.edit} - ${organism.latinName!organism.tradeName}</h1> + <#else> + <h1>${i18nBundle.newOrganism}</h1> + </#if> + <#if messageKey?has_content> + <div class="alert alert-success">${i18nBundle(messageKey)}</div> + </#if> + <div id="errorMsgEl" class="alert alert-danger" <#if !formValidation?has_content> style="display:none;"</#if>> + <#if formValidation?has_content>${formValidation.validationMessages?replace("\n", "<br>")}</#if> + </div> + <#assign formId = "organismForm"> + <form id="${formId}" role="form" action="/organism?action=organismFormSubmit" method="POST" onsubmit="return true;" onsubmit2="try{ return validateForm(this);}catch(err){alert(err);return false;}"> + <input type="hidden" name="organismId" value="${organism.organismId!"-1"}"/> + <div class="form-group"> + <label for="parentOrganismId">${i18nBundle.parentOrganismId}</label> + <select class="form-control" name="parentOrganismId" onblur="validateField(this);"> + <option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.parentOrganismId?lower_case}</option> + <#list allOrganisms?sort_by("latinName") as parentOrganism> + <option value="${parentOrganism.organismId}" + <#if (organism.parentOrganismId?has_content && organism.parentOrganismId == parentOrganism.organismId) + || (parentOrganismId?has_content && parentOrganismId == parentOrganism.organismId) + > + selected="selected" + </#if> + >${parentOrganism.latinName!""}/${parentOrganism.tradeName!""}/${parentOrganism.getLocalName(currentLocale.language)!""} (${hierarchyCategories.getName(parentOrganism.hierarchyCategoryId)})</option> + </#list> + </select> + </div> + <div class="form-group"> + <label for="latinName">${i18nBundle.latinName}</label> + <input type="text" class="form-control" name="latinName" placeholder="${i18nBundle.latinName}" value="${organism.latinName!""}" onblur="validateField(this);" /> + <span class="help-block" id="${formId}_latinName_validation"></span> + </div> + <div class="form-group"> + <label for="tradeName">${i18nBundle.tradeName}</label> + <input type="text" class="form-control" name="tradeName" placeholder="${i18nBundle.tradeName}" value="${organism.tradeName!""}" onblur="validateField(this);" /> + <span class="help-block" id="${formId}_tradeName_validation"></span> + </div> + <div class="form-group"> + <label for="Name">${i18nBundle.localName} (${currentLocale.getDisplayLanguage(currentLocale)})</label> + <input type="text" class="form-control" name="localName" placeholder="${i18nBundle.localName}" value="<#if organism.organismId?has_content>${organism.getLocalName(currentLocale.language)!""}</#if>" onblur="validateField(this);" /> + <span class="help-block" id="${formId}_localName_validation"></span> + </div> + <div class="form-group"> + <label for="hierarchyCategoryId">${i18nBundle.hierarchyCategoryId}</label> + <select class="form-control" name="hierarchyCategoryId" onblur="validateField(this);"> + <option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.hierarchyCategoryId?lower_case}</option> + <#list hierarchyCategories.hierarchyCategoryIds as hierarchyCategoryId> + <option value="${hierarchyCategoryId}" + <#if (organism.hierarchyCategoryId?has_content && organism.hierarchyCategoryId == hierarchyCategoryId)> + selected="selected" + </#if> + >${hierarchyCategories.getName(hierarchyCategoryId)}</option> + </#list> + </select> + </div> + <fieldset> + <h3>${i18nBundle.externalResources}</h3> + <#if organism.organismExternalResourceSet?has_content> + <#list organism.organismExternalResourceSet as organismExternalResource> + <div class="form-group"> + <label for="externalResourceIdentifier_${organismExternalResource.externalResource.externalResourceId}">${i18nBundle.externalResourceIdentifier} - ${organismExternalResource.externalResource.name} (${organismExternalResource.externalResource.uri}${organismExternalResource.externalResource.identifierTemplate})</label> + <input type="text" class="form-control" name="externalResourceIdentifier_${organismExternalResource.externalResource.externalResourceId}" placeholder="${i18nBundle.externalResourceIdentifier}" value="${organismExternalResource.resourceIdentifier}" /> + </div> + </#list> + </#if> + <#list unreferencedExternalResources as externalResource> + <div class="form-group"> + <label for="externalResourceIdentifier_${externalResource.externalResourceId}">${i18nBundle.externalResourceIdentifier} - ${externalResource.name} (${externalResource.uri}${externalResource.identifierTemplate})</label> + <input type="text" class="form-control" name="externalResourceIdentifier_${externalResource.externalResourceId}" placeholder="${i18nBundle.externalResourceIdentifier}" value="" /> + </div> + </#list> + + </fieldset> + <button type="submit" class="btn btn-default">${i18nBundle.submit}</button> + <a href="/organism?action=listChildOrganisms&organismId=${organism.parentOrganismId!"null"}" class="btn btn-default" role="button">${i18nBundle.cancel}</a> + </form> +</#macro> +<@page_html/> diff --git a/src/main/webapp/templates/organismList.ftl b/src/main/webapp/templates/organismList.ftl new file mode 100644 index 0000000000000000000000000000000000000000..4dde4687083c0a7dd29d7ffcab0eafcdfb8ebcc0 --- /dev/null +++ b/src/main/webapp/templates/organismList.ftl @@ -0,0 +1,70 @@ +<#-- + Copyright (c) 2014 Bioforsk <http://www.bioforsk.no/>. + + This file is part of VIPSLogic. + VIPSLogic 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. + + 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 + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with VIPSLogic. If not, see <http://www.gnu.org/licenses/>. + +--><#include "master.ftl"> +<#macro page_head> + <title>${i18nBundle.organisms}<#if organism.organismId?has_content> - ${organism.localName!""}<#if organism.tradeName?has_content> / ${organism.tradeName}</#if> (${organism.latinName!""})</#if></title> +</#macro> +<#macro page_contents> + <h1>${i18nBundle.organisms}</h1> + <#if organism.organismId?has_content> + <h2>${organism.getLocalName(currentLocale.language)!""}<#if organism.tradeName?has_content> / ${organism.tradeName}</#if> (<i>${organism.latinName!""}</i>)</h2> + </#if> + <#if messageKey?has_content> + <div class="alert alert-success">${i18nBundle(messageKey)}</div> + </#if> + <#if user.isSuperUser()> + <a href="/organism?action=newOrganismForm&parentOrganismId=${organism.organismId!""}" class="btn btn-default" role="button">${i18nBundle.addNew}</a> + </#if> + <#if organism.organismId?has_content> + <a href="/organism?action=listChildOrganisms&organismId=${organism.parentOrganismId!""}" class="btn btn-default" role="button">${i18nBundle.up}</a> + </#if> + <div class="table-responsive"> + <table class="table table-striped"> + <thead> + <th>${i18nBundle.latinName}</th> + <th>${i18nBundle.localName}</th> + <#if tradeNamePresent> + <th>${i18nBundle.tradeName}</th> + </#if> + <th></th> + </thead> + <tbody> + <#list organism.childOrganisms as childOrganism> + <tr> + <td>${childOrganism.latinName!""}</td> + <td>${childOrganism.getLocalName(currentLocale.language)}</td> + <#if tradeNamePresent> + <td>${childOrganism.tradeName!""}</td> + </#if> + <td> + <#if user.isSuperUser()> + <a href="/organism?action=editOrganismForm&organismId=${childOrganism.organismId}&parentOrganismId=${organism.organismId!""}" class="btn btn-default" role="button">${i18nBundle.edit}</a> + <#if ! childOrganism.childOrganisms?has_content || childOrganism.childOrganisms?size == 0> + <button type="button" class="btn btn-danger" onclick="if(confirm('${childOrganism.getLocalName(currentLocale.language)!""}/${childOrganism.tradeName!""}/${childOrganism.latinName!""}: ${i18nBundle.confirmDelete}')) {window.location.href='/organism?action=deleteOrganism&organismId=${childOrganism.organismId}';}">${i18nBundle.delete}</button> + </#if> + </#if> + <a href="/organism?action=viewOrganism&organismId=${childOrganism.organismId}" class="btn btn-default" role="button">${i18nBundle.details}</a> + <a href="/organism?action=listChildOrganisms&organismId=${childOrganism.organismId}" class="btn btn-default" role="button">${i18nBundle.children}</a> + </td> + </tr> + </#list> + </tbody> + </table> + </div> +</#macro> +<@page_html/> diff --git a/src/main/webapp/templates/userForm.ftl b/src/main/webapp/templates/userForm.ftl index 70a8d193c5fb8a01b234f1922e9f5c022b72d100..af9cb601af1f7e0fc0f8f199020a46fa3c191946 100644 --- a/src/main/webapp/templates/userForm.ftl +++ b/src/main/webapp/templates/userForm.ftl @@ -5,6 +5,10 @@ <#macro custom_js> <script src="/js/resourcebundle.js"></script> <script src="/js/validateForm.js"></script> + <script type="text/javascript"> + // Load main form definition (for validation) + loadFormDefinition("userForm"); + </script> </#macro> <#macro page_contents> <h1>${viewUser.firstName} ${viewUser.lastName}</h1> diff --git a/src/test/java/no/bioforsk/vips/logic/session/UserBeanTest.java b/src/test/java/no/bioforsk/vips/logic/session/UserBeanTest.java index d2855d071b1a1ee5628b4fee64e16276c5aa0144..3ad7e84a6a95bbce0a47bc42e63ff81ec5d81eda 100644 --- a/src/test/java/no/bioforsk/vips/logic/session/UserBeanTest.java +++ b/src/test/java/no/bioforsk/vips/logic/session/UserBeanTest.java @@ -69,7 +69,7 @@ public class UserBeanTest { ResourceBundle i18nBundle = ResourceBundle.getBundle("no.bioforsk.vips.logic.i18n.vipslogictexts",new Locale("no")); UserBean uBean = new UserBean(); String result = uBean.getUserEmailVerificationBody(i18nBundle, "logic.vips.bioforsk.no",StringUtils.generateRandomAlphanumericString(30)); - System.out.println(result); + //System.out.println(result); assert(true); }