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);
}