diff --git a/src/main/java/org/genesys2/server/model/impl/AccessionList.java b/src/main/java/org/genesys2/server/model/impl/AccessionList.java index 442f5a5487520fddde32f433f7ae1ba8f3144b05..cbf3902769142ac6b3309dc4eba79e11da7556f7 100644 --- a/src/main/java/org/genesys2/server/model/impl/AccessionList.java +++ b/src/main/java/org/genesys2/server/model/impl/AccessionList.java @@ -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 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; } @@ -95,5 +98,17 @@ public class AccessionList extends VersionedAuditedModel implements AclAwareMode public void setTitle(String 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 diff --git a/src/main/java/org/genesys2/server/model/impl/Project.java b/src/main/java/org/genesys2/server/model/impl/Project.java index bf0a2f90dc8518d2b42fd4b729cbb58930305bf6..d1738007d2ff4dd3e7df2500528ca3ac0e3137d4 100644 --- a/src/main/java/org/genesys2/server/model/impl/Project.java +++ b/src/main/java/org/genesys2/server/model/impl/Project.java @@ -1,3 +1,19 @@ +/** + * 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,47 +27,51 @@ import java.util.UUID; @Table(name = "project") public class Project extends VersionedAuditedModel implements AclAwareModel { - @Column(length=200, nullable=false) - private String name; + private static final long serialVersionUID = -2262512202111475334L; + + @Column(length = 200, nullable = false) + private String name; - @Column(length=200, nullable=true) - private String url; + @Column(length = 200, nullable = true) + private String url; - @Column(length=50, nullable=false, unique=true) - private String code; + @Column(length = 50, nullable = false, unique = true) + private String code; - @OneToMany(fetch = FetchType.LAZY, targetEntity = AccessionList.class) - private List accessionLists; + @Column(name = "uuid", nullable = false) + @ElementCollection(fetch = FetchType.LAZY) + @CollectionTable(name = "project_accelist", joinColumns = @JoinColumn(name = "projectId", referencedColumnName = "id")) + private List accessionLists; - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public String getUrl() { - return url; - } + public String getUrl() { + return url; + } - public void setUrl(String url) { - this.url = url; - } + public void setUrl(String url) { + this.url = url; + } - public String getCode() { - return code; - } + public String getCode() { + return code; + } - public void setCode(String code) { - this.code = code; - } + public void setCode(String code) { + this.code = code; + } - public List getAccessionLists() { - return accessionLists; - } + public List getAccessionLists() { + return accessionLists; + } - public void setAccessionLists(List accessionLists) { - this.accessionLists = accessionLists; - } + public void setAccessionLists(List accessionLists) { + this.accessionLists = accessionLists; + } } diff --git a/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepository.java b/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepository.java index 1c7bcc63344460b9aa97166e764611facd34dae4..c3f89859b6e69035ae22076cb0832e6db058fe39 100644 --- a/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepository.java +++ b/src/main/java/org/genesys2/server/persistence/domain/AccessionListRepository.java @@ -36,6 +36,9 @@ public interface AccessionListRepository extends JpaRepository findByUuids(List 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 getAccessionIds(AccessionList loaded); AccessionList getList(UUID uuid); + List getLists(List 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 diff --git a/src/main/java/org/genesys2/server/service/ProjectService.java b/src/main/java/org/genesys2/server/service/ProjectService.java index dcc417aa591e7b73ea479a149556f4219f76db0f..7a979e9fb1d2623bd0b278fa35f052e2c2f3d719 100644 --- a/src/main/java/org/genesys2/server/service/ProjectService.java +++ b/src/main/java/org/genesys2/server/service/ProjectService.java @@ -1,3 +1,19 @@ +/** + * 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; diff --git a/src/main/java/org/genesys2/server/service/impl/AccessionListServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/AccessionListServiceImpl.java index 42e1a78c110ae822fac19853015084d83dc16ad8..3d46f9f32818890f3858c4f2f6f23b2cda4acfa3 100644 --- a/src/main/java/org/genesys2/server/service/impl/AccessionListServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/AccessionListServiceImpl.java @@ -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 getLists(List 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 diff --git a/src/main/java/org/genesys2/server/service/impl/ProjectServiceImpl.java b/src/main/java/org/genesys2/server/service/impl/ProjectServiceImpl.java index 34b1ebfab0a1f4b63432151b3aa0facd32406e5c..10a36e403876d4445dc08ba3b403e6930adc1d1c 100644 --- a/src/main/java/org/genesys2/server/service/impl/ProjectServiceImpl.java +++ b/src/main/java/org/genesys2/server/service/impl/ProjectServiceImpl.java @@ -1,3 +1,19 @@ +/** + * 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,54 +31,60 @@ 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; + @Autowired + ProjectRepository projectRepository; - @Autowired - ContentService contentService; + @Autowired + ContentService contentService; - @Override - public Page list(Pageable p) { - return projectRepository.findAll(p); - } + @Override + public Page list(Pageable p) { + return projectRepository.findAll(p); + } - @Override - public Project getProjectById(Long id) { - return projectRepository.findOne(id); - } + @Override + public Project getProjectById(Long id) { + return projectRepository.findOne(id); + } - @Override - public Project getProjectByCode(String code) { - return projectRepository.findByCode(code); - } + @Override + public Project getProjectByCode(String code) { + Project project = projectRepository.findByCode(code); + project.getAccessionLists().size(); + return project; + } - @Override - public List getAllProjects() { - return projectRepository.findAll(); - } + @Override + public List getAllProjects() { + return projectRepository.findAll(); + } - @Override - public List getProjectsByName(String name) { - return projectRepository.findByName(name); - } + @Override + public List getProjectsByName(String name) { + return projectRepository.findByName(name); + } - @Override - public void saveProject(Project project) { - projectRepository.save(project); - } + @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 - public void deleteProject(Project project) { - projectRepository.delete(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) - public void updateBlurp(Project project, String textBody, String summary, Locale locale) { - contentService.updateArticle(project, "blurp", null, textBody, summary, locale); - } + @Override + @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); + } } diff --git a/src/main/java/org/genesys2/server/servlet/controller/ProjectController.java b/src/main/java/org/genesys2/server/servlet/controller/ProjectController.java index cbf29251e9f6cc976542c74d89e5ce8c4d90dce8..34d5e551e101cc72ced4dcc45e8eece5b4cd5a7d 100644 --- a/src/main/java/org/genesys2/server/servlet/controller/ProjectController.java +++ b/src/main/java/org/genesys2/server/servlet/controller/ProjectController.java @@ -1,6 +1,25 @@ +/** + * 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,67 +30,90 @@ 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() { + return "redirect:/project/list"; + } + + @RequestMapping("/list") + public String listProjects(ModelMap modelMap, @RequestParam(value = "page", required = false, defaultValue = "1") int page) { - @Autowired - private ProjectService projectService; + Page projects = projectService.list(new PageRequest(page - 1, 20, new Sort("name"))); - @Autowired - ContentService contentService; + modelMap.addAttribute("pagedData", projects); - @RequestMapping({"/", ""}) - public String projects(){ - return "redirect:/project/list"; - } + return "/project/index"; + } - @RequestMapping("/list") - public String listProjects(ModelMap modelMap, @RequestParam(value = "page", required = false, defaultValue = "1") int page){ + @RequestMapping("/{code}") + public String viewProject(ModelMap modelMap, @PathVariable(value = "code") String code) { + Project project = projectService.getProjectByCode(code); + 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"; + } - Page projects = projectService.list(new PageRequest(page - 1, 20, new Sort("name"))); + @RequestMapping("/add-project") + public String addProject(ModelMap modelMap) { + modelMap.addAttribute("project", new Project()); + return "/project/edit"; + } - modelMap.addAttribute("pagedData", projects); + @RequestMapping("/{code}/edit") + public String editProject(ModelMap modelMap, @PathVariable(value = "code") String code) { + viewProject(modelMap, code); + return "/project/edit"; + } - return "/project/index"; - } + @RequestMapping("/update-project") + public String update(ModelMap modelMap, @ModelAttribute("project") Project p, @RequestParam("blurp") String aboutBody, + @RequestParam(value = "summary", required = false) String summary) { - @RequestMapping("/{code}") - public String viewProject(ModelMap modelMap, @PathVariable(value = "code")String code){ - Project project = projectService.getProjectByCode(code); - modelMap.addAttribute("blurp", contentService.getArticle(project, "blurp", getLocale())); - modelMap.addAttribute("project", project); - return "/project/view"; - } + _logger.debug("Updating project " + p.getCode()); + Project project = null; - @RequestMapping("/edit/{code}") - public String editProject(ModelMap modelMap, @PathVariable(value = "code") String code){ - viewProject(modelMap, code); - return "/project/edit"; - } + if (p.getId() != null) + project = projectService.getProjectById(p.getId()); - @RequestMapping("/{code}/update") - public String update(ModelMap modelMap, @PathVariable(value = "code")String code, @RequestParam("blurp") String aboutBody, - @RequestParam(value = "summary", required = false) String summary){ + if (project == null) { + project = new Project(); + } - _logger.debug("Updating project " + code); - final Project project = projectService.getProjectByCode(code); - if (project == null) { - throw new ResourceNotFoundException(); - } + project.setCode(p.getCode()); + project.setUrl(p.getUrl()); + project.setName(p.getName()); + project.setAccessionLists(p.getAccessionLists()); - projectService.updateBlurp(project, aboutBody, summary, getLocale()); + projectService.saveProject(project); + projectService.updateBlurp(project, aboutBody, summary, getLocale()); - return "redirect:/project/" + code; - } + return "redirect:/project/" + p.getCode(); + } - protected Locale getLocale() { - return LocaleContextHolder.getLocale(); - } + protected Locale getLocale() { + return LocaleContextHolder.getLocale(); + } } diff --git a/src/main/resources/content/language.properties b/src/main/resources/content/language.properties index 7ded274b2253533e424af10b9386cabf7924186c..0eed87d9ead778046da3ccf62fdd54714c1971a6 100644 --- a/src/main/resources/content/language.properties +++ b/src/main/resources/content/language.properties @@ -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 + diff --git a/src/main/webapp/WEB-INF/decorator/header.jsp b/src/main/webapp/WEB-INF/decorator/header.jsp index 1ae899ab8927bc9b24ed34425635e6595efee4ba..70f5c0529184ca9370f37a1b20116269b05d34bc 100644 --- a/src/main/webapp/WEB-INF/decorator/header.jsp +++ b/src/main/webapp/WEB-INF/decorator/header.jsp @@ -58,6 +58,7 @@
  • ">
  • ">
  • ">
  • +
  • ">
  • ">
  • diff --git a/src/main/webapp/WEB-INF/jsp/project/edit.jsp b/src/main/webapp/WEB-INF/jsp/project/edit.jsp index 576e5ba411efa89ff7c96e8bd2e2af747c13bf4f..92ea2b4812c3e7f57e854e494ea94e6c5e0e179f 100644 --- a/src/main/webapp/WEB-INF/jsp/project/edit.jsp +++ b/src/main/webapp/WEB-INF/jsp/project/edit.jsp @@ -1,44 +1,101 @@ -<%@include file="/WEB-INF/jsp/init.jsp" %> +<%@include file="/WEB-INF/jsp/init.jsp"%> +<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> - <spring:message code="project.page.profile.title" arguments="${project.name}" argumentSeparator="|" /> +<spring:message code="project.page.profile.title" arguments="${project.name}" argumentSeparator="|" /> +

    + ${project.name} + + + +

    -
    " method="post"> -
    - -
    + " method="post"> + + + + + +
    + +
    + +
    +
    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    -
    -
    +
    +
    -
    - -
    +
    + +
    -
    -
    +
    +
    + +
    + +
    + +
    + +
    +
    +
    + +
    +
    +
    + + " class="btn btn-primary" /> + " class="btn btn-default"> + + - " class="btn btn-primary" /> " class="btn btn-default"> - - - -
    + - - - + diff --git a/src/main/webapp/WEB-INF/jsp/project/index.jsp b/src/main/webapp/WEB-INF/jsp/project/index.jsp index dc15625024cd27d7480aafc8fb9c36e7fde118c7..640f227e5d5c89ce53e1c36b3a879affac8db872 100644 --- a/src/main/webapp/WEB-INF/jsp/project/index.jsp +++ b/src/main/webapp/WEB-INF/jsp/project/index.jsp @@ -1,32 +1,39 @@ -<%@include file="/WEB-INF/jsp/init.jsp" %> +<%@include file="/WEB-INF/jsp/init.jsp"%> - <spring:message code="project.page.list.title"/> +<spring:message code="project.page.list.title" /> -

    - -

    +

    + +

    -
    - -
    +
    + +
    + + " class="close"> + + + - + diff --git a/src/main/webapp/WEB-INF/jsp/project/view.jsp b/src/main/webapp/WEB-INF/jsp/project/view.jsp index a0de83ca224a1759cfb7d180e37ae69927264a0a..79900c113532045028fb6d9d4f48b5ed764194a3 100644 --- a/src/main/webapp/WEB-INF/jsp/project/view.jsp +++ b/src/main/webapp/WEB-INF/jsp/project/view.jsp @@ -1,33 +1,52 @@ -<%@include file="/WEB-INF/jsp/init.jsp" %> +<%@include file="/WEB-INF/jsp/init.jsp"%> - <c:out value="${project.name}"/> - " /> +<c:out value="${project.code} - ${project.name}" /> +" /> - -
    - -
    -
    +

    + ${project.name} + + + +

    - - " - class="close"> - - - - - " class="close"> - - - + + " class="close"> + + + + + " class="close"> + + + - - <%@include file="/WEB-INF/jsp/content/include/blurp-display.jsp" %> - + + <%@include file="/WEB-INF/jsp/content/include/blurp-display.jsp"%> + + +
    +

    + + + +

    +
    +
    +
      + +
    • + "> +
    • +
      +
    +
    +
    +