diff --git a/vipra-rest/src/main/java/de/vipra/rest/model/Article.java b/vipra-rest/src/main/java/de/vipra/rest/model/Article.java index 54eee2bf673b768ed79033909d1ea0dda0556b69..15e9003eee3bd6479e401b4d99f871a8c7c00eeb 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/model/Article.java +++ b/vipra-rest/src/main/java/de/vipra/rest/model/Article.java @@ -1,22 +1,13 @@ package de.vipra.rest.model; import java.net.URI; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import org.bson.Document; - public class Article extends de.vipra.util.model.Article { private Map<String, String> links; - public Article() {} - - public Article(Document document) { - super(document); - } - public Map<String, String> getLinks() { return links; } @@ -32,19 +23,11 @@ public class Article extends de.vipra.util.model.Article { links.put(name, link); } - public void setSelf(URI base) { + public void setBase(URI base) { URI self = uri(base); if (self != null) { addLink("self", self.toString()); } } - public static ArrayList<Article> fromDocuments(final ArrayList<Document> docs) { - ArrayList<Article> articles = new ArrayList<Article>(); - for (Document doc : docs) { - articles.add(new Article(doc)); - } - return articles; - } - } diff --git a/vipra-rest/src/main/java/de/vipra/rest/resource/ArticleResource.java b/vipra-rest/src/main/java/de/vipra/rest/resource/ArticleResource.java index 9755629db7cf90e626a28c476527b6127e6d870b..c346a0834bec048169e82d360c5473a067ae272b 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/resource/ArticleResource.java +++ b/vipra-rest/src/main/java/de/vipra/rest/resource/ArticleResource.java @@ -39,7 +39,7 @@ public class ArticleResource { public ArticleResource(@Context ServletContext servletContext) throws ConfigException, IOException { Config config = new Config(); Mongo mongo = Mongo.getInstance(config); - service = new ArticleService(mongo.getDatabase()); + service = new ArticleService(mongo); } @GET diff --git a/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleDeserializer.java b/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleDeserializer.java index fef599531f1d1b5c172c4e14866b1ffc65a86673..14c531038b1b9334e97e699ef9ecc4504439a6cd 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleDeserializer.java +++ b/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleDeserializer.java @@ -10,7 +10,7 @@ import com.fasterxml.jackson.databind.JsonNode; import de.vipra.rest.model.Article; -import static de.vipra.rest.serializer.Helper.*; +import static de.vipra.rest.serializer.JsonHelper.*; public class ArticleDeserializer extends JsonDeserializer<Article> { diff --git a/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleSerializer.java b/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleSerializer.java index a248288e9fecd3ca81ccc4c7e3311260bbdcc08a..c241ce97af969b4acb6954d8e0cf4e9b27ed77b3 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleSerializer.java +++ b/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleSerializer.java @@ -9,7 +9,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; -import static de.vipra.rest.serializer.Helper.*; +import static de.vipra.rest.serializer.JsonHelper.*; public class ArticleSerializer extends JsonSerializer<Article> { diff --git a/vipra-rest/src/main/java/de/vipra/rest/serializer/Helper.java b/vipra-rest/src/main/java/de/vipra/rest/serializer/JsonHelper.java similarity index 98% rename from vipra-rest/src/main/java/de/vipra/rest/serializer/Helper.java rename to vipra-rest/src/main/java/de/vipra/rest/serializer/JsonHelper.java index d4d04f45134cb92c2b82c8ca94d6dc679f257e06..10bfca3a60b0e2f7f716515519407f76cf96f96c 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/serializer/Helper.java +++ b/vipra-rest/src/main/java/de/vipra/rest/serializer/JsonHelper.java @@ -7,7 +7,7 @@ import java.util.Date; import com.fasterxml.jackson.databind.JsonNode; -public class Helper { +public class JsonHelper { public static <T> T get(JsonNode node, String name, T defaultValue, Class<T> type) { if (node == null) { diff --git a/vipra-rest/src/main/java/de/vipra/rest/service/ArticleService.java b/vipra-rest/src/main/java/de/vipra/rest/service/ArticleService.java index 4d98db3203c54822a9ca1ad887ffd47754c79bb8..09444254534b927ad9ca529124afeaaca741f2a6 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/service/ArticleService.java +++ b/vipra-rest/src/main/java/de/vipra/rest/service/ArticleService.java @@ -3,69 +3,49 @@ package de.vipra.rest.service; import java.net.URI; import java.util.ArrayList; -import org.bson.Document; - -import com.mongodb.client.MongoCollection; -import com.mongodb.client.MongoDatabase; -import com.mongodb.client.model.Filters; -import com.mongodb.client.result.DeleteResult; -import com.mongodb.client.result.UpdateResult; - import de.vipra.rest.model.Article; +import de.vipra.util.Mongo; +import de.vipra.util.service.ModelService; -import static de.vipra.rest.resource.Helper.*; - -public class ArticleService { - - final MongoCollection<Document> articles; +public class ArticleService extends ModelService<Article> { - public ArticleService(MongoDatabase db) { - articles = db.getCollection("articles"); + public ArticleService(Mongo mongo) { + super(mongo, "articles", Article.class); } public Article getArticle(URI base, String id) { - ArrayList<Document> result = articles.find(Filters.eq("_id", objectId(id))).into(new ArrayList<Document>()); - if (result.size() == 1) { - Article article = new Article(result.get(0)); - article.setSelf(base); - return article; - } else { - return null; + Article article = super.getSingle(id); + if (article != null) { + article.setBase(base); } + return article; } public ArrayList<Article> getArticles(URI base, int skip, int limit, String sortBy) { - - ArrayList<Document> docs = articles.find().skip(skip).limit(limit).sort(getSorts(sortBy)) - .into(new ArrayList<Document>()); - ArrayList<Article> result = Article.fromDocuments(docs); - for (Article article : result) { + ArrayList<Article> articles = super.getMultiple(skip, limit, sortBy); + for (Article article : articles) { article.setText(null); - article.setSelf(base); + article.setBase(base); } - return result; + return articles; } public Article createArticle(URI base, Article article) { - Document doc = new Document(article.toDocument()); - articles.insertOne(doc); - article = new Article(doc); - article.setSelf(base); + article = super.createSingle(article); + if (article != null) { + article.setBase(base); + } return article; } public long deleteArticle(String id) { - DeleteResult result = articles.deleteOne(Filters.eq("_id", objectId(id))); - return result.getDeletedCount(); + return super.deleteSingle(id); } public long updateArticle(URI base, Article article) { - Document docOld = new Document("_id", objectId(article.getId())); - Document docNew = article.toDocument(); - UpdateResult result = articles.replaceOne(docOld, docNew); - article.fromDocument(docNew); - article.setSelf(base); - return result.getModifiedCount(); + long updated = super.updateSingle(article); + article.setBase(base); + return updated; } } diff --git a/vipra-util/.classpath b/vipra-util/.classpath index d38d831c96760fdab9ce81082bb658d298932a2c..8e8834b85c6119993d8a437a28cc84a03dbd4179 100644 --- a/vipra-util/.classpath +++ b/vipra-util/.classpath @@ -2,16 +2,16 @@ <classpath> <classpathentry kind="src" path="src/main/java"/> <classpathentry kind="src" path="src/main/resources"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> <attributes> <attribute name="maven.pomderived" value="true"/> </attributes> </classpathentry> - <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> <attributes> - <attribute name="maven.pomderived" value="true"/> + <attribute name="owner.project.facets" value="java"/> </attributes> </classpathentry> - <classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/> <classpathentry kind="output" path="target/classes"/> </classpath> diff --git a/vipra-util/.settings/org.eclipse.jdt.core.prefs b/vipra-util/.settings/org.eclipse.jdt.core.prefs index b57afe22e4855dd1b5f89346a1983ffbb135152c..0f67aafb9462a60cfdb12a1efb87599393e417e4 100644 --- a/vipra-util/.settings/org.eclipse.jdt.core.prefs +++ b/vipra-util/.settings/org.eclipse.jdt.core.prefs @@ -1,15 +1,15 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/vipra-util/.settings/org.eclipse.wst.common.project.facet.core.xml b/vipra-util/.settings/org.eclipse.wst.common.project.facet.core.xml index 926884d914bf20b850efed694a328543aa498e30..78e8ebb782bd149152a876e5c227156f0192bd2a 100644 --- a/vipra-util/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/vipra-util/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -2,6 +2,6 @@ <faceted-project> <fixed facet="jst.utility"/> <fixed facet="java"/> - <installed facet="java" version="1.6"/> <installed facet="jst.utility" version="1.0"/> + <installed facet="java" version="1.8"/> </faceted-project> diff --git a/vipra-rest/src/main/java/de/vipra/rest/resource/Helper.java b/vipra-util/src/main/java/de/vipra/util/helper/MongoHelper.java similarity index 83% rename from vipra-rest/src/main/java/de/vipra/rest/resource/Helper.java rename to vipra-util/src/main/java/de/vipra/util/helper/MongoHelper.java index 14037482fbb3d0ee7eadaa0222b5b4f7f4ad9007..5b39e776c590ae5c2f96f51749f1e860deebec66 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/resource/Helper.java +++ b/vipra-util/src/main/java/de/vipra/util/helper/MongoHelper.java @@ -1,17 +1,17 @@ -package de.vipra.rest.resource; - -import static com.mongodb.client.model.Sorts.*; +package de.vipra.util.helper; import java.util.ArrayList; import org.bson.conversions.Bson; import org.bson.types.ObjectId; -public class Helper { +import static com.mongodb.client.model.Sorts.*; + +public class MongoHelper { public static Bson getSorts(String sortBy) { String[] sortKeys = sortBy.split(","); - ArrayList<Bson> sorts = new ArrayList<>(sortKeys.length); + ArrayList<Bson> sorts = new ArrayList<Bson>(sortKeys.length); for (String sort : sortKeys) { if (sort.startsWith("-")) { sorts.add(descending(sort.substring(1))); diff --git a/vipra-util/src/main/java/de/vipra/util/model/Article.java b/vipra-util/src/main/java/de/vipra/util/model/Article.java index a784d993105ef1fbcf283aaec923227c67154b99..77d2d07dd25b6db5ae1f1cee275c5d82c6646b79 100644 --- a/vipra-util/src/main/java/de/vipra/util/model/Article.java +++ b/vipra-util/src/main/java/de/vipra/util/model/Article.java @@ -12,15 +12,6 @@ public class Article extends Model { private String url; private Date date; - public Article() { - super(Article.class); - } - - public Article(Document document) { - this(); - fromDocument(document); - } - public String getTitle() { return title; } @@ -53,6 +44,11 @@ public class Article extends Model { this.date = date; } + public String getType() { + return Article.class.getSimpleName().toLowerCase(); + } + + @Override public Document toDocument() { Document doc = new Document("title", title).append("text", text).append("url", url).append("date", date); if (getId() != null) { @@ -61,6 +57,7 @@ public class Article extends Model { return doc; } + @Override public void fromDocument(Document document) { setId(document.getObjectId("_id").toString()); setTitle(document.getString("title")); diff --git a/vipra-util/src/main/java/de/vipra/util/model/Model.java b/vipra-util/src/main/java/de/vipra/util/model/Model.java index a8078a513b112e17ecd551c95ca2dc687f69e948..77073b12997982363ddd51b1aa96578854bc5fe2 100644 --- a/vipra-util/src/main/java/de/vipra/util/model/Model.java +++ b/vipra-util/src/main/java/de/vipra/util/model/Model.java @@ -3,13 +3,16 @@ package de.vipra.util.model; import java.net.URI; import java.net.URISyntaxException; +import org.bson.Document; + public abstract class Model { private String id; - private final String type; - public Model(Class<?> clazz) { - this.type = clazz.getSimpleName().toLowerCase(); + public Model() {} + + public Model(Document document) { + fromDocument(document); } public String getId() { @@ -20,10 +23,6 @@ public abstract class Model { this.id = id; } - public String getType() { - return type; - } - public URI uri(URI base) { try { return new URI(base.toString() + "/" + getId()); @@ -32,4 +31,10 @@ public abstract class Model { } } + public abstract String getType(); + + public abstract void fromDocument(Document document); + + public abstract Document toDocument(); + } diff --git a/vipra-util/src/main/java/de/vipra/util/service/ModelService.java b/vipra-util/src/main/java/de/vipra/util/service/ModelService.java new file mode 100644 index 0000000000000000000000000000000000000000..d24a0b71046490876a13adfd230001c1ebe6b480 --- /dev/null +++ b/vipra-util/src/main/java/de/vipra/util/service/ModelService.java @@ -0,0 +1,84 @@ +package de.vipra.util.service; + +import static de.vipra.util.helper.MongoHelper.getSorts; +import static de.vipra.util.helper.MongoHelper.objectId; + +import java.util.ArrayList; + +import org.bson.Document; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.mongodb.client.MongoCollection; +import com.mongodb.client.model.Filters; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; + +import de.vipra.util.Mongo; +import de.vipra.util.model.Model; + +public class ModelService<T extends Model> { + + private static final Logger log = LoggerFactory.getLogger(ModelService.class); + + private final MongoCollection<Document> collection; + private final Class<T> clazz; + + public ModelService(Mongo mongo, String collectionName, Class<T> clazz) { + this.collection = mongo.getDatabase().getCollection(collectionName); + this.clazz = clazz; + } + + private T newT(Document document) { + try { + T t = clazz.newInstance(); + t.fromDocument(document); + return t; + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | SecurityException e) { + log.error(e.getMessage()); + return null; + } + } + + protected T getSingle(String id) { + ArrayList<Document> result = collection.find(Filters.eq("_id", objectId(id))).into(new ArrayList<Document>()); + if (result.size() == 1) { + return newT(result.get(0)); + } else { + return null; + } + } + + protected ArrayList<T> getMultiple(int skip, int limit, String sortBy) { + ArrayList<Document> documents = collection.find().skip(skip).limit(limit).sort(getSorts(sortBy)) + .into(new ArrayList<Document>()); + ArrayList<T> items = new ArrayList<>(documents.size()); + + for (Document document : documents) { + items.add(newT(document)); + } + + return items; + } + + protected T createSingle(T t) { + Document document = new Document(t.toDocument()); + collection.insertOne(document); + t.fromDocument(document); + return t; + } + + protected long deleteSingle(String id) { + DeleteResult result = collection.deleteOne(Filters.eq("_id", objectId(id))); + return result.getDeletedCount(); + } + + protected long updateSingle(T t) { + Document docOld = new Document("_id", objectId(t.getId())); + Document docNew = t.toDocument(); + UpdateResult result = collection.replaceOne(docOld, docNew); + t.fromDocument(docNew); + return result.getModifiedCount(); + } + +}