diff --git a/src/main/java/org/wikitolearn/wikirating/model/Author.java b/src/main/java/org/wikitolearn/wikirating/model/Author.java new file mode 100644 index 0000000..d869e92 --- /dev/null +++ b/src/main/java/org/wikitolearn/wikirating/model/Author.java @@ -0,0 +1,66 @@ +package org.wikitolearn.wikirating.model; + +import org.neo4j.ogm.annotation.EndNode; +import org.neo4j.ogm.annotation.GraphId; +import org.neo4j.ogm.annotation.RelationshipEntity; +import org.neo4j.ogm.annotation.StartNode; +import org.neo4j.ogm.annotation.typeconversion.DateLong; + +import java.util.Date; + +/** + * This entity represent the edit of a user on a Page. + * It stores the the reliability of the user at the moment + * of the creation. + */ +@RelationshipEntity(type="Author") +public class Author { + @GraphId + private Long graphId; + private double reliability; + @StartNode + private User user; + @EndNode + private Revision revision; + + public Author() { + } + + public Author(double reliability){ + this.reliability = reliability; + } + + public double getReliability() { + return reliability; + } + + public void setReliability(double reliability) { + this.reliability = reliability; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Revision getRevision() { + return revision; + } + + public void setRevision(Revision revision) { + this.revision = revision; + } + + @Override + public String toString() { + return "Author{" + + "graphId=" + graphId + + ", reliability=" + reliability + + ", user=" + user + + ", revision=" + revision + + '}'; + } +} diff --git a/src/main/java/org/wikitolearn/wikirating/model/Revision.java b/src/main/java/org/wikitolearn/wikirating/model/Revision.java index 9db807b..7fa79fb 100644 --- a/src/main/java/org/wikitolearn/wikirating/model/Revision.java +++ b/src/main/java/org/wikitolearn/wikirating/model/Revision.java @@ -1,364 +1,358 @@ package org.wikitolearn.wikirating.model; import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.Index; import org.neo4j.ogm.annotation.NodeEntity; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.neo4j.ogm.annotation.Relationship; import org.neo4j.ogm.annotation.typeconversion.DateLong; import java.util.Date; import java.util.Set; /** * This class handles the data of the Revision of a page. * Created by valsdav on 14/03/17. */ @JsonIgnoreProperties(ignoreUnknown = true) @NodeEntity( label = "Revision" ) public class Revision { @GraphId private Long graphId; private int revid; private String lang; private int userid; private int parentid; @DateLong private Date timestamp; private long length; private double changeCoefficient; private double currentMeanVote; private double currentVotesReliability; private double currentNormalisesVotesReliability; private double totalMeanVote; private double totalVotesReliability; private double totalNormalisesVotesReliability; private boolean validated; @Index(unique = true, primary=true) private String langRevId; @Relationship(type="PREVIOUS_REVISION", direction = Relationship.OUTGOING) private Revision previousRevision; @Relationship(type="VOTE", direction = Relationship.INCOMING) private Set votes; - @Relationship( type="AUTHOR", direction = Relationship.INCOMING) - private User author; + //This relationship represents the connection between the revision + //and its creator (user). It saves his reliability at the moment of the author. + @Relationship(type="AUTHOR", direction = Relationship.INCOMING) + private Author author; /** * */ public Revision() {} /** * @param revid * @param userid * @param parentid * @param length * @param lang * @param timestamp */ public Revision(int revid, String lang, int userid, int parentid, long length, Date timestamp) { this.revid = revid; this.langRevId = lang +"_"+revid; this.userid = userid; this.parentid = parentid; this.length = length; this.lang = lang; this.timestamp = timestamp; this.validated = false; } /** * @return the revid */ public int getRevid() { return revid; } /** * @param revid the revid to set */ public void setRevid(int revid) { this.revid = revid; } /** * @return the userid */ public int getUserid() { return userid; } /** * @param userid the userid to set */ public void setUserid(int userid) { this.userid = userid; } /** * @return the parentid */ public int getParentid() { return parentid; } /** * @param parentid the parentid to set */ public void setParentid(int parentid) { this.parentid = parentid; } /** * @return the length */ public long getLength() { return length; } /** * @param length the length to set */ public void setLength(long length) { this.length = length; } /** * @return the changeCoefficient */ public double getChangeCoefficient() { return changeCoefficient; } /** * @param changeCoefficient the changeCoefficient to set */ public void setChangeCoefficient(double changeCoefficient) { this.changeCoefficient = changeCoefficient; } /** * @return the currentMeanVote */ public double getCurrentMeanVote() { return currentMeanVote; } /** * @param currentMeanVote the currentMeanVote to set */ public void setCurrentMeanVote(double currentMeanVote) { this.currentMeanVote = currentMeanVote; } /** * @return the currentVotesReliability */ public double getCurrentVotesReliability() { return currentVotesReliability; } /** * @param currentVotesReliability the currentVotesReliability to set */ public void setCurrentVotesReliability(double currentVotesReliability) { this.currentVotesReliability = currentVotesReliability; } /** * @return the currentNormalisesVotesReliability */ public double getCurrentNormalisesVotesReliability() { return currentNormalisesVotesReliability; } /** * @param currentNormalisesVotesReliability the currentNormalisesVotesReliability to set */ public void setCurrentNormalisesVotesReliability(double currentNormalisesVotesReliability) { this.currentNormalisesVotesReliability = currentNormalisesVotesReliability; } /** * @return the totalMeanVote */ public double getTotalMeanVote() { return totalMeanVote; } /** * @param totalMeanVote the totalMeanVote to set */ public void setTotalMeanVote(double totalMeanVote) { this.totalMeanVote = totalMeanVote; } /** * @return the totalVotesReliability */ public double getTotalVotesReliability() { return totalVotesReliability; } /** * @param totalVotesReliability the totalVotesReliability to set */ public void setTotalVotesReliability(double totalVotesReliability) { this.totalVotesReliability = totalVotesReliability; } /** * @return the totalNormalisesVotesReliability */ public double getTotalNormalisesVotesReliability() { return totalNormalisesVotesReliability; } /** * @param totalNormalisesVotesReliability the totalNormalisesVotesReliability to set */ public void setTotalNormalisesVotesReliability(double totalNormalisesVotesReliability) { this.totalNormalisesVotesReliability = totalNormalisesVotesReliability; } /** * @return the validated */ public boolean isValidated() { return validated; } /** * @param validated the validated to set */ public void setValidated(boolean validated) { this.validated = validated; } /** * @return the lang */ public String getLang() { return lang; } /** * @param lang the lang to set */ public void setLang(String lang) { this.lang = lang; } /** * @return the langRevId */ public String getLangRevId() { return langRevId; } /** * @param langRevId the langRevId to set */ public void setLangRevId(String langRevId) { this.langRevId = langRevId; } /** * @return the graphId */ public Long getGraphId() { return graphId; } /** * @param graphId the graphId to set */ public void setGraphId(Long graphId) { this.graphId = graphId; } /** * @return the timestamp */ public Date getTimestamp() { return timestamp; } /** * @param timestamp the timestamp to set */ public void setTimestamp(Date timestamp) { this.timestamp = timestamp; } /** * @return the previousRevision */ public Revision getPreviousRevision() { return previousRevision; } /** * @param previousRevision the previousRevision to set */ public void setPreviousRevision(Revision previousRevision) { this.previousRevision = previousRevision; } /** * @return the votes */ public Set getVotes() { return votes; } /** * @param votes the votes to set */ public void setVotes(Set votes) { this.votes = votes; } - /** - * @return the author - */ - public User getAuthor() { + public Author getAuthor() { return author; } - /** - * @param author the author to set - */ - public void setAuthor(User author) { + public void setAuthor(Author author) { this.author = author; } - + /** * * @param vote the vote to set */ public void addVote(Vote vote){ this.votes.add(vote); } /* (non-Javadoc) * @see java.lang.Object#toString() */ - @Override - public String toString() { - return "Revision{" + - "graphId=" + graphId + - ", revid=" + revid + - ", lang='" + lang + '\'' + - ", userid=" + userid + - ", parentid=" + parentid + - ", timestamp=" + timestamp + - ", length=" + length + - ", changeCoefficient=" + changeCoefficient + - ", validated=" + validated + - ", langRevId='" + langRevId + '\'' + - ", author=" + author + - '}'; - } + @Override + public String toString() { + return "Revision{" + + "revid=" + revid + + ", lang='" + lang + '\'' + + ", userid=" + userid + + ", parentid=" + parentid + + ", timestamp=" + timestamp + + ", length=" + length + + ", validated=" + validated + + ", langRevId='" + langRevId + '\'' + + ", author=" + author + + '}'; + } } \ No newline at end of file diff --git a/src/main/java/org/wikitolearn/wikirating/model/User.java b/src/main/java/org/wikitolearn/wikirating/model/User.java index fae4184..f2bbdc5 100644 --- a/src/main/java/org/wikitolearn/wikirating/model/User.java +++ b/src/main/java/org/wikitolearn/wikirating/model/User.java @@ -1,172 +1,173 @@ /** * */ package org.wikitolearn.wikirating.model; import org.neo4j.ogm.annotation.GraphId; import org.neo4j.ogm.annotation.Index; import org.neo4j.ogm.annotation.NodeEntity; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import org.neo4j.ogm.annotation.Relationship; import java.util.Set; /** * @author aletundo, valsdav * */ @NodeEntity( label = "User") @JsonIgnoreProperties(ignoreUnknown = true) public class User { @GraphId private Long graphId; @JsonProperty("name") private String username; @Index(unique=true,primary = true) private int userid; private double votesReliability; private double contributesReliability; private double totalReliability; - @Relationship( type="AUTHOR", direction = Relationship.UNDIRECTED) - private Set revisionsAuthored; + @Relationship( type="AUTHOR", direction = Relationship.OUTGOING) + private Set authors; @Relationship( type="VOTE", direction = Relationship.OUTGOING) private Set votes; /** * */ public User() {} /** * @param username * @param userid * @param votesReliability * @param contributesReliability * @param totalReliability */ public User(String username, int userid, double votesReliability, double contributesReliability, double totalReliability) { this.username = username; this.userid = userid; this.votesReliability = votesReliability; this.contributesReliability = contributesReliability; this.totalReliability = totalReliability; } /** * @return the username */ public String getUsername() { return username; } /** * @param username the username to set */ public void setUsername(String username) { this.username = username; } /** * @return the userid */ public int getUserid() { return userid; } /** * @param userid the userid to set */ public void setUserId(int userid) { this.userid = userid; } /** * @return the votesReliability */ public double getVotesReliability() { return votesReliability; } /** * @param votesReliability the votesReliability to set */ public void setVotesReliability(double votesReliability) { this.votesReliability = votesReliability; } /** * @return the contributesReliability */ public double getContributesReliability() { return contributesReliability; } /** * @param contributesReliability the contributesReliability to set */ public void setContributesReliability(double contributesReliability) { this.contributesReliability = contributesReliability; } /** * @return the totalReliability */ public double getTotalReliability() { return totalReliability; } /** * @param totalReliability the totalReliability to set */ public void setTotalReliability(double totalReliability) { this.totalReliability = totalReliability; } /** * * @return */ - public Set getRevisionsAuthored() { - return revisionsAuthored; + public Set getAuthors() { + return authors; } /** * - * @param revisionsAuthored + * @param authors */ - public void setRevisionsAuthored(Set revisionsAuthored) { - this.revisionsAuthored = revisionsAuthored; + public void setAuthors(Set authors) { + this.authors = authors; } - + + public void addAuthor(Author author){ + this.authors.add(author); + } + /** * * @return the votes of the user */ public Set getVotes() { return votes; } /** * * @param votes the votes to set */ public void setVotes(Set votes) { this.votes = votes; } - - public void setRevisionAuthored(Revision revision){ - this.revisionsAuthored.add(revision); - } + /* (non-Javadoc) * @see java.lang.Object#toString() */ @Override public String toString() { return "User [username=" + username + ", userid=" + userid + ", votesReliability=" + votesReliability + ", contributesReliability=" + contributesReliability + ", totalReliability=" + totalReliability + "]"; } } diff --git a/src/main/java/org/wikitolearn/wikirating/service/UserService.java b/src/main/java/org/wikitolearn/wikirating/service/UserService.java index a48dfec..4b75f50 100644 --- a/src/main/java/org/wikitolearn/wikirating/service/UserService.java +++ b/src/main/java/org/wikitolearn/wikirating/service/UserService.java @@ -1,120 +1,138 @@ /** * */ package org.wikitolearn.wikirating.service; +import java.util.Collection; import java.util.List; import java.util.Set; import java.util.concurrent.CompletableFuture; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.wikitolearn.wikirating.exception.UserNotFoundException; +import org.wikitolearn.wikirating.model.Author; import org.wikitolearn.wikirating.model.Revision; import org.wikitolearn.wikirating.model.User; import org.wikitolearn.wikirating.repository.RevisionRepository; import org.wikitolearn.wikirating.repository.UserRepository; import org.wikitolearn.wikirating.service.mediawiki.UserMediaWikiService; /** * * @author aletundo, valsdav * */ @Service public class UserService { private static final Logger LOG = LoggerFactory.getLogger(UserService.class); @Autowired private UserMediaWikiService userMediaWikiService; @Autowired private UserRepository userRepository; @Autowired private RevisionRepository revisionRepository; /** * Initialize the graph for the first time querying the MediaWiki API * to get the all the users and then insert them. * @param apiUrl the MediaWiki API url * @return CompletableFuture */ @Async public CompletableFuture initUsers(String apiUrl){ List users = userMediaWikiService.getAll(apiUrl); addUsers(users); return CompletableFuture.completedFuture(true); } /** * Initialize relationships between users and their created revisions for the first time * @return CompletableFuture */ @Async public CompletableFuture initAuthorship(){ Iterable users = userRepository.findAll(); - for(User user : users){ Set revisions = revisionRepository.findByUserid(user.getUserid()); - user.setRevisionsAuthored(revisions); - userRepository.save(user); + this.setAuthorship(revisions, user); LOG.info("Set revisions authorship for user {}", user.getUserid()); } - // Get revisions with userid = 0 (anonymous authors) Set anonRevisions = revisionRepository.findByUserid(0); User anonymousUser = new User("AnonymousUser", 0, 0.0, 0.0, 0.0); - anonymousUser.setRevisionsAuthored(anonRevisions); - userRepository.save(anonymousUser); + this.setAuthorship(anonRevisions, anonymousUser); LOG.info("Set revisions authorship for anonymous revisions"); return CompletableFuture.completedFuture(true); } /** * Insert users into the graph * @param users the list of users to be inserted * @return the list of inserted users */ public List addUsers(List users){ userRepository.save(users); LOG.info("Inserted users: {}", users); return users; //TODO handle exceptions } + + /** + * Set the authorship for a list a Revisions for a selected User + * @param revisions + * @param user + */ + public void setAuthorship(Collection revisions, User user){ + for (Revision rev : revisions){ + Author author = new Author(user.getTotalReliability()); + author.setRevision(rev); + author.setUser(user); + user.addAuthor(author); + } + userRepository.save(user); + } /** - * Set the authorship for a revision + * Set the authorship for a revision creating a new Author relationship + * that saves the reliability of the user. * @param revision the revision */ public void setAuthorship(Revision revision){ User user = userRepository.findByUserId(revision.getUserid()); - user.setRevisionAuthored(revision); + Author author = new Author(user.getTotalReliability()); + author.setRevision(revision); + author.setUser(user); + user.addAuthor(author); + userRepository.save(user); } /** * Set the authorship for a list of revisions * @param revisions the list of revisions */ - public void setAuthorship(List revisions){ + public void setAuthorship(Collection revisions){ for(Revision revision : revisions){ setAuthorship(revision); } } /** * Get the requested user. * @param userId the user id * @return the requested user * @throws UserNotFoundException */ public User getUser(int userId) throws UserNotFoundException{ User user = userRepository.findByUserId(userId); if(user == null){ LOG.error("User {} not found", userId); throw new UserNotFoundException(); } return user; } }