Commit 550cf467 authored by Corentin Guillevic's avatar Corentin Guillevic

Add of package 'data' : permit to generate a dataset in the datastore from csv...

Add of package 'data' : permit to generate a dataset in the datastore from csv files. Add test classes for 'data' classes.
parent 8aa836f3
......@@ -26,7 +26,7 @@
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="owner.project.facets" value="java"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/WebAndCloud-1.0-SNAPSHOT/WEB-INF/classes"/>
......
......@@ -16,17 +16,17 @@
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<name>com.google.cloud.tools.eclipse.appengine.standard.java8.appengineWeb</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.google.cloud.tools.eclipse.appengine.standard.java8.appengineWeb</name>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
......
package data;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import javax.servlet.ServletContext;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
public class DataGenerator {
private ServletContext context;
private DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
private HashMap<String, Person> persons = new HashMap<>();
private HashMap<String, Post> posts = new HashMap<>();
public DataGenerator(ServletContext context) {
this.context = context;
}
public void instanciatePersons() throws IOException {
InputStream resource = context.getResourceAsStream("/WEB-INF/persons.csv");
ArrayList<ArrayList<String>> data = new ParserCSV(resource, "<separator>").parse();
Person person;
for(ArrayList<String> personData : data){
person = new Person(personData);
persons.putIfAbsent(person.getId(), person);
}
}
public void instanciatePosts() throws IOException {
InputStream resource = context.getResourceAsStream("/WEB-INF/posts.csv");
ArrayList<ArrayList<String>> data = new ParserCSV(resource, "<separator>").parse();
Post post;
for(ArrayList<String> postData : data){
post = new Post(postData);
posts.putIfAbsent(post.getId(), post);
}
}
public void linkPosterAndPost() {
Set<String> idPosts = posts.keySet();
Post p;
//Link between "poster" and "posts"
for(String keyPost : idPosts) {
p = posts.get(keyPost);
persons.get(p.getIdPoster());
p.getPoster();
p.getPoster().set(persons.get(p.getIdPoster()));
}
}
public void randomFollows(int maxFollows){
int nFollows;
int incr;
int randomIndice;
ArrayList<String> idPersons = new ArrayList<>();
idPersons.addAll(persons.keySet());
Person p;
Person follower;
for(String keyPerson : idPersons) {
nFollows = (int) Math.round(Math.random()*maxFollows);
incr = 0;
while(incr < nFollows) {
randomIndice = (int) Math.round(Math.random()*(idPersons.size()-1));
if(idPersons.get(randomIndice) != keyPerson) {
p = persons.get(keyPerson);
follower = persons.get(idPersons.get(randomIndice));
if(!p.getFollowers().contains(follower)) {
p.getFollowers().add(follower);
++incr;
}
}
}
}
}
public void randomLikes(int maxLikes){
int nLikes;
int incr, nPost;
int randomIndice;
ArrayList<String> idPosts = new ArrayList<>();
idPosts.addAll(posts.keySet());
Set<String> idPersons = persons.keySet();
Person person;
Post post;
for(String keyPerson : idPersons) {
nLikes = (int) Math.round(Math.random()*maxLikes);
incr = 0;
nPost = idPosts.size();
while(incr < nLikes && nPost > 0) {
randomIndice = (int) Math.round(Math.random()*(idPosts.size()-1));
person = persons.get(keyPerson);
post = posts.get(idPosts.get(randomIndice));
if(post.getIdPoster() != person.getId() && !person.getLikedPosts().contains(post)) {
person.getLikedPosts().add(post);
++incr;
}
--nPost;
}
}
}
public void putPersons() {
Set<String> idPersons = persons.keySet();
for(String key : idPersons) {
datastore.put(persons.get(key).toEntity());
//System.out.println(persons.get(key).toEntity().toString());
}
}
public void putPosts() {
Set<String> idPosts = posts.keySet();
for(String key : idPosts) {
datastore.put(posts.get(key).toEntity());
}
}
public void generate() throws Exception{
instanciatePersons();
instanciatePosts();
linkPosterAndPost();
randomFollows(persons.size()/2);
randomLikes(posts.size()/3);
putPersons();
putPosts();
//generatePerson();
}
public final class Constants{
public static final String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.";
}
}
package data;
public interface MultipleBidirectionalReference<T> {
/**
* Ajoute la nouvelle valeur
* Transmet la reference a newValue
* @param newValue: nouvelle valeur
*/
public abstract void add(T newValue);
/**
* Ajoute la nouvelle valeur
* @param newValue: nouvelle valeur
*/
public abstract void basicAdd(T newValue);
/**
* Supprime la valeur
* Supprime la reference de newValue
* @param val: valeur a supprime
* @return vrai si la valeur est supprime, faux sinon
*/
public abstract boolean remove(T val);
/**
* Supprime la valeur
* @param val: valeur a supprime
* @return vrai si la valeur est supprime, faux sinon
*/
public abstract boolean basicRemove(T val);
/**
* Supprime toutes les valeurs stockees
* Supprime les references des valeurs
*/
public abstract void clear();
/**
* Teste si val est contenue dans les valeurs stockees
* @param val: valeur a tester
* @return vrai si val est contenue dans les valeurs, faux sinon
*/
public abstract boolean contains(T val);
/**
* @return le nombre de valeur stockee
*/
public abstract int size();
/**
* @return vrai si aucune valeur n est stockee, faux sinon
*/
public abstract boolean isEmpty();
/**
* @param i: indice de la valeur a renvoyer
* @return la valeur stockee a l indice i
*/
public abstract T get(int i);
}
package data;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
public class ParserCSV {
private InputStream resource;
private String separator;
public ParserCSV(InputStream resource) {
this.resource = resource;
this.separator = ",";
}
public ParserCSV(InputStream resource, String separator) {
this.resource = resource;
this.separator = separator;
}
public InputStream getResource() {
return resource;
}
public void setResource(InputStream resource) {
this.resource = resource;
}
public String getSeparator() {
return separator;
}
public void setSeparator(String separator) {
this.separator = separator;
}
public BufferedReader getBufferReader() {
return new BufferedReader(new InputStreamReader(resource));
}
public ArrayList<ArrayList<String>> parse() throws IOException{
ArrayList<ArrayList<String>> parseArray = new ArrayList<>();
BufferedReader bufferReader = getBufferReader();
String line;
String[] splitLine;
while(bufferReader.ready()) {
line = bufferReader.readLine();
if(!line.isEmpty()) {
splitLine = line.split(separator, -1);
parseArray.add(new ArrayList<String>(Arrays.asList(splitLine)));
}
}
return parseArray;
}
}
package data;
import static data.DataGenerator.Constants.LOREM_IPSUM;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import com.google.appengine.api.datastore.EmbeddedEntity;
import com.google.appengine.api.datastore.Entity;
public class Person {
private String id;
private String name;
private String imageUrl;
private String email;
private String description;
private int numberFollowers = 0;
private int numberFollows = 0;
private int numberPosts = 0;
private MultipleBidirectionalReferencePost posts = new MultipleBidirectionalReferencePost();
private MultipleBidirectionalReferenceLikedPost likedPosts = new MultipleBidirectionalReferenceLikedPost();
private MultipleBidirectionalReferenceFollowers followers = new MultipleBidirectionalReferenceFollowers();
private MultipleBidirectionalReferenceFollows follows = new MultipleBidirectionalReferenceFollows();
public Person(String id, String name, String imageUrl, String email) {
this.id = id;
this.name = name;
this.imageUrl = imageUrl;
this.email = email;
this.description = LOREM_IPSUM;
}
public Person(String id, String name, String imageUrl, String email, String description) {
this.id = id;
this.name = name;
this.imageUrl = imageUrl;
this.email = email;
this.description = description;
}
public Person(ArrayList<String> line) throws IllegalArgumentException{
if(line.size() != 5) {throw new IllegalArgumentException();}
this.id = line.get(0);
this.name = line.get(1);
this.email = line.get(2);
this.imageUrl = line.get(3);
this.description = line.get(4).equals("") ? LOREM_IPSUM : line.get(4);
}
public Entity toEntity() {
Entity e = new Entity("person", id);
e.setProperty("name", name);
e.setProperty("email", email);
e.setProperty("imageUrl", imageUrl);
e.setProperty("description", description);
//Stats
EmbeddedEntity stats = new EmbeddedEntity();
stats.setProperty("numberFollowers", numberFollowers);
stats.setProperty("numberFollows", numberFollows);
stats.setProperty("numberPosts", numberPosts);
e.setProperty("stats", stats);
//List attributes
List<String> follows = getFollows().getCollection()
.stream()
.map(x -> x.getId())
.collect(Collectors.toList());
List<String> followers = getFollowers().getCollection()
.stream()
.map(x -> x.getId())
.collect(Collectors.toList());
List<String> posts = getPosts().getCollection()
.stream()
.map(x -> x.getId())
.collect(Collectors.toList());
List<String> likedPosts = getLikedPosts().getCollection()
.stream()
.map(x -> x.getId())
.collect(Collectors.toList());
e.setProperty("follows", follows);
e.setProperty("followers", followers);
e.setProperty("posts", posts);
e.setProperty("likedPosts", likedPosts);
return e;
}
public String getId() {
return id;
}
public MultipleBidirectionalReferencePost getPosts() {
return posts;
}
public MultipleBidirectionalReferenceLikedPost getLikedPosts() {
return likedPosts;
}
public MultipleBidirectionalReferenceFollowers getFollowers() {
return followers;
}
public MultipleBidirectionalReferenceFollows getFollows() {
return follows;
}
public class MultipleBidirectionalReferencePost implements MultipleBidirectionalReference<Post> {
private ArrayList<Post> posts = new ArrayList<>();
public void add(Post newValue) {
newValue.getPoster().basicSet(Person.this);
posts.add(newValue);
++numberPosts;
}
public void basicAdd(Post newValue) {
posts.add(newValue);
++numberPosts;
}
public boolean remove(Post val) {
val.getPoster().basicUnset();
if(posts.remove(val)) {
--numberPosts;
return true;
}
else {
return false;
}
}
public boolean basicRemove(Post val) {
if(posts.remove(val)) {
--numberPosts;
return true;
}
else {
return false;
}
}
public boolean contains(Post val){
return posts.contains(val);
}
public int size() {
return posts.size();
}
public Post get(int i) {
return posts.get(i);
}
public Collection<Post> getCollection(){
return posts;
}
public void clear(){
for (Post p: posts) {
p.getPoster().basicUnset();
}
posts.clear();
numberPosts = 0;
}
public boolean isEmpty(){
return posts.isEmpty();
}
}
public class MultipleBidirectionalReferenceLikedPost implements MultipleBidirectionalReference<Post> {
private ArrayList<Post> likedPosts = new ArrayList<>();
public void add(Post newValue) {
newValue.getFollowers().basicAdd(Person.this);
likedPosts.add(newValue);
}
public void basicAdd(Post newValue) {
likedPosts.add(newValue);
}
public boolean remove(Post val) {
val.getFollowers().basicRemove(Person.this);
return likedPosts.remove(val);
}
public boolean basicRemove(Post val) {
return likedPosts.remove(val);
}
public boolean contains(Post val){
return likedPosts.contains(val);
}
public int size() {
return likedPosts.size();
}
public Post get(int i) {
return likedPosts.get(i);
}
public Collection<Post> getCollection(){
return likedPosts;
}
public void clear(){
for (Post p: likedPosts) {
p.getFollowers().basicRemove(Person.this);
}
likedPosts.clear();
}
public boolean isEmpty(){
return likedPosts.isEmpty();
}
}
public class MultipleBidirectionalReferenceFollowers implements MultipleBidirectionalReference<Person> {
private ArrayList<Person> persons = new ArrayList<>();
public void add(Person newValue) {
newValue.getFollows().basicAdd(Person.this);
persons.add(newValue);
++numberFollowers;
}
public void basicAdd(Person newValue) {
persons.add(newValue);
++numberFollowers;
}
public boolean remove(Person val) {
val.getFollows().basicRemove(Person.this);
if(persons.remove(val)) {
--numberFollowers;
return true;
}
else {
return false;
}
}
public boolean basicRemove(Person val) {
if(persons.remove(val)) {
--numberFollowers;
return true;
}
else {
return false;
}
}
public boolean contains(Person val){
return persons.contains(val);
}
public int size() {
return persons.size();
}
public Person get(int i) {
return persons.get(i);
}
public Collection<Person> getCollection(){
return persons;
}
public void clear(){
for (Person p: persons) {
p.getFollows().basicRemove(Person.this);
}
persons.clear();
numberFollowers = 0;
}
public boolean isEmpty(){
return persons.isEmpty();
}
}
public class MultipleBidirectionalReferenceFollows implements MultipleBidirectionalReference<Person> {
private ArrayList<Person> persons = new ArrayList<>();
public void add(Person newValue) {
newValue.getFollowers().basicAdd(Person.this);
persons.add(newValue);
++numberFollows;
}
public void basicAdd(Person newValue) {
persons.add(newValue);
++numberFollows;
}
public boolean remove(Person val) {
val.getFollowers().basicRemove(Person.this);
if(persons.remove(val)) {
--numberFollows;
return true;
}
else {
return false;
}
}
public boolean basicRemove(Person val) {
if(persons.remove(val)) {
--numberFollows;
return true;
}
else {
return false;
}
}
public boolean contains(Person val){
return persons.contains(val);
}
public int size() {
return persons.size();
}
public Person get(int i) {
return persons.get(i);
}
public Collection<Person> getCollection(){