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

Projects

parent 7518f111
......@@ -45,7 +45,7 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode
protected UUID uuid;
@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;
@Column(name = "title", nullable = false)
......@@ -54,6 +54,9 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode
@Column(name = "description", nullable = true)
private String description;
@Column
private boolean shared;
public UUID getUuid() {
return uuid;
}
......@@ -96,4 +99,16 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode
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;
import org.genesys2.server.model.AclAwareModel;
......@@ -11,16 +27,20 @@ import java.util.UUID;
@Table(name = "project")
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;
@Column(length=200, nullable=true)
@Column(length = 200, nullable = true)
private String url;
@Column(length=50, nullable=false, unique=true)
@Column(length = 50, nullable = false, unique = true)
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;
public String getName() {
......
......@@ -36,6 +36,9 @@ public interface AccessionListRepository extends JpaRepository<AccessionList, Lo
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)")
@Modifying
void addOne(AccessionList list, AccessionId accession);
......@@ -47,4 +50,5 @@ public interface AccessionListRepository extends JpaRepository<AccessionList, Lo
@Query(nativeQuery=true, value="select count(acceid) from accelistitems where listid = ?1")
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.springframework.data.jpa.repository.JpaRepository;
......
......@@ -40,6 +40,7 @@ public interface AccessionListService {
Set<Long> getAccessionIds(AccessionList loaded);
AccessionList getList(UUID uuid);
List<AccessionList> getLists(List<UUID> uuid);
void removeAll(AccessionList accessionList);
......@@ -50,4 +51,5 @@ public interface AccessionListService {
void addToList(AccessionList loaded, AppliedFilters filters);
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;
import org.genesys2.server.model.impl.Project;
......
......@@ -21,6 +21,7 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.collections.ListUtils;
import org.apache.log4j.Logger;
import org.genesys2.server.model.genesys.AccessionData;
import org.genesys2.server.model.impl.AccessionList;
......@@ -34,6 +35,7 @@ import org.genesys2.server.service.impl.FilterHandler.LiteralValueFilter;
import org.genesys2.spring.SecurityContextUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
......@@ -53,11 +55,18 @@ public class AccessionListServiceImpl implements AccessionListService {
}
@Override
@PostAuthorize("hasRole('ADMINISTRATOR') or hasPermission(returnObject, 'READ')")
@PostAuthorize("hasRole('ADMINISTRATOR') or hasPermission(returnObject, 'READ') or returnObject.shared == true")
public AccessionList getList(UUID 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
@PreAuthorize("isAuthenticated() and (#accessionList.id==null or hasRole('ADMINISTRATOR') or hasPermission(#accessionList, 'WRITE'))")
@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;
import org.genesys2.server.model.impl.Project;
......@@ -15,8 +31,8 @@ import java.util.List;
import java.util.Locale;
@Service
@Transactional
public class ProjectServiceImpl implements ProjectService{
@Transactional(readOnly = true)
public class ProjectServiceImpl implements ProjectService {
@Autowired
ProjectRepository projectRepository;
......@@ -36,7 +52,9 @@ public class ProjectServiceImpl implements ProjectService{
@Override
public Project getProjectByCode(String code) {
return projectRepository.findByCode(code);
Project project = projectRepository.findByCode(code);
project.getAccessionLists().size();
return project;
}
@Override
......@@ -50,18 +68,22 @@ public class ProjectServiceImpl implements ProjectService{
}
@Override
@PreAuthorize("#project.id==null or hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#project, 'ADMINISTRATION')")
@Transactional
public void saveProject(Project project) {
projectRepository.save(project);
}
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#project, 'ADMINISTRATION')")
@Transactional
public void deleteProject(Project project) {
projectRepository.delete(project);
}
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#crop, 'ADMINISTRATION')")
@Transactional(readOnly = false)
@PreAuthorize("hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasPermission(#project, 'ADMINISTRATION')")
@Transactional
public void updateBlurp(Project project, String textBody, String summary, Locale 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;
import java.util.Locale;
import org.genesys2.server.model.impl.Project;
import org.genesys2.server.service.AccessionListService;
import org.genesys2.server.service.ContentService;
import org.genesys2.server.service.ProjectService;
import org.genesys2.spring.ResourceNotFoundException;
......@@ -11,29 +30,31 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Locale;
@Controller
@RequestMapping("/project")
public class ProjectController extends BaseController{
public class ProjectController extends BaseController {
@Autowired
private ProjectService projectService;
@Autowired
private AccessionListService accessionListService;
@Autowired
ContentService contentService;
@RequestMapping({"/", ""})
public String projects(){
@RequestMapping({ "/", "" })
public String projects() {
return "redirect:/project/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")));
......@@ -43,32 +64,53 @@ public class ProjectController extends BaseController{
}
@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);
modelMap.addAttribute("blurp", contentService.getArticle(project, "blurp", getLocale()));
if (project != null) {
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";
}
@RequestMapping("/edit/{code}")
public String editProject(ModelMap modelMap, @PathVariable(value = "code") String code){
@RequestMapping("/add-project")
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);
return "/project/edit";
}
@RequestMapping("/{code}/update")
public String update(ModelMap modelMap, @PathVariable(value = "code")String code, @RequestParam("blurp") String aboutBody,
@RequestParam(value = "summary", required = false) String summary){
@RequestMapping("/update-project")
public String update(ModelMap modelMap, @ModelAttribute("project") Project p, @RequestParam("blurp") String aboutBody,
@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) {
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());
return "redirect:/project/" + code;
return "redirect:/project/" + p.getCode();
}
protected Locale getLocale() {
......
......@@ -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).
select-country=Select country
project.page.list.title=WIEWS Projects
project.page.profile.title=WIEWS {0}
project.page.list.title=Projects
project.page.profile.title={0}
project.code=Project Code
project.name=Project Name
project.url=Project website
project.summary=Summary (HTML metadata)
project.accessionLists=Accession Lists
faoInstitutes.page.list.title=WIEWS Institutes
faoInstitutes.page.profile.title=WIEWS {0}
......@@ -737,3 +742,4 @@ region.page.show.world = Show all world regions
region.countries-in-region=List of countries in {0}
region.regions-in-region=FAO Regions in {0}
region.show-all-regions=List all FAO regions
......@@ -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="/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="/project" />"><spring:message code="project.page.list.title" /></a></li>
</security:authorize>
<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>
......
<!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>
<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>
<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}" />
<div class="form-group">
<label class="col-lg-3 control-label">
<spring:message code="project.code" />
</label>
<div class="controls col-lg-9">
<input type="text" name="code" class="form-control required" value="${project.code}" />
</div>
</div>
<div class="form-group">
<label for="blurp-body" class="col-lg-12 control-label"><spring:message code="blurp.blurp-body" /></label>
<label class="col-lg-3 control-label">
<spring:message code="project.name" />
</label>
<div class="controls col-lg-9">
<input type="text" name="name" class="form-control required" value="${project.name}" />
</div>
</div>
<div class="form-group">
<label class="col-lg-3 control-label">
<spring:message code="project.url" />
</label>
<div class="controls col-lg-9">
<input type="text" name="url" class="form-control required" placeholder="https://" value="${project.url}" />
</div>
</div>
<div class="form-group">
<label for="blurp-body" class="col-lg-12 control-label">
<spring:message code="blurp.blurp-body" />
</label>
<div class="controls col-lg-12">
<textarea id="blurp-body" name="blurp" class="span9 required html-editor">
<c:out value="${blurp.body}" />
......@@ -19,7 +59,9 @@
</div>
<div class="form-group">
<label for="project-summary" class="col-lg-12 control-label"><spring:message code="project.summary" /></label>
<label for="project-summary" class="col-lg-12 control-label">
<spring:message code="project.summary" />
</label>
<div class="controls col-lg-12">
<textarea id="project-summary" name="summary" class="span9 required html-editor">
<c:out value="${blurp.summary}" />
......@@ -27,18 +69,33 @@
</div>
</div>
<input type="submit" value="<spring:message code="save"/>" class="btn btn-primary" /> <a href="<c:url value="/project/${project.code}" />" class="btn btn-default"> <spring:message code="cancel" />
</a>
<!-- CSRF protection -->
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
<div class="form-group">
<label class="col-lg-3 control-label">
<spring:message code="project.accessionLists" />
</label>
<div class="controls col-lg-9">
<c:forEach items="${project.accessionLists}" var="accessionList">
<div>
<input type="text" name="accessionLists" class="form-control" value="${accessionList}" />
</div>
</c:forEach>
<div>
<input type="text" name="accessionLists" class="form-control" value="" placeholder="u-u-i-d" />
</div>
</div>
</div>
<input type="submit" value="<spring:message code="save"/>" class="btn btn-primary" />
<a href="<c:url value="/project/${project.code}" />" class="btn btn-default">
<spring:message code="cancel" />
</a>
</form>
<content tag="javascript">
<script type="text/javascript">
<content tag="javascript"> <script type="text/javascript">
<local:tinyMCE selector=".html-editor" />
</script>
</content>
</script> </content>
</body>
</html>
<!DOCTYPE html>
<%@include file="/WEB-INF/jsp/init.jsp" %>
<%@include file="/WEB-INF/jsp/init.jsp"%>
<html>
<head>
<title><spring:message code="project.page.list.title"/></title>
<title><spring:message code="project.page.list.title" /></title>
</head>
<body>
<h1>
<spring:message code="project.page.list.title"/>
</h1>
<h1>
<spring:message code="project.page.list.title" />
</h1>
<div class="main-col-header clearfix">
<div class="main-col-header clearfix">
<div class="nav-header">
<local:paginate page="${pagedData}"/>
<local:paginate page="${pagedData}" />
</div>
</div>
</div>
<security:authorize access="hasRole('ADMINISTRATOR') or hasRole('CONTENTMANAGER') or hasRole('VETTEDUSER')">
<a href="<c:url value="/project/add-project" />" class="close">
<spring:message code="add" />
</a>
</security:authorize>
<ul class="funny-list">
<ul class="funny-list">
<c:forEach items="${pagedData.content}" var="project" varStatus="status">
<li class="clearfix ${status.count % 2 == 0 ? 'even' : 'odd'}">
<a class="show pull-left" href="<c:url value="/project/${project.code}" />">
<b><c:out value="${project.code}"/></b>
<c:out value="${project.name}"/>
<b>
<c:out value="${project.code}" />
</b>
<c:out value="${project.name}" />
</a>
</li>
</c:forEach>
</ul>
</ul>
</body>
</html>
<!DOCTYPE html>
<%@include file="/WEB-INF/jsp/init.jsp" %>
<%@include file="/WEB-INF/jsp/init.jsp"%>
<html>
<head>
<title><c: