Repository: syncope
Updated Branches:
  refs/heads/2_0_X fd93a2c42 -> cc8963220
  refs/heads/2_1_X eb522f556 -> 34bb49ed6
  refs/heads/master c3ce309a1 -> fa3b769df


[SYNCOPE-1287] Pagination for Remediations too


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/34bb49ed
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/34bb49ed
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/34bb49ed

Branch: refs/heads/2_1_X
Commit: 34bb49ed6bcd59d1303f10e774e17835ef8d99bf
Parents: eb522f5
Author: Francesco Chicchiriccò <ilgro...@apache.org>
Authored: Thu Jul 12 14:05:23 2018 +0200
Committer: Francesco Chicchiriccò <ilgro...@apache.org>
Committed: Thu Jul 12 14:05:23 2018 +0200

----------------------------------------------------------------------
 .../approvals/ApprovalDirectoryPanel.java       |  4 --
 .../ConnInstanceHistoryConfDirectoryPanel.java  |  7 +--
 .../panels/RemediationDirectoryPanel.java       | 12 ++--
 .../ResourceHistoryConfDirectoryPanel.java      |  9 +--
 .../console/rest/RemediationRestClient.java     | 14 ++++-
 .../console/tasks/ExecutionsDirectoryPanel.java |  9 +--
 .../console/tasks/TaskDirectoryPanel.java       |  8 ---
 .../console/widgets/RemediationsWidget.java     | 15 +++--
 .../common/rest/api/beans/RemediationQuery.java | 32 +++++++++++
 .../rest/api/service/RemediationService.java    |  7 ++-
 .../syncope/core/logic/RemediationLogic.java    | 15 ++++-
 .../persistence/api/dao/RemediationDAO.java     |  5 +-
 .../persistence/jpa/dao/JPARemediationDAO.java  | 58 +++++++++++++++++++-
 .../persistence/jpa/inner/RemediationTest.java  |  3 +-
 .../cxf/service/RemediationServiceImpl.java     |  9 ++-
 .../apache/syncope/fit/core/PullTaskITCase.java |  4 +-
 16 files changed, 151 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
index 65e7124..252ccf6 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/approvals/ApprovalDirectoryPanel.java
@@ -32,7 +32,6 @@ import 
org.apache.syncope.client.console.commons.DirectoryDataProvider;
 import org.apache.syncope.client.console.panels.DirectoryPanel;
 import org.apache.syncope.client.console.rest.UserWorkflowRestClient;
 import 
org.apache.syncope.client.console.approvals.ApprovalDirectoryPanel.ApprovalProvider;
-import 
org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.layout.FormLayoutInfoUtils;
 import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
 import org.apache.syncope.client.console.pages.BasePage;
@@ -253,15 +252,12 @@ public class ApprovalDirectoryPanel
 
         private static final long serialVersionUID = -2311716167583335852L;
 
-        private final SortableDataProviderComparator<WorkflowFormTO> 
comparator;
-
         private final UserWorkflowRestClient restClient = new 
UserWorkflowRestClient();
 
         public ApprovalProvider(final int paginatorRows) {
             super(paginatorRows);
 
             setSort("createTime", SortOrder.ASCENDING);
-            comparator = new SortableDataProviderComparator<>(this);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
index 2e836ba..ab053bf 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ConnInstanceHistoryConfDirectoryPanel.java
@@ -213,14 +213,10 @@ public abstract class 
ConnInstanceHistoryConfDirectoryPanel extends DirectoryPan
         public Iterator<ConnInstanceHistoryConfTO> iterator(final long first, 
final long count) {
             final List<ConnInstanceHistoryConfTO> configurations = 
restClient.list(entityKey);
 
-            Collections.sort(configurations, getComparator());
+            Collections.sort(configurations, comparator);
             return configurations.iterator();
         }
 
-        public SortableDataProviderComparator<ConnInstanceHistoryConfTO> 
getComparator() {
-            return comparator;
-        }
-
         @Override
         public long size() {
             return restClient.list(entityKey).size();
@@ -230,6 +226,5 @@ public abstract class ConnInstanceHistoryConfDirectoryPanel 
extends DirectoryPan
         public IModel<ConnInstanceHistoryConfTO> model(final 
ConnInstanceHistoryConfTO object) {
             return new CompoundPropertyModel<>(object);
         }
-
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/client/console/src/main/java/org/apache/syncope/client/console/panels/RemediationDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/RemediationDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/RemediationDirectoryPanel.java
index 242c422..1e34454 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/RemediationDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/RemediationDirectoryPanel.java
@@ -30,7 +30,6 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.DirectoryDataProvider;
-import 
org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.layout.AnyObjectFormLayoutInfo;
 import org.apache.syncope.client.console.layout.FormLayoutInfoUtils;
 import org.apache.syncope.client.console.layout.GroupFormLayoutInfo;
@@ -311,26 +310,23 @@ public class RemediationDirectoryPanel
 
         private static final long serialVersionUID = -2311716167583335852L;
 
-        private final SortableDataProviderComparator<RemediationTO> comparator;
-
         private final RemediationRestClient restClient = new 
RemediationRestClient();
 
         public RemediationProvider(final int paginatorRows) {
             super(paginatorRows);
+
             setSort("instant", SortOrder.ASCENDING);
-            this.comparator = new SortableDataProviderComparator<>(this);
         }
 
         @Override
         public Iterator<RemediationTO> iterator(final long first, final long 
count) {
-            final List<RemediationTO> list = restClient.getRemediations();
-            Collections.sort(list, comparator);
-            return list.subList((int) first, (int) first + (int) 
count).iterator();
+            int page = ((int) first / paginatorRows);
+            return restClient.getRemediations((page < 0 ? 0 : page) + 1, 
paginatorRows, getSort()).iterator();
         }
 
         @Override
         public long size() {
-            return restClient.getRemediations().size();
+            return restClient.countRemediations();
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
index c964c29..09a1cf9 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/panels/ResourceHistoryConfDirectoryPanel.java
@@ -206,7 +206,7 @@ public abstract class ResourceHistoryConfDirectoryPanel 
extends DirectoryPanel<
         public RHConfProvider(final int paginatorRows) {
             super(paginatorRows);
 
-            setSort("creation", SortOrder.ASCENDING); // sort by 'creation' 
property
+            setSort("creation", SortOrder.ASCENDING);
             comparator = new SortableDataProviderComparator<>(this);
         }
 
@@ -214,14 +214,10 @@ public abstract class ResourceHistoryConfDirectoryPanel 
extends DirectoryPanel<
         public Iterator<ResourceHistoryConfTO> iterator(final long first, 
final long count) {
             final List<ResourceHistoryConfTO> configurations = 
restClient.list(entityKey);
 
-            Collections.sort(configurations, getComparator());
+            Collections.sort(configurations, comparator);
             return configurations.iterator();
         }
 
-        public SortableDataProviderComparator<ResourceHistoryConfTO> 
getComparator() {
-            return comparator;
-        }
-
         @Override
         public long size() {
             return restClient.list(entityKey).size();
@@ -231,6 +227,5 @@ public abstract class ResourceHistoryConfDirectoryPanel 
extends DirectoryPanel<
         public IModel<ResourceHistoryConfTO> model(final ResourceHistoryConfTO 
object) {
             return new CompoundPropertyModel<>(object);
         }
-
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/client/console/src/main/java/org/apache/syncope/client/console/rest/RemediationRestClient.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/rest/RemediationRestClient.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/rest/RemediationRestClient.java
index a5023e5..381ee03 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/rest/RemediationRestClient.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/rest/RemediationRestClient.java
@@ -25,14 +25,24 @@ import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.to.AnyTO;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.RemediationTO;
+import org.apache.syncope.common.rest.api.beans.RemediationQuery;
 import org.apache.syncope.common.rest.api.service.RemediationService;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
 
 public class RemediationRestClient extends BaseRestClient {
 
     private static final long serialVersionUID = -7033745375669316378L;
 
-    public List<RemediationTO> getRemediations() {
-        return getService(RemediationService.class).list();
+    public int countRemediations() {
+        return getService(RemediationService.class).
+                list(new RemediationQuery.Builder().page(1).size(1).build()).
+                getTotalCount();
+    }
+
+    public List<RemediationTO> getRemediations(final int page, final int size, 
final SortParam<String> sort) {
+        return getService(RemediationService.class).
+                list(new 
RemediationQuery.Builder().page(page).size(size).orderBy(toOrderBy(sort)).build()).
+                getResult();
     }
 
     public RemediationTO getRemediation(final String key) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
index f920381..1494e34 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
@@ -25,7 +25,6 @@ import java.util.List;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.commons.DirectoryDataProvider;
-import 
org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.panels.DirectoryPanel;
 import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
@@ -168,21 +167,15 @@ public abstract class ExecutionsDirectoryPanel
 
         private static final long serialVersionUID = 8943636537120648961L;
 
-        private final SortableDataProviderComparator<ExecTO> comparator;
-
         private final String taskKey;
 
         public ExecProvider(final String taskKey, final int paginatorRows) {
             super(paginatorRows);
+
             this.taskKey = taskKey;
-            comparator = new SortableDataProviderComparator<>(this);
             setSort("end", SortOrder.DESCENDING);
         }
 
-        public SortableDataProviderComparator<ExecTO> getComparator() {
-            return comparator;
-        }
-
         @Override
         public Iterator<ExecTO> iterator(final long first, final long count) {
             int page = ((int) first / paginatorRows);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
index 56a17a9..35aabff 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/tasks/TaskDirectoryPanel.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.client.console.tasks;
 
 import org.apache.syncope.client.console.commons.DirectoryDataProvider;
-import 
org.apache.syncope.client.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.client.console.commons.TaskDataProvider;
 import org.apache.syncope.client.console.panels.DirectoryPanel;
 import org.apache.syncope.client.console.panels.AjaxDataTablePanel;
@@ -70,22 +69,15 @@ public abstract class TaskDirectoryPanel<T extends TaskTO>
 
         private static final long serialVersionUID = -20112718133295756L;
 
-        private final SortableDataProviderComparator<T> comparator;
-
         private final TaskType id;
 
         public TasksProvider(final int paginatorRows, final TaskType id) {
             super(paginatorRows);
 
             setSort("key", SortOrder.ASCENDING);
-            this.comparator = new SortableDataProviderComparator<>(this);
             this.id = id;
         }
 
-        public SortableDataProviderComparator<T> getComparator() {
-            return comparator;
-        }
-
         @Override
         public long size() {
             return restClient.count(id);

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/client/console/src/main/java/org/apache/syncope/client/console/widgets/RemediationsWidget.java
----------------------------------------------------------------------
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/widgets/RemediationsWidget.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/widgets/RemediationsWidget.java
index 79e0ec4..9e888db 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/widgets/RemediationsWidget.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/widgets/RemediationsWidget.java
@@ -22,9 +22,7 @@ import 
de.agilecoders.wicket.core.markup.html.bootstrap.image.Icon;
 import 
de.agilecoders.wicket.extensions.markup.html.bootstrap.icon.FontAwesomeIconTypeBuilder;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
-import java.util.stream.Collectors;
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.pages.Remediations;
@@ -35,6 +33,7 @@ import 
org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import 
org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy;
+import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.link.AbstractLink;
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;
@@ -85,6 +84,14 @@ public class RemediationsWidget extends 
AlertWidget<RemediationTO> {
     }
 
     @Override
+    protected int getLatestAlertsSize() {
+        return 
SyncopeConsoleSession.get().owns(StandardEntitlement.REMEDIATION_LIST)
+                && 
SyncopeConsoleSession.get().owns(StandardEntitlement.REMEDIATION_READ)
+                ? restClient.countRemediations()
+                : 0;
+    }
+
+    @Override
     protected IModel<List<RemediationTO>> getLatestAlerts() {
         return new ListModel<RemediationTO>() {
 
@@ -96,9 +103,7 @@ public class RemediationsWidget extends 
AlertWidget<RemediationTO> {
                 if 
(SyncopeConsoleSession.get().owns(StandardEntitlement.REMEDIATION_LIST)
                         && 
SyncopeConsoleSession.get().owns(StandardEntitlement.REMEDIATION_READ)) {
 
-                    updatedRemediations = 
restClient.getRemediations().stream().
-                            
sorted(Comparator.comparing(RemediationTO::getInstant)).
-                            collect(Collectors.toList());
+                    updatedRemediations = restClient.getRemediations(1, 
MAX_SIZE, new SortParam<>("instant", true));
                 } else {
                     updatedRemediations = 
Collections.<RemediationTO>emptyList();
                 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/RemediationQuery.java
----------------------------------------------------------------------
diff --git 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/RemediationQuery.java
 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/RemediationQuery.java
new file mode 100644
index 0000000..f70858c
--- /dev/null
+++ 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/beans/RemediationQuery.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.common.rest.api.beans;
+
+public class RemediationQuery extends AbstractQuery {
+
+    private static final long serialVersionUID = 4000880445378096031L;
+
+    public static class Builder extends 
AbstractQuery.Builder<RemediationQuery, Builder> {
+
+        @Override
+        protected RemediationQuery newInstance() {
+            return new RemediationQuery();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RemediationService.java
----------------------------------------------------------------------
diff --git 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RemediationService.java
 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RemediationService.java
index 0b4a704..09d2b22 100644
--- 
a/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RemediationService.java
+++ 
b/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RemediationService.java
@@ -28,8 +28,8 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.security.SecurityRequirement;
 import io.swagger.v3.oas.annotations.security.SecurityRequirements;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import java.util.List;
 import javax.validation.constraints.NotNull;
+import javax.ws.rs.BeanParam;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
@@ -44,9 +44,11 @@ import javax.ws.rs.core.Response;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.RemediationTO;
 import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.beans.RemediationQuery;
 
 /**
  * REST operations for remediations.
@@ -61,11 +63,12 @@ public interface RemediationService extends JAXRSService {
     /**
      * Returns a list of all remediations.
      *
+     * @param query query conditions
      * @return list of all remediations.
      */
     @GET
     @Produces({ MediaType.APPLICATION_JSON, SyncopeConstants.APPLICATION_YAML, 
MediaType.APPLICATION_XML })
-    List<RemediationTO> list();
+    PagedResult<RemediationTO> list(@BeanParam RemediationQuery query);
 
     /**
      * Returns remediation with matching key.

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/core/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
----------------------------------------------------------------------
diff --git 
a/core/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java 
b/core/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
index 67257cf..19f6c8f 100644
--- 
a/core/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
+++ 
b/core/logic/src/main/java/org/apache/syncope/core/logic/RemediationLogic.java
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.patch.AnyObjectPatch;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.patch.GroupPatch;
@@ -36,6 +37,7 @@ import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.RemediationDAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.Remediation;
 import org.apache.syncope.core.provisioning.api.data.RemediationDataBinder;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -63,8 +65,17 @@ public class RemediationLogic extends 
AbstractTransactionalLogic<RemediationTO>
 
     @PreAuthorize("hasRole('" + StandardEntitlement.REMEDIATION_LIST + "')")
     @Transactional(readOnly = true)
-    public List<RemediationTO> list() {
-        return 
remediationDAO.findAll().stream().map(binder::getRemediationTO).collect(Collectors.toList());
+    public Pair<Integer, List<RemediationTO>> list(
+            final int page,
+            final int size,
+            final List<OrderByClause> orderByClauses) {
+
+        int count = remediationDAO.count();
+
+        List<RemediationTO> result = remediationDAO.findAll(page, size, 
orderByClauses).stream().
+                map(binder::getRemediationTO).collect(Collectors.toList());
+
+        return Pair.of(count, result);
     }
 
     @PreAuthorize("hasRole('" + StandardEntitlement.REMEDIATION_READ + "')")

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java
 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java
index 368f427..73216b3 100644
--- 
a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java
+++ 
b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/RemediationDAO.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Remediation;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
@@ -31,7 +32,9 @@ public interface RemediationDAO extends DAO<Remediation> {
 
     List<Remediation> findByPullTask(PullTask pullTask);
 
-    List<Remediation> findAll();
+    int count();
+
+    List<Remediation> findAll(int page, int itemsPerPage, List<OrderByClause> 
orderByClauses);
 
     Remediation save(Remediation remediation);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARemediationDAO.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARemediationDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARemediationDAO.java
index fa7a044..c0309b3 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARemediationDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPARemediationDAO.java
@@ -18,14 +18,18 @@
  */
 package org.apache.syncope.core.persistence.jpa.dao;
 
+import java.lang.reflect.Field;
 import java.util.List;
+import javax.persistence.Query;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.core.persistence.api.dao.RemediationDAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.Remediation;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
 import org.apache.syncope.core.persistence.jpa.entity.JPARemediation;
 import org.springframework.stereotype.Repository;
+import org.springframework.util.ReflectionUtils;
 
 @Repository
 public class JPARemediationDAO extends AbstractDAO<Remediation> implements 
RemediationDAO {
@@ -54,9 +58,57 @@ public class JPARemediationDAO extends 
AbstractDAO<Remediation> implements Remed
     }
 
     @Override
-    public List<Remediation> findAll() {
-        TypedQuery<Remediation> query = entityManager().createQuery(
-                "SELECT e FROM " + JPARemediation.class.getSimpleName() + " e 
", Remediation.class);
+    public int count() {
+        Query query = entityManager().createNativeQuery("SELECT COUNT(id) FROM 
" + JPARemediation.TABLE);
+        return ((Number) query.getSingleResult()).intValue();
+    }
+
+    @Override
+    public List<Remediation> findAll(
+            final int page,
+            final int itemsPerPage,
+            final List<OrderByClause> orderByClauses) {
+
+        StringBuilder queryString = new StringBuilder(
+                "SELECT e FROM " + JPARemediation.class.getSimpleName() + " 
e");
+
+        if (!orderByClauses.isEmpty()) {
+            queryString.append(" ORDER BY ");
+            orderByClauses.forEach(clause -> {
+                String field = clause.getField().trim();
+                boolean ack = true;
+                if ("resource".equals(field)) {
+                    queryString.append("e.pullTask.resource.id");
+                } else {
+                    Field beanField = 
ReflectionUtils.findField(JPARemediation.class, field);
+                    if (beanField == null) {
+                        ack = false;
+                        LOG.warn("Remediation sort request by {}: unsupported, 
ignoring", field);
+                    } else {
+                        queryString.append("e.").append(field);
+                    }
+                }
+                if (ack) {
+                    if (clause.getDirection() == OrderByClause.Direction.ASC) {
+                        queryString.append(" ASC");
+                    } else {
+                        queryString.append(" DESC");
+                    }
+                    queryString.append(',');
+                }
+            });
+
+            queryString.deleteCharAt(queryString.length() - 1);
+        }
+
+        TypedQuery<Remediation> query = 
entityManager().createQuery(queryString.toString(), Remediation.class);
+
+        query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
+
+        if (itemsPerPage > 0) {
+            query.setMaxResults(itemsPerPage);
+        }
+
         return query.getResultList();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
index 34b26eb..fe4e571 100644
--- 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Set;
@@ -54,7 +55,7 @@ public class RemediationTest extends AbstractTest {
 
     @Test
     public void findAll() {
-        List<Remediation> remediations = remediationDAO.findAll();
+        List<Remediation> remediations = remediationDAO.findAll(1, 1, 
Collections.emptyList());
         assertTrue(remediations.isEmpty());
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
----------------------------------------------------------------------
diff --git 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
index d7f6b6e..d4a402d 100644
--- 
a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
+++ 
b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/RemediationServiceImpl.java
@@ -21,10 +21,13 @@ package org.apache.syncope.core.rest.cxf.service;
 import java.util.Date;
 import java.util.List;
 import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.PagedResult;
 import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.RemediationTO;
+import org.apache.syncope.common.rest.api.beans.RemediationQuery;
 import org.apache.syncope.common.rest.api.service.RemediationService;
 import org.apache.syncope.core.logic.RemediationLogic;
 import org.apache.syncope.core.persistence.api.dao.AnyDAO;
@@ -51,8 +54,10 @@ public class RemediationServiceImpl extends 
AbstractServiceImpl implements Remed
     private AnyObjectDAO anyObjectDAO;
 
     @Override
-    public List<RemediationTO> list() {
-        return logic.list();
+    public PagedResult<RemediationTO> list(final RemediationQuery query) {
+        Pair<Integer, List<RemediationTO>> result = logic.list(
+                query.getPage(), query.getSize(), 
getOrderByClauses(query.getOrderBy()));
+        return buildPagedResult(result.getRight(), query.getPage(), 
query.getSize(), result.getLeft());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/34bb49ed/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
----------------------------------------------------------------------
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
index 2825f00..7354a1c 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java
@@ -84,6 +84,7 @@ import org.apache.syncope.common.lib.types.ResourceOperation;
 import org.apache.syncope.common.lib.types.TaskType;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 import org.apache.syncope.common.rest.api.beans.AnyQuery;
+import org.apache.syncope.common.rest.api.beans.RemediationQuery;
 import org.apache.syncope.common.rest.api.beans.TaskQuery;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
 import org.apache.syncope.common.rest.api.service.TaskService;
@@ -710,7 +711,8 @@ public class PullTaskITCase extends AbstractTaskITCase {
             }
 
             // 3b. remediation was created
-            Optional<RemediationTO> remediation = 
remediationService.list().stream().
+            Optional<RemediationTO> remediation = remediationService.list(
+                    new 
RemediationQuery.Builder().page(1).size(1000).build()).getResult().stream().
                     filter(r -> 
"uid=pullFromLDAP,ou=People,o=isp".equalsIgnoreCase(r.getRemoteName())).
                     findFirst();
             assertTrue(remediation.isPresent());

Reply via email to