diff --git a/.classpath b/.classpath
index 2fde9ee..db0444e 100644
--- a/.classpath
+++ b/.classpath
@@ -5,26 +5,19 @@
-
-
-
-
-
-
+
-
-
+
-
@@ -44,22 +37,13 @@
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
diff --git a/.gitignore b/.gitignore
index e6d545e..9255f6f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,10 +21,12 @@ etc/ivy/ivy.jar
restMapping.xml
/out
/output/
+bin/start_network.bat
+bin/start_network.sh
# IntelliJ
.idea/
# Eclipse
.metadata
-.idea/workspace.xml
\ No newline at end of file
+.idea/workspace.xml
diff --git a/bin/JOOQGeneration/run.bat b/bin/JOOQGeneration/run.bat
index 07f809b..a78426e 100644
--- a/bin/JOOQGeneration/run.bat
+++ b/bin/JOOQGeneration/run.bat
@@ -1 +1 @@
-java -classpath ../../lib/jooq-3.6.2.jar;../../lib/jooq-meta-3.6.2.jar;../../lib/jooq-codegen-3.6.2.jar;../../lib/mysql-connector-java-5.1.6.jar;. org.jooq.util.GenerationTool /activitytracker_generation_info.xml
+java -classpath ../../lib/jooq-3.8.2.jar;../../lib/jooq-meta-3.8.2.jar;../../lib/jooq-codegen-3.8.2.jar;../../lib/mysql-connector-java-5.1.6.jar;. org.jooq.util.GenerationTool /activitytracker_generation_info.xml
diff --git a/bin/JOOQGeneration/run.sh b/bin/JOOQGeneration/run.sh
index be8eeea..f6d6d0b 100644
--- a/bin/JOOQGeneration/run.sh
+++ b/bin/JOOQGeneration/run.sh
@@ -1 +1 @@
-java -classpath ../../lib/jooq-3.4.2.jar:../../lib/jooq-meta-3.4.2.jar:../../lib/jooq-codegen-3.4.2.jar:../../lib/mysql-connector-java-5.1.33.jar:. org.jooq.util.GenerationTool /reqbaz_generation_info.xml
\ No newline at end of file
+java -classpath ../../lib/jooq-3.8.2.jar:../../lib/jooq-meta-3.8.2.jar:../../lib/jooq-codegen-3.8.2.jar:../../lib/mysql-connector-java-5.1.6.jar:. org.jooq.util.GenerationTool /reqbaz_generation_info.xml
\ No newline at end of file
diff --git a/bin/start_network.bat b/bin/start_network.bat
deleted file mode 100644
index 1330bfa..0000000
--- a/bin/start_network.bat
+++ /dev/null
@@ -1,15 +0,0 @@
-:: this script is autogenerated by 'ant
- startscripts'
- :: it starts a LAS2peer node providing the service 'de.rwth.dbis.acis.activitytracker.service.ActivityTrackerService' of this project
- :: pls execute it from the bin folder of your deployment by double-clicking on it
-
- %~d0
- cd %~p0
- cd ..
- set BASE=%CD%
- set CLASSPATH="%BASE%/lib/*;"
-
- java -cp %CLASSPATH% i5.las2peer.tools.L2pNodeLauncher -p 9012 uploadStartupDirectory startService('de.rwth.dbis.acis.activitytracker.service.ActivityTrackerService@0.1','Passphrase') startWebConnector interactive
- pause
-
-
\ No newline at end of file
diff --git a/bin/start_network.sh b/bin/start_network.sh
deleted file mode 100644
index b4f0878..0000000
--- a/bin/start_network.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
- # this script is autogenerated by 'ant startscripts'
- # it starts a LAS2peer node providing the service 'de.rwth.dbis.acis.activitytracker.service.ActivityTrackerService' of this project
- # pls execute it from the root folder of your deployment, e. g. ./bin/start_network.sh
-
- java -cp "lib/*" i5.las2peer.tools.L2pNodeLauncher -p 9012 uploadStartupDirectory startService\(\'de.rwth.dbis.acis.activitytracker.service.ActivityTrackerService@0.1\',\'Passphrase\'\) startWebConnector interactive
-
-
\ No newline at end of file
diff --git a/etc/activitytracker_demo_data.sql b/etc/activitytracker_demo_data.sql
index 2abcd3a..60dc90e 100644
--- a/etc/activitytracker_demo_data.sql
+++ b/etc/activitytracker_demo_data.sql
@@ -18,7 +18,7 @@ VALUES
NULL, 'http://localhost:8080/bazaar/components/1', 'COMPONENT', 'http://localhost:8080/bazaar/users/2'),
('6', '2015-10-21 10:00:00', 'CREATE', 'http://localhost:8080/bazaar/projects/2', 'PROJECT',
'http://localhost:5000/#!/projects/2', NULL, NULL, 'http://localhost:8080/bazaar/users/2'),
- ('7', '2015-10-21 07:00:00', 'CREATE', 'http://localhost:8080/bazaar/components/2', 'COMPONENT',
+ ('7', '2015-10-21 10:00:00', 'CREATE', 'http://localhost:8080/bazaar/components/2', 'COMPONENT',
'http://localhost:5000/#!/projects/2/components/2', 'http://localhost:8080/bazaar/projects/2',
'PROJECT', 'http://localhost:8080/bazaar/users/2'),
('8', '2015-10-21 11:00:00', 'CREATE', 'http://localhost:8080/bazaar/requirements/2', 'REQUIREMENT',
diff --git a/etc/ant_configuration/service.properties b/etc/ant_configuration/service.properties
index 3349308..0ad55a4 100644
--- a/etc/ant_configuration/service.properties
+++ b/etc/ant_configuration/service.properties
@@ -3,4 +3,4 @@ service.name=de.rwth.dbis.acis.activitytracker.service
service.path=de/rwth/dbis/acis/activitytracker/service
service.class=ActivityTrackerService
service.passphrase=Passphrase
-service.dependencies=
+service.dependencies=
\ No newline at end of file
diff --git a/etc/de.rwth.dbis.acis.activitytracker.service.ActivityTrackerService.properties b/etc/de.rwth.dbis.acis.activitytracker.service.ActivityTrackerService.properties
index 99228cf..bb728d9 100644
--- a/etc/de.rwth.dbis.acis.activitytracker.service.ActivityTrackerService.properties
+++ b/etc/de.rwth.dbis.acis.activitytracker.service.ActivityTrackerService.properties
@@ -3,3 +3,4 @@ dbPassword=reqbaz
dbUrl=jdbc:mysql://localhost:3306/reqbaztrack
lang=BAZAAR_LANG
country=BAZAAR_COUNTRY
+baseURL=https://localhost:8080/activities/
diff --git a/etc/ivy/ivy.xml b/etc/ivy/ivy.xml
index 6ca9af2..1acadcc 100644
--- a/etc/ivy/ivy.xml
+++ b/etc/ivy/ivy.xml
@@ -9,9 +9,11 @@
-
-
-
+
+
+
+
+
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/ActivityTrackerService.java b/src/main/de/rwth/dbis/acis/activitytracker/service/ActivityTrackerService.java
index ffa236f..a548ea0 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/ActivityTrackerService.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/ActivityTrackerService.java
@@ -1,6 +1,5 @@
package de.rwth.dbis.acis.activitytracker.service;
-import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.gson.Gson;
import com.google.gson.JsonParser;
import de.rwth.dbis.acis.activitytracker.service.dal.DALFacade;
@@ -9,6 +8,7 @@
import de.rwth.dbis.acis.activitytracker.service.dal.entities.ActivityEx;
import de.rwth.dbis.acis.activitytracker.service.dal.helpers.PageInfo;
import de.rwth.dbis.acis.activitytracker.service.dal.helpers.Pageable;
+import de.rwth.dbis.acis.activitytracker.service.dal.helpers.PaginationResult;
import de.rwth.dbis.acis.activitytracker.service.exception.ActivityTrackerException;
import de.rwth.dbis.acis.activitytracker.service.exception.ErrorCode;
import de.rwth.dbis.acis.activitytracker.service.exception.ExceptionHandler;
@@ -25,12 +25,7 @@
import i5.las2peer.restMapper.tools.XMLCheck;
import i5.las2peer.security.Context;
import io.swagger.annotations.*;
-import io.swagger.jaxrs.Reader;
-import io.swagger.models.Swagger;
-import io.swagger.util.Json;
import org.apache.commons.dbcp2.*;
-import org.apache.commons.pool2.ObjectPool;
-import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
@@ -43,9 +38,7 @@
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URI;
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -53,7 +46,6 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
-import java.util.logging.Level;
/**
* LAS2peer Activity Service
@@ -85,11 +77,11 @@ public class ActivityTrackerService extends Service {
protected String dbUrl;
protected String lang;
protected String country;
+ protected String baseURL;
private DataSource dataSource;
- // TODO: see http://layers.dbis.rwth-aachen.de/jira/browse/LAS-298
- // private final L2pLogger logger = L2pLogger.getInstance(ActivityTrackerService.class.getName());
+ private final L2pLogger logger = L2pLogger.getInstance(ActivityTrackerService.class.getName());
public ActivityTrackerService() throws Exception {
setFieldValues();
@@ -113,80 +105,102 @@ public ActivityTrackerService() throws Exception {
})
//TODO add filter
public HttpResponse getActivities(
- @ApiParam(value = "Page number", required = false) @DefaultValue("0") @QueryParam("page") int page,
- @ApiParam(value = "Elements of components by page", required = false) @DefaultValue("10") @QueryParam("per_page") int perPage,
- @ApiParam(value = "User access token", required = false) @DefaultValue("") @QueryParam("access_token") String accessToken) {
- List activities = new ArrayList();
- List activitiesEx = new ArrayList();
- DALFacade dalFacade = null;
- int getObjectCount = 0;
+ @ApiParam(value = "Before cursor pagination", required = false) @DefaultValue("-1") @QueryParam("before") int before,
+ @ApiParam(value = "After cursor pagination", required = false) @DefaultValue("-1") @QueryParam("after") int after,
+ @ApiParam(value = "Limit of elements of components", required = false) @DefaultValue("10") @QueryParam("limit") int limit,
+ @ApiParam(value = "User authorization token", required = false) @DefaultValue("") @HeaderParam("authorization") String authorizationToken) {
- PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
- cm.setMaxTotal(20);
- CloseableHttpClient httpclient = HttpClients.custom()
- .setConnectionManager(cm)
- .build();
+ DALFacade dalFacade = null;
try {
+ if (before != -1 && after != -1) {
+ ExceptionHandler.getInstance().throwException(ExceptionLocation.ACTIVITIESERVICE, ErrorCode.WRONG_PARAMETER, "both: before and after parameter not possible");
+ }
+ int cursor = before != -1 ? before : after;
+ Pageable.SortDirection sortDirection = after != -1 ? Pageable.SortDirection.ASC : Pageable.SortDirection.DESC;
+
+ PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
+ cm.setMaxTotal(20);
+ CloseableHttpClient httpclient = HttpClients.custom()
+ .setConnectionManager(cm)
+ .build();
+
dalFacade = getDBConnection();
Gson gson = new Gson();
ExecutorService executor = Executors.newCachedThreadPool();
- while (activitiesEx.size() < perPage && getObjectCount < 5) {
- Pageable pageInfo = new PageInfo(page, perPage);
+ int getObjectCount = 0;
+ PaginationResult activities;
+ List activitiesEx = new ArrayList<>();
+ Pageable pageInfo = new PageInfo(cursor, limit, "", sortDirection);
+ while (activitiesEx.size() < limit && getObjectCount < 5) {
+ pageInfo = new PageInfo(cursor, limit, "", sortDirection);
activities = dalFacade.findActivities(pageInfo);
getObjectCount++;
- page++;
- activitiesEx.addAll(getObjectBodies(httpclient, executor, accessToken, activities));
+ cursor = sortDirection == Pageable.SortDirection.ASC ? cursor + limit : cursor - limit;
+ if (cursor < 0) {
+ cursor = 0;
+ }
+ activitiesEx.addAll(getObjectBodies(httpclient, executor, authorizationToken, activities.getElements()));
}
executor.shutdown();
- if (activitiesEx.size() > perPage) {
- activitiesEx = activitiesEx.subList(0, perPage);
+ if (activitiesEx.size() > limit) {
+ activitiesEx = activitiesEx.subList(0, limit);
}
- return new HttpResponse(gson.toJson(activitiesEx), HttpURLConnection.HTTP_OK);
+ PaginationResult activitiesExResult = new PaginationResult<>(pageInfo, activitiesEx);
+
+ HttpResponse response = new HttpResponse(gson.toJson(activitiesExResult.getElements()), HttpURLConnection.HTTP_OK);
+ Map parameter = new HashMap<>();
+ parameter.put("limit", String.valueOf(limit));
+ response = this.addPaginationToHtppResponse(activitiesExResult, "", parameter, response);
+
+ return response;
+
+ } catch (ActivityTrackerException atException) {
+ return new HttpResponse(ExceptionHandler.getInstance().toJSON(atException), HttpURLConnection.HTTP_INTERNAL_ERROR);
} catch (Exception ex) {
- ActivityTrackerException atException = ExceptionHandler.getInstance().convert(ex, ExceptionLocation.ACTIVITIESERVICE, ErrorCode.UNKNOWN, "");
+ ActivityTrackerException atException = ExceptionHandler.getInstance().convert(ex, ExceptionLocation.ACTIVITIESERVICE, ErrorCode.UNKNOWN, ex.getMessage());
return new HttpResponse(ExceptionHandler.getInstance().toJSON(atException), HttpURLConnection.HTTP_INTERNAL_ERROR);
} finally {
closeDBConnection(dalFacade);
}
}
- private List getObjectBodies(CloseableHttpClient httpclient, ExecutorService executor, String accessToken,
+ private List getObjectBodies(CloseableHttpClient httpclient, ExecutorService executor, String authorizationToken,
List activities) throws Exception {
- List activitiesEx = new ArrayList();
- Map> dataFutures = new HashMap>();
- Map> parentDataFutures = new HashMap>();
- Map> userFutures = new HashMap>();
+ List activitiesEx = new ArrayList<>();
+ Map> dataFutures = new HashMap<>();
+ Map> parentDataFutures = new HashMap<>();
+ Map> userFutures = new HashMap<>();
JsonParser parser = new JsonParser();
for (int i = 0; i < activities.size(); i++) {
Activity activity = activities.get(i);
if (activity.getDataUrl() != null && !activity.getDataUrl().isEmpty()) {
URIBuilder uriBuilder = new URIBuilder(activity.getDataUrl());
- if (!accessToken.isEmpty()) {
- uriBuilder.setParameter("access_token", accessToken);
- }
URI uri = uriBuilder.build();
HttpGet httpget = new HttpGet(uri);
+ if (!authorizationToken.isEmpty()) {
+ httpget.addHeader("authorization", authorizationToken);
+ }
dataFutures.put(activity.getId(), executor.submit(new HttpRequestCallable(httpclient, httpget)));
}
if (activity.getParentDataUrl() != null && !activity.getParentDataUrl().isEmpty()) {
URIBuilder uriBuilder = new URIBuilder(activity.getParentDataUrl());
- if (!accessToken.isEmpty()) {
- uriBuilder.setParameter("access_token", accessToken);
- }
URI uri = uriBuilder.build();
HttpGet httpget = new HttpGet(uri);
+ if (!authorizationToken.isEmpty()) {
+ httpget.addHeader("authorization", authorizationToken);
+ }
parentDataFutures.put(activity.getId(), executor.submit(new HttpRequestCallable(httpclient, httpget)));
}
if (activity.getUserUrl() != null && !activity.getUserUrl().isEmpty()) {
URIBuilder uriBuilder = new URIBuilder(activity.getUserUrl());
- if (!accessToken.isEmpty()) {
- uriBuilder.setParameter("access_token", accessToken);
- }
URI uri = uriBuilder.build();
HttpGet httpget = new HttpGet(uri);
+ if (!authorizationToken.isEmpty()) {
+ httpget.addHeader("authorization", authorizationToken);
+ }
userFutures.put(activity.getId(), executor.submit(new HttpRequestCallable(httpclient, httpget)));
}
}
@@ -252,6 +266,55 @@ public HttpResponse createActivity(@ApiParam(value = "Activity" +
}
}
+ public HttpResponse addPaginationToHtppResponse(PaginationResult paginationResult, String path, Map httpParameter,
+ HttpResponse httpResponse) throws URISyntaxException {
+ httpResponse.setHeader("X-Limit", String.valueOf(paginationResult.getPageable().getLimit()));
+
+ if (paginationResult.getPageable().getSortDirection() == Pageable.SortDirection.ASC) {
+ if (paginationResult.getPrevCursor() != -1) {
+ httpResponse.setHeader("X-Cursor-Before", String.valueOf(paginationResult.getPrevCursor()));
+ }
+ if (paginationResult.getNextCursor() != -1) {
+ httpResponse.setHeader("X-Cursor-After", String.valueOf(paginationResult.getNextCursor()));
+ }
+ } else {
+ if (paginationResult.getNextCursor() != -1) {
+ httpResponse.setHeader("X-Cursor-Before", String.valueOf(paginationResult.getNextCursor()));
+ }
+ if (paginationResult.getPrevCursor() != -1) {
+ httpResponse.setHeader("X-Cursor-After", String.valueOf(paginationResult.getPrevCursor()));
+ }
+ }
+
+ URIBuilder uriBuilder = new URIBuilder(baseURL + path);
+ for (Map.Entry entry : httpParameter.entrySet()) {
+ uriBuilder.addParameter(entry.getKey(), entry.getValue());
+ }
+ String links = new String();
+ if (paginationResult.getPageable().getSortDirection() == Pageable.SortDirection.ASC) {
+ if (paginationResult.getPrevCursor() != -1) {
+ URIBuilder uriBuilderTemp = new URIBuilder(uriBuilder.build());
+ links = links.concat("<" + uriBuilderTemp.addParameter("before", String.valueOf(paginationResult.getPrevCursor())).build() + ">; rel=\"prev\",");
+ }
+ if (paginationResult.getNextCursor() != -1) {
+ URIBuilder uriBuilderTemp = new URIBuilder(uriBuilder.build());
+ links = links.concat("<" + uriBuilderTemp.addParameter("after", String.valueOf(paginationResult.getNextCursor())).build() + ">; rel=\"next\"");
+ }
+ } else {
+ if (paginationResult.getNextCursor() != -1) {
+ URIBuilder uriBuilderTemp = new URIBuilder(uriBuilder.build());
+ links = links.concat("<" + uriBuilderTemp.addParameter("before", String.valueOf(paginationResult.getNextCursor())).build() + ">; rel=\"prev\",");
+ }
+ if (paginationResult.getPrevCursor() != -1) {
+ URIBuilder uriBuilderTemp = new URIBuilder(uriBuilder.build());
+ links = links.concat("<" + uriBuilderTemp.addParameter("after", String.valueOf(paginationResult.getPrevCursor())).build() + ">; rel=\"next\"");
+ }
+ }
+
+ httpResponse.setHeader("Link", links);
+ return httpResponse;
+ }
+
// //////////////////////////////////////////////////////////////////////////////////////
// Methods required by the LAS2peer framework.
// //////////////////////////////////////////////////////////////////////////////////////
@@ -301,11 +364,14 @@ public String getRESTMapping() {
}
private static DataSource setupDataSource(String dbUrl, String dbUserName, String dbPassword) {
- ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(dbUrl, dbUserName, dbPassword);
- PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
- ObjectPool connectionPool = new GenericObjectPool<>(poolableConnectionFactory);
- poolableConnectionFactory.setPool(connectionPool);
- PoolingDataSource dataSource = new PoolingDataSource<>(connectionPool);
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName("com.mysql.jdbc.Driver");
+ dataSource.setUrl(dbUrl);
+ dataSource.setUsername(dbUserName);
+ dataSource.setPassword(dbPassword);
+ dataSource.setValidationQuery("SELECT 1;");
+ dataSource.setTestOnBorrow(true); // test each connection when borrowing from the pool with the validation query
+ dataSource.setMaxConnLifetimeMillis(1000 * 60 * 60); // max connection life time 1h. mysql drops connection after 8h.
return dataSource;
}
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/DALFacade.java b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/DALFacade.java
index a588cda..da85bfe 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/DALFacade.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/DALFacade.java
@@ -2,15 +2,14 @@
import de.rwth.dbis.acis.activitytracker.service.dal.entities.Activity;
import de.rwth.dbis.acis.activitytracker.service.dal.helpers.Pageable;
+import de.rwth.dbis.acis.activitytracker.service.dal.helpers.PaginationResult;
import de.rwth.dbis.acis.activitytracker.service.exception.ActivityTrackerException;
-import java.sql.Connection;
-import java.util.List;
public interface DALFacade {
void close();
- List findActivities(Pageable pageable) throws ActivityTrackerException;
+ PaginationResult findActivities(Pageable pageable) throws ActivityTrackerException;
Activity createActivity(Activity activity) throws ActivityTrackerException;
}
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/DALFacadeImpl.java b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/DALFacadeImpl.java
index 219bb87..2148cab 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/DALFacadeImpl.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/DALFacadeImpl.java
@@ -2,16 +2,14 @@
import de.rwth.dbis.acis.activitytracker.service.dal.entities.Activity;
import de.rwth.dbis.acis.activitytracker.service.dal.helpers.Pageable;
+import de.rwth.dbis.acis.activitytracker.service.dal.helpers.PaginationResult;
import de.rwth.dbis.acis.activitytracker.service.dal.repositories.ActivityRepository;
import de.rwth.dbis.acis.activitytracker.service.dal.repositories.ActivityRepositoryImpl;
-import de.rwth.dbis.acis.activitytracker.service.dal.transform.ActivityTransformator;
import de.rwth.dbis.acis.activitytracker.service.exception.ActivityTrackerException;
import org.jooq.*;
import org.jooq.impl.DSL;
import javax.sql.DataSource;
-import java.sql.Connection;
-import java.util.Iterator;
import java.util.List;
public class DALFacadeImpl implements DALFacade {
@@ -25,13 +23,13 @@ public DALFacadeImpl(DataSource dataSource, SQLDialect dialect) {
}
public void close() {
- dslContext.close();
+ dslContext.close();
}
@Override
- public List findActivities(Pageable pageable) throws ActivityTrackerException{
- List activities = activityRepository.findAll(pageable);
+ public PaginationResult findActivities(Pageable pageable) throws ActivityTrackerException {
+ PaginationResult activities = activityRepository.findAll(pageable);
return activities;
}
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/entities/Activity.java b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/entities/Activity.java
index 0e5a2a1..a9da9ce 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/entities/Activity.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/entities/Activity.java
@@ -4,7 +4,6 @@
public class Activity extends EntityBase {
- private final int id;
private final Date creationTime;
private final String activityAction;
private final String dataUrl;
@@ -14,10 +13,6 @@ public class Activity extends EntityBase {
private final String parentDataType;
private final String userUrl;
- @Override
- public int getId() {
- return id;
- }
public Date getCreationTime() {
return creationTime;
@@ -52,7 +47,7 @@ public String getUserUrl() {
}
protected Activity(Builder builder) {
- this.id = builder.id;
+ super(builder);
this.creationTime = builder.creationTime;
this.activityAction = builder.activityAction;
this.dataUrl = builder.dataUrl;
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/entities/EntityBase.java b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/entities/EntityBase.java
index 4c14127..0183c12 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/entities/EntityBase.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/entities/EntityBase.java
@@ -4,7 +4,20 @@
public abstract class EntityBase implements IdentifiedById {
+ private final int id;
+
+ public EntityBase(Activity.Builder builder) {
+ this.id = builder.id;
+ }
+
+ @Override
+ public int getId() {
+ return id;
+ }
+
public String toJSON() {
return new Gson().toJson(this);
}
+
+ // TODO: Add an abstract Builder to avoid import Activity.Builder here
}
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/PageInfo.java b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/PageInfo.java
index 971bc80..045ce56 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/PageInfo.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/PageInfo.java
@@ -2,33 +2,35 @@
public class PageInfo implements Pageable {
- private final int pageNumber;
- private final int pageSize;
+ private final int cursor;
+ private final int limit;
+ private final String filter;
private final SortDirection sortDirection;
- public PageInfo(int pageNumber, int pageSize) {
- this(pageNumber, pageSize, SortDirection.DEFAULT);
+ public PageInfo(int cursor, int limit, String filter) {
+ this(cursor, limit, filter, SortDirection.DEFAULT);
}
- public PageInfo(int pageNumber, int pageSize, SortDirection sortDirection) {
- this.pageNumber = pageNumber;
- this.pageSize = pageSize;
+ public PageInfo(int cursor, int limit, String filter, SortDirection sortDirection) {
+ this.cursor = cursor;
+ this.limit = limit;
+ this.filter = filter;
this.sortDirection = sortDirection;
}
@Override
- public int getOffset() {
- return pageNumber * pageSize;
+ public int getCursor() {
+ return cursor;
}
@Override
- public int getPageNumber() {
- return pageNumber;
+ public int getLimit() {
+ return limit;
}
@Override
- public int getPageSize() {
- return pageSize;
+ public String getFilter() {
+ return filter;
}
@Override
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/Pageable.java b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/Pageable.java
index e97f7c7..f5b4764 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/Pageable.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/Pageable.java
@@ -1,15 +1,16 @@
package de.rwth.dbis.acis.activitytracker.service.dal.helpers;
public interface Pageable {
- int getOffset();
+ int getCursor();
- int getPageNumber();
+ int getLimit();
- int getPageSize();
+ String getFilter();
SortDirection getSortDirection();
- public enum SortDirection {
+ enum SortDirection {
DEFAULT, ASC, DESC
}
+
}
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/PaginationResult.java b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/PaginationResult.java
new file mode 100644
index 0000000..9a34e58
--- /dev/null
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/helpers/PaginationResult.java
@@ -0,0 +1,44 @@
+package de.rwth.dbis.acis.activitytracker.service.dal.helpers;
+
+
+import de.rwth.dbis.acis.activitytracker.service.dal.entities.EntityBase;
+
+import java.util.List;
+
+public class PaginationResult {
+
+ private Pageable pageable;
+ private List elements;
+
+ public PaginationResult(Pageable pageable, List elements) {
+ this.pageable = pageable;
+ this.elements = elements;
+ }
+
+ public Pageable getPageable() {
+ return pageable;
+ }
+
+ public List getElements() {
+ return elements;
+ }
+
+ public int getPrevCursor() {
+ if (this.getElements().isEmpty()) {
+ return -1;
+ } else {
+ return this.getElements().get(0).getId();
+ }
+
+ }
+
+ public int getNextCursor() {
+ if (this.getElements().isEmpty()) {
+ return -1;
+ } else {
+ return this.getElements().get(this.getElements().size() - 1).getId();
+ }
+ }
+
+}
+
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/repositories/Repository.java b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/repositories/Repository.java
index c49d8b0..6f4647f 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/repositories/Repository.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/repositories/Repository.java
@@ -2,6 +2,7 @@
import de.rwth.dbis.acis.activitytracker.service.dal.entities.EntityBase;
import de.rwth.dbis.acis.activitytracker.service.dal.helpers.Pageable;
+import de.rwth.dbis.acis.activitytracker.service.dal.helpers.PaginationResult;
import de.rwth.dbis.acis.activitytracker.service.exception.ActivityTrackerException;
import java.util.List;
@@ -35,18 +36,19 @@ public interface Repository {
/**
* @param pageable
- * @return all the entities currently in the database
+ * @return PaginationResult with all the entities currently in the database
* @throws ActivityTrackerException
*/
- public List findAll(Pageable pageable) throws ActivityTrackerException;
+ public PaginationResult findAll(Pageable pageable) throws ActivityTrackerException;
+
/**
* @param searchTerm
* @param pageable
- * @return all the entities currently in the database matching the searchTerm
+ * @return PaginationResult with all the entities currently in the database matching the searchTerm
* @throws ActivityTrackerException
*/
- public List searchAll(String searchTerm, Pageable pageable) throws ActivityTrackerException;
+ public PaginationResult searchAll(String searchTerm, Pageable pageable) throws ActivityTrackerException;
/**
* @param id of the entity we are looking for
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/repositories/RepositoryImpl.java b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/repositories/RepositoryImpl.java
index de89856..52966e0 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/dal/repositories/RepositoryImpl.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/dal/repositories/RepositoryImpl.java
@@ -2,17 +2,20 @@
import de.rwth.dbis.acis.activitytracker.service.dal.entities.EntityBase;
import de.rwth.dbis.acis.activitytracker.service.dal.helpers.Pageable;
+import de.rwth.dbis.acis.activitytracker.service.dal.helpers.PaginationResult;
import de.rwth.dbis.acis.activitytracker.service.dal.transform.Transformator;
import de.rwth.dbis.acis.activitytracker.service.exception.ActivityTrackerException;
import de.rwth.dbis.acis.activitytracker.service.exception.ErrorCode;
import de.rwth.dbis.acis.activitytracker.service.exception.ExceptionHandler;
import de.rwth.dbis.acis.activitytracker.service.exception.ExceptionLocation;
import org.jooq.*;
+import org.jooq.Condition;
import org.jooq.exception.DataAccessException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.locks.*;
public class RepositoryImpl implements Repository {
@@ -83,7 +86,7 @@ public E delete(int id) throws ActivityTrackerException {
public List findAll() throws ActivityTrackerException {
List entries = null;
try {
- entries = new ArrayList();
+ entries = new ArrayList<>();
List queryResults = jooq.selectFrom(transformator.getTable()).fetchInto(transformator.getRecordClass());
@@ -100,63 +103,84 @@ public List findAll() throws ActivityTrackerException {
/**
* @param pageable
- * @return all the entities currently in the database
+ * @return PaginationResult with all the entities currently in the database
* @throws ActivityTrackerException
*/
@Override
- public List findAll(Pageable pageable) throws ActivityTrackerException {
- List entries = null;
+ public PaginationResult findAll(Pageable pageable) throws ActivityTrackerException {
+ PaginationResult result = null;
try {
- entries = new ArrayList();
+ List entries = new ArrayList<>();
+
+ Condition condition = transformator.getTableId().notEqual(-1);
+ if (pageable.getCursor() != -1) {
+ if (pageable.getSortDirection() == Pageable.SortDirection.ASC) {
+ condition = transformator.getTableId().greaterThan(pageable.getCursor());
+ } else {
+ condition = transformator.getTableId().lessThan(pageable.getCursor());
+ }
+ }
List queryResults = jooq.selectFrom(transformator.getTable())
+ .where(condition)
.orderBy(transformator.getSortFields(pageable.getSortDirection()))
- .limit(pageable.getPageSize())
- .offset(pageable.getOffset())
+ .limit(pageable.getLimit())
.fetchInto(transformator.getRecordClass());
for (R queryResult : queryResults) {
E entry = transformator.mapToEntity(queryResult);
entries.add(entry);
}
+
+ result = new PaginationResult<>(pageable, entries);
} catch (DataAccessException e) {
ExceptionHandler.getInstance().convertAndThrowException(e, ExceptionLocation.REPOSITORY, ErrorCode.UNKNOWN, e.getMessage());
}
- return entries;
+ return result;
}
/**
* @param searchTerm
* @param pageable
- * @return all the entities currently in the database matching the searchTerm
+ * @return PaginationResult with all the entities currently in the database matching the searchTerm
* @throws ActivityTrackerException
*/
@Override
- public List searchAll(String searchTerm, Pageable pageable) throws ActivityTrackerException {
- List entries = null;
+ public PaginationResult searchAll(String searchTerm, Pageable pageable) throws ActivityTrackerException {
+ PaginationResult result = null;
try {
- entries = new ArrayList();
+ List entries = new ArrayList<>();
+
+ Condition condition = transformator.getTableId().notEqual(-1);
+ if (pageable.getCursor() != -1) {
+ if (pageable.getSortDirection() == Pageable.SortDirection.ASC) {
+ condition = transformator.getTableId().greaterThan(pageable.getCursor());
+ } else {
+ condition = transformator.getTableId().lessThan(pageable.getCursor());
+ }
+ }
String likeExpression = "%" + searchTerm + "%";
List queryResults = jooq.selectFrom(transformator.getTable())
- .where(transformator.getSearchFields(likeExpression))
+ .where(transformator.getSearchFields(likeExpression)).and(condition)
.orderBy(transformator.getSortFields(pageable.getSortDirection()))
- .limit(pageable.getPageSize())
- .offset(pageable.getOffset())
+ .limit(pageable.getLimit())
.fetchInto(transformator.getRecordClass());
for (R queryResult : queryResults) {
E entry = transformator.mapToEntity(queryResult);
entries.add(entry);
}
+
+ result = new PaginationResult<>(pageable, entries);
} catch (ActivityTrackerException ex) {
ExceptionHandler.getInstance().convertAndThrowException(ex);
} catch (Exception e) {
ExceptionHandler.getInstance().convertAndThrowException(e, ExceptionLocation.REPOSITORY, ErrorCode.UNKNOWN);
}
- return entries;
+ return result;
}
/**
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/exception/ErrorCode.java b/src/main/de/rwth/dbis/acis/activitytracker/service/exception/ErrorCode.java
index 360ee19..052f74f 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/exception/ErrorCode.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/exception/ErrorCode.java
@@ -7,7 +7,8 @@ public enum ErrorCode {
AUTHORIZATION("003", "This user is not authorized to use this method"),
DB_COMM("004", "Error during communicating to database. Possibly wrong connection parameters"),
NOT_FOUND("005", "The item was not found"),
- NETWORK_PROBLEM("006", "Error while trying to receive activity content");
+ NETWORK_PROBLEM("006", "Error while trying to receive activity content"),
+ WRONG_PARAMETER("006", "Wrong paramer given");
private final String code;
private final String message;
diff --git a/src/main/de/rwth/dbis/acis/activitytracker/service/network/HttpRequestCallable.java b/src/main/de/rwth/dbis/acis/activitytracker/service/network/HttpRequestCallable.java
index 32a35dc..cd5663a 100644
--- a/src/main/de/rwth/dbis/acis/activitytracker/service/network/HttpRequestCallable.java
+++ b/src/main/de/rwth/dbis/acis/activitytracker/service/network/HttpRequestCallable.java
@@ -26,9 +26,6 @@ public class HttpRequestCallable implements Callable {
private final HttpContext context;
private final HttpGet httpget;
- // TODO: see http://layers.dbis.rwth-aachen.de/jira/browse/LAS-298
- //private final L2pLogger logger = L2pLogger.getInstance(ActivityTrackerService.class.getName());
-
public HttpRequestCallable(CloseableHttpClient httpClient, HttpGet httpget) {
this.httpClient = httpClient;
this.context = new BasicHttpContext();
@@ -36,7 +33,7 @@ public HttpRequestCallable(CloseableHttpClient httpClient, HttpGet httpget) {
}
@Override
- public Object call() throws Exception, ActivityTrackerException {
+ public Object call() throws Exception {
String responseBody = new String();
CloseableHttpResponse response = null;
try {
@@ -61,10 +58,12 @@ public Object call() throws Exception, ActivityTrackerException {
IOUtils.copy(entity.getContent(), writer);
responseBody = writer.toString();
}
+ } catch (ActivityTrackerException ate) {
+ throw ate;
} catch (Exception e) {
- // logger.log(Level.SEVERE, e.toString(), e);
throw ExceptionHandler.getInstance().convert(e, ExceptionLocation.NETWORK, ErrorCode.UNKNOWN, "");
- } finally {
+ }
+ finally {
if (response != null) {
response.close();
}