Commit 5efb2162 authored by Matija Obreza's avatar Matija Obreza
Browse files

Projects

parent 7518f111
...@@ -45,7 +45,7 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode ...@@ -45,7 +45,7 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode
protected UUID uuid; protected UUID uuid;
@ManyToMany(cascade = {}, fetch = FetchType.LAZY) @ManyToMany(cascade = {}, fetch = FetchType.LAZY)
@JoinTable(name = "accelistitems", joinColumns = @JoinColumn(name = "listid"), inverseJoinColumns = @JoinColumn(name="acceid")) @JoinTable(name = "accelistitems", joinColumns = @JoinColumn(name = "listid") , inverseJoinColumns = @JoinColumn(name = "acceid") )
private Set<AccessionId> accessionIds; private Set<AccessionId> accessionIds;
@Column(name = "title", nullable = false) @Column(name = "title", nullable = false)
...@@ -54,6 +54,9 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode ...@@ -54,6 +54,9 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode
@Column(name = "description", nullable = true) @Column(name = "description", nullable = true)
private String description; private String description;
@Column
private boolean shared;
public UUID getUuid() { public UUID getUuid() {
return uuid; return uuid;
} }
...@@ -96,4 +99,16 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode ...@@ -96,4 +99,16 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode
this.title = title; this.title = title;
} }
public void setShared(boolean shared) {
this.shared = shared;
}
public boolean isShared() {
return shared;
}
public boolean getShared() {
return shared;
}
} }
\ No newline at end of file
/**
* Copyright 2015 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.model.impl; package org.genesys2.server.model.impl;
import org.genesys2.server.model.AclAwareModel; import org.genesys2.server.model.AclAwareModel;
...@@ -11,16 +27,20 @@ import java.util.UUID; ...@@ -11,16 +27,20 @@ import java.util.UUID;
@Table(name = "project") @Table(name = "project")
public class Project extends VersionedAuditedModel implements AclAwareModel { public class Project extends VersionedAuditedModel implements AclAwareModel {
@Column(length=200, nullable=false) private static final long serialVersionUID = -2262512202111475334L;
@Column(length = 200, nullable = false)
private String name; private String name;
@Column(length=200, nullable=true) @Column(length = 200, nullable = true)
private String url; private String url;
@Column(length=50, nullable=false, unique=true) @Column(length = 50, nullable = false, unique = true)
private String code; private String code;
@OneToMany(fetch = FetchType.LAZY, targetEntity = AccessionList.class) @Column(name = "uuid", nullable = false)
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "project_accelist", joinColumns = @JoinColumn(name = "projectId", referencedColumnName = "id"))
private List<UUID> accessionLists; private List<UUID> accessionLists;
public String getName() { public String getName() {
......
...@@ -36,6 +36,9 @@ public interface AccessionListRepository extends JpaRepository<AccessionList, Lo ...@@ -36,6 +36,9 @@ public interface AccessionListRepository extends JpaRepository<AccessionList, Lo
AccessionList findByUuid(UUID uuid); AccessionList findByUuid(UUID uuid);
@Query("from AccessionList al where al.uuid in (?1)")
List<AccessionList> findByUuids(List<UUID> uuid);
@Query(nativeQuery = true, value = "insert into accelistitems (listid, acceid) values (?1, ?2)") @Query(nativeQuery = true, value = "insert into accelistitems (listid, acceid) values (?1, ?2)")
@Modifying @Modifying
void addOne(AccessionList list, AccessionId accession); void addOne(AccessionList list, AccessionId accession);
...@@ -47,4 +50,5 @@ public interface AccessionListRepository extends JpaRepository<AccessionList, Lo ...@@ -47,4 +50,5 @@ public interface AccessionListRepository extends JpaRepository<AccessionList, Lo
@Query(nativeQuery=true, value="select count(acceid) from accelistitems where listid = ?1") @Query(nativeQuery=true, value="select count(acceid) from accelistitems where listid = ?1")
int sizeOf(AccessionList list); int sizeOf(AccessionList list);
} }
package org.genesys2.server.persistence.domain; /**
* Copyright 2015 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.persistence.domain;
import org.genesys2.server.model.impl.Project; import org.genesys2.server.model.impl.Project;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
......
...@@ -40,6 +40,7 @@ public interface AccessionListService { ...@@ -40,6 +40,7 @@ public interface AccessionListService {
Set<Long> getAccessionIds(AccessionList loaded); Set<Long> getAccessionIds(AccessionList loaded);
AccessionList getList(UUID uuid); AccessionList getList(UUID uuid);
List<AccessionList> getLists(List<UUID> uuid);
void removeAll(AccessionList accessionList); void removeAll(AccessionList accessionList);
...@@ -50,4 +51,5 @@ public interface AccessionListService { ...@@ -50,4 +51,5 @@ public interface AccessionListService {
void addToList(AccessionList loaded, AppliedFilters filters); void addToList(AccessionList loaded, AppliedFilters filters);
int sizeOf(AccessionList loaded); int sizeOf(AccessionList loaded);
} }
\ No newline at end of file
/**
* Copyright 2015 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.service; package org.genesys2.server.service;
import org.genesys2.server.model.impl.Project; import org.genesys2.server.model.impl.Project;
......
...@@ -21,6 +21,7 @@ import java.util.List; ...@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import org.apache.commons.collections.ListUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.genesys2.server.model.genesys.AccessionData; import org.genesys2.server.model.genesys.AccessionData;
import org.genesys2.server.model.impl.AccessionList; import org.genesys2.server.model.impl.AccessionList;
...@@ -34,6 +35,7 @@ import org.genesys2.server.service.impl.FilterHandler.LiteralValueFilter; ...@@ -34,6 +35,7 @@ import org.genesys2.server.service.impl.FilterHandler.LiteralValueFilter;
import org.genesys2.spring.SecurityContextUtil; import org.genesys2.spring.SecurityContextUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostAuthorize; import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
...@@ -53,11 +55,18 @@ public class AccessionListServiceImpl implements AccessionListService { ...@@ -53,11 +55,18 @@ public class AccessionListServiceImpl implements AccessionListService {
} }
@Override @Override
@PostAuthorize("hasRole('ADMINISTRATOR') or hasPermission(returnObject, 'READ')") @PostAuthorize("hasRole('ADMINISTRATOR') or hasPermission(returnObject, 'READ') or returnObject.shared == true")
public AccessionList getList(UUID uuid) { public AccessionList getList(UUID uuid) {
return accessionListRepository.findByUuid(uuid); return accessionListRepository.findByUuid(uuid);
} }
@SuppressWarnings("unchecked")
@Override
@PostFilter("hasRole('ADMINISTRATOR') or hasPermission(filterObject, 'READ') or filterObject.shared == true")
public List<AccessionList> getLists(List<UUID> uuids) {
return uuids == null || uuids.isEmpty() ? ListUtils.EMPTY_LIST : accessionListRepository.findByUuids(uuids);
}
@Override @Override
@PreAuthorize("isAuthenticated() and (#accessionList.id==null or hasRole('ADMINISTRATOR') or hasPermission(#accessionList, 'WRITE'))") @PreAuthorize("isAuthenticated() and (#accessionList.id==null or hasRole('ADMINISTRATOR') or hasPermission(#accessionList, 'WRITE'))")
@Transactional @Transactional
......
/**
* Copyright 2015 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.service.impl; package org.genesys2.server.service.impl;
import org.genesys2.server.model.impl.Project; import org.genesys2.server.model.impl.Project;
...@@ -15,8 +31,8 @@ import java.util.List; ...@@ -15,8 +31,8 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
@Service @Service
@Transactional @Transactional(readOnly = true)
public class ProjectServiceImpl implements ProjectService{ public class ProjectServiceImpl implements ProjectService {
@Autowired @Autowired
ProjectRepository projectRepository; ProjectRepository projectRepository;
...@@ -36,7 +52,9 @@ public class ProjectServiceImpl implements ProjectService{ ...@@ -36,7 +52,9 @@ public class ProjectServiceImpl implements ProjectService{
@Override @Override
public Project getProjectByCode(String code) { public Project getProjectByCode(String code) {
return projectRepository.findByCode(code); Project project = projectRepository.findByCode(code);
project.getAccessionLists().size();
return project;
} }
@Override @Override
...@@ -50,18 +68,22 @@ public class ProjectServiceImpl implements ProjectService{ ...@@ -50,18 +68,22 @@ public class ProjectServiceImpl implements ProjectService{
} }
@Override @Override
@PreAuthorize("#project.id==null or hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#project, 'ADMINISTRATION')")
@Transactional
public void saveProject(Project project) { public void saveProject(Project project) {
projectRepository.save(project); projectRepository.save(project);
} }
@Override @Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#project, 'ADMINISTRATION')")
@Transactional
public void deleteProject(Project project) { public void deleteProject(Project project) {
projectRepository.delete(project); projectRepository.delete(project);
} }
@Override @Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#crop, 'ADMINISTRATION')") @PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#project, 'ADMINISTRATION')")
@Transactional(readOnly = false) @Transactional
public void updateBlurp(Project project, String textBody, String summary, Locale locale) { public void updateBlurp(Project project, String textBody, String summary, Locale locale) {
contentService.updateArticle(project, "blurp", null, textBody, summary, locale); contentService.updateArticle(project, "blurp", null, textBody, summary, locale);
} }
......
/**
* Copyright 2015 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.servlet.controller; package org.genesys2.server.servlet.controller;
import java.util.Locale;
import org.genesys2.server.model.impl.Project; import org.genesys2.server.model.impl.Project;
import org.genesys2.server.service.AccessionListService;
import org.genesys2.server.service.ContentService; import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.ProjectService; import org.genesys2.server.service.ProjectService;
import org.genesys2.spring.ResourceNotFoundException; import org.genesys2.spring.ResourceNotFoundException;
...@@ -11,29 +30,31 @@ import org.springframework.data.domain.PageRequest; ...@@ -11,29 +30,31 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import java.util.Locale;
@Controller @Controller
@RequestMapping("/project") @RequestMapping("/project")
public class ProjectController extends BaseController{ public class ProjectController extends BaseController {
@Autowired @Autowired
private ProjectService projectService; private ProjectService projectService;
@Autowired
private AccessionListService accessionListService;
@Autowired @Autowired
ContentService contentService; ContentService contentService;
@RequestMapping({"/", ""}) @RequestMapping({ "/", "" })
public String projects(){ public String projects() {
return "redirect:/project/list"; return "redirect:/project/list";
} }
@RequestMapping("/list") @RequestMapping("/list")
public String listProjects(ModelMap modelMap, @RequestParam(value = "page", required = false, defaultValue = "1") int page){ public String listProjects(ModelMap modelMap, @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
Page<Project> projects = projectService.list(new PageRequest(page - 1, 20, new Sort("name"))); Page<Project> projects = projectService.list(new PageRequest(page - 1, 20, new Sort("name")));
...@@ -43,32 +64,53 @@ public class ProjectController extends BaseController{ ...@@ -43,32 +64,53 @@ public class ProjectController extends BaseController{
} }
@RequestMapping("/{code}") @RequestMapping("/{code}")
public String viewProject(ModelMap modelMap, @PathVariable(value = "code")String code){ public String viewProject(ModelMap modelMap, @PathVariable(value = "code") String code) {
Project project = projectService.getProjectByCode(code); Project project = projectService.getProjectByCode(code);
modelMap.addAttribute("blurp", contentService.getArticle(project, "blurp", getLocale())); if (project != null) {
modelMap.addAttribute("project", project); modelMap.addAttribute("project", project);
modelMap.addAttribute("accessionLists", accessionListService.getLists(project.getAccessionLists()));
modelMap.addAttribute("blurp", contentService.getArticle(project, "blurp", getLocale()));
} else {
throw new ResourceNotFoundException("No project with code " + code);
}
return "/project/view"; return "/project/view";
} }
@RequestMapping("/edit/{code}") @RequestMapping("/add-project")
public String editProject(ModelMap modelMap, @PathVariable(value = "code") String code){ public String addProject(ModelMap modelMap) {
modelMap.addAttribute("project", new Project());
return "/project/edit";
}
@RequestMapping("/{code}/edit")
public String editProject(ModelMap modelMap, @PathVariable(value = "code") String code) {
viewProject(modelMap, code); viewProject(modelMap, code);
return "/project/edit"; return "/project/edit";
} }
@RequestMapping("/{code}/update") @RequestMapping("/update-project")
public String update(ModelMap modelMap, @PathVariable(value = "code")String code, @RequestParam("blurp") String aboutBody, public String update(ModelMap modelMap, @ModelAttribute("project") Project p, @RequestParam("blurp") String aboutBody,
@RequestParam(value = "summary", required = false) String summary){ @RequestParam(value = "summary", required = false) String summary) {
_logger.debug("Updating project " + p.getCode());
Project project = null;
if (p.getId() != null)
project = projectService.getProjectById(p.getId());
_logger.debug("Updating project " + code);
final Project project = projectService.getProjectByCode(code);
if (project == null) { if (project == null) {
throw new ResourceNotFoundException(); project = new Project();
} }
project.setCode(p.getCode());
project.setUrl(p.getUrl());
project.setName(p.getName());
project.setAccessionLists(p.getAccessionLists());
projectService.saveProject(project);
projectService.updateBlurp(project, aboutBody, summary, getLocale()); projectService.updateBlurp(project, aboutBody, summary, getLocale());
return "redirect:/project/" + code; return "redirect:/project/" + p.getCode();
} }
protected Locale getLocale() { protected Locale getLocale() {
......
...@@ -156,9 +156,14 @@ country.replaced-by=Country code is replaced by: {0} ...@@ -156,9 +156,14 @@ country.replaced-by=Country code is replaced by: {0}
country.is-itpgrfa-contractingParty={0} is party to the International Treaty on Plant Genetic Resources for Food and Agriculture (ITPGRFA). country.is-itpgrfa-contractingParty={0} is party to the International Treaty on Plant Genetic Resources for Food and Agriculture (ITPGRFA).
select-country=Select country select-country=Select country
project.page.list.title=WIEWS Projects project.page.list.title=Projects
project.page.profile.title=WIEWS {0} project.page.profile.title={0}
project.code=Project Code
project.name=Project Name
project.url=Project website
project.summary=Summary (HTML metadata) project.summary=Summary (HTML metadata)
project.accessionLists=Accession Lists
faoInstitutes.page.list.title=WIEWS Institutes faoInstitutes.page.list.title=WIEWS Institutes
faoInstitutes.page.profile.title=WIEWS {0} faoInstitutes.page.profile.title=WIEWS {0}
...@@ -737,3 +742,4 @@ region.page.show.world = Show all world regions ...@@ -737,3 +742,4 @@ region.page.show.world = Show all world regions
region.countries-in-region=List of countries in {0} region.countries-in-region=List of countries in {0}
region.regions-in-region=FAO Regions in {0} region.regions-in-region=FAO Regions in {0}
region.show-all-regions=List all FAO regions region.show-all-regions=List all FAO regions
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
<li><a href="<c:url value="/team" />"><spring:message code="user.pulldown.teams" /></a></li> <li><a href="<c:url value="/team" />"><spring:message code="user.pulldown.teams" /></a></li>
<li><a href="<c:url value="/management/" />"><spring:message code="user.pulldown.oauth-clients" /></a></li> <li><a href="<c:url value="/management/" />"><spring:message code="user.pulldown.oauth-clients" /></a></li>
<li><a href="<c:url value="/content" />"><spring:message code="user.pulldown.manage-content" /></a></li> <li><a href="<c:url value="/content" />"><spring:message code="user.pulldown.manage-content" /></a></li>
<li><a href="<c:url value="/project" />"><spring:message code="project.page.list.title" /></a></li>
</security:authorize> </security:authorize>
<li><a href="<c:url value="/profile/${user.username}" />"><spring:message code="user.pulldown.profile"/></a></li> <li><a href="<c:url value="/profile/${user.username}" />"><spring:message code="user.pulldown.profile"/></a></li>
<li><a id="logout1" href="#" onclick="document.getElementById('logoutForm').submit();" ><spring:message code="user.pulldown.logout"/></a> <li><a id="logout1" href="#" onclick="document.getElementById('logoutForm').submit();" ><spring:message code="user.pulldown.logout"/></a>
......
<!DOCTYPE html> <!DOCTYPE html>
<%@include file="/WEB-INF/jsp/init.jsp" %> <%@include file="/WEB-INF/jsp/init.jsp"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
<html> <html>
<head> <head>
<title><spring:message code="project.page.profile.title" arguments="${project.name}" argumentSeparator="|" /></title> <title><spring:message code="project.page.profile.title" arguments="${project.name}" argumentSeparator="|" /></title>
</head> </head>
<body> <body>
<h1>
${project.name}
<small>
<c:out value="${project.code}" />
</small>
</h1>
<form role="form" class="form-horizontal" action="<c:url value="/project/${project.code}/update" />" method="post"> <form role="form" class="form-horizontal" action="<c:url value="/project/update-project" />" method="post">
<input type="hidden" name="id" value="${project.id}" />
<input type="hidden" name="version" value="${project.version}" />
<!-- CSRF protection -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />