Manager for publications (especially authorships)

pull/1/head
Jens Pelzetter 2019-09-07 19:49:12 +02:00
parent d9c8c10ac5
commit 9ed08ad047
18 changed files with 372 additions and 278 deletions

View File

@ -1,18 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @param <T>
*/
public abstract class AbstractPublicationWithPublisherRepository<T extends PublicationWithPublisher>
extends AbstractPublicationRepository<T> {
private static final long serialVersionUID = 1L;
}

View File

@ -1,17 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @param <T>
*/
public abstract class AbstractUnPublishedRepository<T extends UnPublished> extends AbstractPublicationRepository<T> {
private static final long serialVersionUID = 1L;
}

View File

@ -1,22 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ArticleInCollectedVolumeRepository
extends AbstractPublicationRepository<ArticleInCollectedVolume> {
private static final long serialVersionUID = 1L;
@Override
public Class<ArticleInCollectedVolume> getEntityClass() {
return ArticleInCollectedVolume.class;
}
}

View File

@ -1,22 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ArticleInJournalRepository
extends AbstractPublicationRepository<ArticleInJournal>{
private static final long serialVersionUID = 1L;
@Override
public Class<ArticleInJournal> getEntityClass() {
return ArticleInJournal.class;
}
}

View File

@ -0,0 +1,172 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
import org.hibernate.envers.Audited;
import org.librecms.assets.Person;
import java.io.Serializable;
import java.util.Objects;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import static org.scientificcms.publications.SciPublicationsConstants.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Entity
@Table(name = "AUTHORSHIPS", schema = DB_SCHEMA)
@Audited
public class Authorship implements Serializable, Comparable<Authorship> {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "AUTHORSHIP_ID")
@GeneratedValue(strategy = GenerationType.AUTO)
private long authorshipId;
@Column(name = "UUID", length = 36, nullable = false)
private String uuid;
@ManyToOne
@JoinColumn(name = "PUBLICATION_ID")
private Publication publication;
@ManyToOne
@JoinColumn(name = "AUTHOR_ID")
private Person author;
@Column(name = "EDITOR")
private boolean editor;
@Column(name = "AUTHOR_ORDER")
private long authorOrder;
public long getAuthorshipId() {
return authorshipId;
}
protected void setAuthorshipId(final long authorshipId) {
this.authorshipId = authorshipId;
}
public String getUuid() {
return uuid;
}
protected void setUuid(final String uuid) {
this.uuid = uuid;
}
public Publication getPublication() {
return publication;
}
protected void setPublication(final Publication publication) {
this.publication = publication;
}
public Person getAuthor() {
return author;
}
protected void setAuthor(final Person author) {
this.author = author;
}
public boolean isEditor() {
return editor;
}
public void setEditor(final boolean editor) {
this.editor = editor;
}
public long getAuthorOrder() {
return authorOrder;
}
public void setAuthorOrder(final long authorOrder) {
this.authorOrder = authorOrder;
}
@Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + (int) (authorshipId ^ (authorshipId >>> 32));
hash = 59 * hash + Objects.hashCode(uuid);
hash = 59 * hash + (editor ? 1 : 0);
hash = 59 * hash + (int) (authorOrder ^ (authorOrder >>> 32));
return hash;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Authorship)) {
return false;
}
final Authorship other = (Authorship) obj;
if (!other.canEqual(this)) {
return false;
}
if (authorshipId != other.getAuthorshipId()) {
return false;
}
if (editor != other.isEditor()) {
return false;
}
return authorOrder == other.getAuthorOrder();
}
public boolean canEqual(final Object obj) {
return obj instanceof Authorship;
}
@Override
public int compareTo(final Authorship other) {
return Long.compare(authorOrder, other.getAuthorOrder());
}
@Override
public final String toString() {
return toString("");
}
public String toString(final String data) {
return String.format("%s{ "
+ "authorshipId = %d, "
+ "uuid = %s, "
+ "author = %s"
+ "editor = %b,"
+ "authorOrder = %d%s "
+ "}",
super.toString(),
authorshipId,
uuid,
Objects.toString(author),
editor,
authorOrder,
data);
}
}

View File

@ -1,22 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CollectedVolumeRepository
extends AbstractPublicationWithPublisherRepository<CollectedVolume>{
private static final long serialVersionUID = 1L;
@Override
public Class<CollectedVolume> getEntityClass() {
return CollectedVolume.class;
}
}

View File

@ -1,21 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ExpertiseRepository extends AbstractPublicationRepository<Expertise> {
private static final long serialVersionUID = 1L;
@Override
public Class<Expertise> getEntityClass() {
return Expertise.class;
}
}

View File

@ -1,22 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class GreyLiteratureRepository
extends AbstractUnPublishedRepository<GreyLiterature>{
private static final long serialVersionUID = 1L;
@Override
public Class<GreyLiterature> getEntityClass() {
return GreyLiterature.class;
}
}

View File

@ -1,21 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class InProceedingsRepository extends AbstractPublicationRepository<InProceedings> {
private static final long serialVersionUID = 1L;
@Override
public Class<InProceedings> getEntityClass() {
return InProceedings.class;
}
}

View File

@ -1,21 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class InternetArticleRepository extends AbstractPublicationRepository<InternetArticle>{
private static final long serialVersionUID = 1L;
@Override
public Class<InternetArticle> getEntityClass() {
return InternetArticle.class;
}
}

View File

@ -1,22 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class MonographRepository
extends AbstractPublicationWithPublisherRepository<Monograph> {
private static final long serialVersionUID = 1L;
@Override
public Class<Monograph> getEntityClass() {
return Monograph.class;
}
}

View File

@ -1,22 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ProceedingsRepository
extends AbstractPublicationWithPublisherRepository<Proceedings>{
private static final long serialVersionUID = 1L;
@Override
public Class<Proceedings> getEntityClass() {
return Proceedings.class;
}
}

View File

@ -9,13 +9,18 @@ import org.hibernate.envers.Audited;
import org.libreccm.l10n.LocalizedString;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import javax.persistence.AssociationOverride;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@ -23,6 +28,8 @@ import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import static org.scientificcms.publications.SciPublicationsConstants.*;
@ -51,6 +58,13 @@ public class Publication implements Serializable {
@Column(name = "YEAR_OF_PUBLICATION")
private Integer yearOfPublication;
@OneToMany(cascade = CascadeType.ALL,
fetch = FetchType.LAZY,
mappedBy = "author",
orphanRemoval = true)
@OrderBy("authorOrder")
private List<Authorship> authorships;
@Embedded
@AssociationOverride(
name = "values",
@ -105,6 +119,7 @@ public class Publication implements Serializable {
private Locale languageOfPublication;
public Publication() {
authorships = new ArrayList<>();
title = new LocalizedString();
shortDescription = new LocalizedString();
publicationAbstract = new LocalizedString();
@ -135,6 +150,30 @@ public class Publication implements Serializable {
this.yearOfPublication = yearOfPublication;
}
public List<Authorship> getAuthorships() {
if (authorships == null) {
return null;
} else {
return Collections.unmodifiableList(authorships);
}
}
protected void addAuthorship(final Authorship authorship) {
authorships.add(authorship);
}
protected void removeAuthorship(final Authorship authorship) {
authorships.remove(authorship);
}
protected void setAuthorships(final List<Authorship> authorships) {
if (authorships == null) {
this.authorships = null;
} else {
this.authorships = new ArrayList<>(authorships);
}
}
public LocalizedString getTitle() {
return title;
}
@ -197,6 +236,7 @@ public class Publication implements Serializable {
hash = 97 * hash + (int) (publicationId ^ (publicationId >>> 32));
hash = 97 * hash + Objects.hashCode(uuid);
hash = 97 * hash + Objects.hashCode(yearOfPublication);
hash = 97 * hash + Objects.hashCode(authorships);
hash = 97 * hash + Objects.hashCode(title);
hash = 97 * hash + Objects.hashCode(shortDescription);
hash = 97 * hash + Objects.hashCode(publicationAbstract);
@ -232,6 +272,9 @@ public class Publication implements Serializable {
if (!Objects.equals(yearOfPublication, other.getYearOfPublication())) {
return false;
}
if (!Objects.equals(authorships, other.getAuthorships())) {
return false;
}
if (!Objects.equals(title, other.getTitle())) {
return false;
}
@ -266,6 +309,7 @@ public class Publication implements Serializable {
+ "publicationId = %d, "
+ "uuid = \"%s\""
+ "yearOfPublication = %d, "
+ "authorships = %s, "
+ "title = %s, "
+ "shortDescription = %s, "
+ "publicationAbstract = %s, "
@ -278,6 +322,7 @@ public class Publication implements Serializable {
publicationId,
uuid,
yearOfPublication,
authorships,
Objects.toString(title),
Objects.toString(shortDescription),
Objects.toString(publicationAbstract),

View File

@ -0,0 +1,141 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege;
import org.librecms.assets.Person;
import org.librecms.contentsection.privileges.ItemPrivileges;
import java.util.Objects;
import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
public class PublicationManager {
@Inject
private PublicationRepository publicationRepository;
@Inject
private EntityManager entityManager;
public void addAuthor(final Person person,
final Publication toPublication) {
Objects.requireNonNull(person);
Objects.requireNonNull(toPublication);
addAuthor(person,
toPublication,
false,
toPublication.getAuthorships().size());
}
public void addAuthor(final Person person,
final Publication toPublication,
final boolean asEditor) {
Objects.requireNonNull(person);
Objects.requireNonNull(toPublication);
addAuthor(person,
toPublication,
asEditor,
toPublication.getAuthorships().size());
}
/**
* Adds an person as author to a publication.
*
* @param person
* @param toPublication
* @param asEditor
* @param atPosition
*/
@AuthorizationRequired
@RequiresPrivilege(ItemPrivileges.EDIT)
@Transactional(Transactional.TxType.REQUIRED)
public void addAuthor(final Person person,
final Publication toPublication,
final boolean asEditor,
final long atPosition) {
Objects.requireNonNull(person);
Objects.requireNonNull(toPublication);
if (atPosition < 0) {
throw new IllegalArgumentException("position can't less than 0");
}
// First check if person is already an author.
final boolean alreadyAdded = toPublication
.getAuthorships()
.stream()
.map(Authorship::getAuthor)
.anyMatch(author -> author.equals(person));
if (alreadyAdded) {
throw new IllegalArgumentException(
String.format(
"Person %s is already an author of "
+ "publication %s.",
Objects.toString(person),
Objects.toString(toPublication)
)
);
}
// Create authorship relation
final long numberOfAuthors = toPublication.getAuthorships().size();
final Authorship authorship = new Authorship();
authorship.setAuthor(person);
authorship.setPublication(toPublication);
authorship.setEditor(asEditor);
if (atPosition >= numberOfAuthors) {
authorship.setAuthorOrder(numberOfAuthors);
} else {
authorship.setAuthorOrder(atPosition);
toPublication
.getAuthorships()
.stream()
.filter(obj -> obj.getAuthorOrder() >= atPosition)
.forEach(obj -> obj.setAuthorOrder(obj.getAuthorOrder() + 1));
}
toPublication.addAuthorship(authorship);
publicationRepository.save(toPublication);
}
public void removeAuthor(final Person author,
final Publication fromPublication) {
final Optional<Authorship> result = fromPublication
.getAuthorships()
.stream()
.filter(authorship -> authorship.getAuthor().equals(author))
.findAny();
if (!result.isPresent()) {
return ;
}
final Authorship remove = result.get();
fromPublication.removeAuthorship(remove);
for(int i = 0; i < fromPublication.getAuthorships().size(); i++) {
fromPublication.getAuthorships().get(i).setAuthorOrder(i);
}
entityManager.remove(remove);
publicationRepository.save(fromPublication);
}
}

View File

@ -7,13 +7,15 @@ package org.scientificcms.publications;
import org.libreccm.core.AbstractEntityRepository;
import javax.enterprise.context.RequestScoped;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @param <T>
*/
public abstract class AbstractPublicationRepository<T extends Publication>
extends AbstractEntityRepository<Long, T> {
@RequestScoped
public class PublicationRepository
extends AbstractEntityRepository<Long, Publication> {
private static final long serialVersionUID = 1L;
@ -23,13 +25,18 @@ public abstract class AbstractPublicationRepository<T extends Publication>
}
@Override
public Long getIdOfEntity(final T entity) {
public Long getIdOfEntity(final Publication entity) {
return entity.getPublicationId();
}
@Override
public boolean isNew(final T entity) {
public boolean isNew(final Publication entity) {
return entity.getPublicationId() == 0;
}
@Override
public Class<Publication> getEntityClass() {
return Publication.class;
}
}

View File

@ -1,21 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class TalkRepository extends AbstractPublicationRepository<Talk> {
private static final long serialVersionUID = 1L;
@Override
public Class<Talk> getEntityClass() {
return Talk.class;
}
}

View File

@ -1,21 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.scientificcms.publications;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class WorkingPaperRepository extends AbstractUnPublishedRepository<WorkingPaper> {
private static final long serialVersionUID = 1L;
@Override
public Class<WorkingPaper> getEntityClass() {
return WorkingPaper.class;
}
}

View File

@ -32,6 +32,7 @@ public class EqualsAndHashCodeTest extends EqualsVerifier {
return Arrays.asList(new Class<?>[]{
ArticleInCollectedVolume.class,
ArticleInJournal.class,
Authorship.class,
CollectedVolume.class,
Expertise.class,
GreyLiterature.class,