Skip to content

Commit 36c17ea

Browse files
committed
lazy streams with pagersplitter (#295)
1 parent 1eaee11 commit 36c17ea

File tree

3 files changed

+68
-12
lines changed

3 files changed

+68
-12
lines changed

src/main/java/org/gitlab4j/api/Pager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.List;
88
import java.util.NoSuchElementException;
99
import java.util.stream.Stream;
10+
import java.util.stream.StreamSupport;
1011

1112
import javax.ws.rs.core.MultivaluedMap;
1213
import javax.ws.rs.core.Response;
@@ -333,4 +334,12 @@ public Stream<T> stream() throws GitLabApiException {
333334

334335
return (streamBuilder.build());
335336
}
337+
338+
public Stream<T> lazyStream() {
339+
// Make sure that current page is 0, this will ensure the whole list is streamed
340+
// regardless of what page the instance is currently on.
341+
currentPage = 0;
342+
343+
return StreamSupport.stream(new PagerSpliterator<T>(this), false);
344+
}
336345
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package org.gitlab4j.api;
2+
3+
import java.util.Iterator;
4+
import java.util.Spliterator;
5+
import java.util.function.Consumer;
6+
7+
class PagerSpliterator<T> implements Spliterator<T> {
8+
9+
private Pager<T> pager;
10+
11+
private Iterator<T> elements;
12+
13+
PagerSpliterator(Pager<T> pager) {
14+
this.pager = pager;
15+
if (pager.hasNext()) {
16+
elements = this.pager.next().iterator();
17+
}
18+
}
19+
20+
@Override
21+
public boolean tryAdvance(Consumer<? super T> action) {
22+
if (elements.hasNext()) {
23+
action.accept(elements.next());
24+
return true;
25+
} else if (pager.hasNext()) {
26+
elements = pager.next().iterator();
27+
action.accept(elements.next());
28+
return true;
29+
}
30+
return false;
31+
}
32+
33+
@Override
34+
public Spliterator<T> trySplit() {
35+
return null;
36+
}
37+
38+
@Override
39+
public long estimateSize() {
40+
return pager.getTotalItems();
41+
}
42+
43+
@Override
44+
public int characteristics() {
45+
return 0;
46+
}
47+
}

src/main/java/org/gitlab4j/api/ProjectApi.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -818,15 +818,15 @@ public Project createProject(Project project, String importUrl) throws GitLabApi
818818
if (isApiVersion(ApiVersion.V3)) {
819819
boolean isPublic = (project.getPublic() != null ? project.getPublic() : project.getVisibility() == Visibility.PUBLIC);
820820
formData.withParam("public", isPublic);
821-
821+
822822
if (project.getTagList() != null && !project.getTagList().isEmpty()) {
823823
throw new IllegalArgumentException("GitLab API v3 does not support tag lists when creating projects");
824824
}
825825
} else {
826826
Visibility visibility = (project.getVisibility() != null ? project.getVisibility() :
827827
project.getPublic() == Boolean.TRUE ? Visibility.PUBLIC : null);
828828
formData.withParam("visibility", visibility);
829-
829+
830830
if (project.getTagList() != null && !project.getTagList().isEmpty()) {
831831
formData.withParam("tag_list", String.join(",", project.getTagList()));
832832
}
@@ -1057,15 +1057,15 @@ public Project updateProject(Project project) throws GitLabApiException {
10571057
formData.withParam("visibility_level", project.getVisibilityLevel());
10581058
boolean isPublic = (project.getPublic() != null ? project.getPublic() : project.getVisibility() == Visibility.PUBLIC);
10591059
formData.withParam("public", isPublic);
1060-
1060+
10611061
if (project.getTagList() != null && !project.getTagList().isEmpty()) {
10621062
throw new IllegalArgumentException("GitLab API v3 does not support tag lists when updating projects");
10631063
}
10641064
} else {
10651065
Visibility visibility = (project.getVisibility() != null ? project.getVisibility() :
10661066
project.getPublic() == Boolean.TRUE ? Visibility.PUBLIC : null);
10671067
formData.withParam("visibility", visibility);
1068-
1068+
10691069
if (project.getTagList() != null && !project.getTagList().isEmpty()) {
10701070
formData.withParam("tag_list", String.join(",", project.getTagList()));
10711071
}
@@ -1090,7 +1090,7 @@ public void deleteProject(Object projectIdOrPath) throws GitLabApiException {
10901090

10911091
/**
10921092
* Forks a project into the user namespace of the authenticated user or the one provided.
1093-
* The forking operation for a project is asynchronous and is completed in a background job.
1093+
* The forking operation for a project is asynchronous and is completed in a background job.
10941094
* The request will return immediately.
10951095
*
10961096
* <pre><code>POST /projects/:id/fork</code></pre>
@@ -1109,7 +1109,7 @@ public Project forkProject(Object projectIdOrPath, String namespace) throws GitL
11091109

11101110
/**
11111111
* Forks a project into the user namespace of the authenticated user or the one provided.
1112-
* The forking operation for a project is asynchronous and is completed in a background job.
1112+
* The forking operation for a project is asynchronous and is completed in a background job.
11131113
* The request will return immediately.
11141114
*
11151115
* <pre><code>POST /projects/:id/fork</code></pre>
@@ -1130,7 +1130,7 @@ public Project forkProject(Object projectIdOrPath, Integer namespaceId) throws G
11301130
* Create a forked from/to relation between existing projects.
11311131
*
11321132
* <pre><code>POST /projects/:id/fork/:forkFromId</code></pre>
1133-
*
1133+
*
11341134
*
11351135
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance
11361136
* @param forkedFromId the ID of the project that was forked from
@@ -1455,7 +1455,7 @@ public List<ProjectUser> getProjectUsers(Object projectIdOrPath, String search)
14551455
}
14561456

14571457
/**
1458-
* Get a Pager of project users matching the specified search string. This Pager includes
1458+
* Get a Pager of project users matching the specified search string. This Pager includes
14591459
* all project members and all users assigned to project parent groups.
14601460
*
14611461
* <pre><code>GET /projects/:id/users</code></pre>
@@ -1644,7 +1644,7 @@ public Optional<ProjectHook> getOptionalHook(Object projectIdOrPath, Integer hoo
16441644
* @return the added ProjectHook instance
16451645
* @throws GitLabApiException if any exception occurs
16461646
*/
1647-
public ProjectHook addHook(String projectName, String url, ProjectHook enabledHooks, boolean enableSslVerification, String secretToken)
1647+
public ProjectHook addHook(String projectName, String url, ProjectHook enabledHooks, boolean enableSslVerification, String secretToken)
16481648
throws GitLabApiException {
16491649

16501650
if (projectName == null) {
@@ -2266,9 +2266,9 @@ public void deletePushRules(Object projectIdOrPath) throws GitLabApiException {
22662266

22672267
/**
22682268
* Get a list of projects that were forked from the specified project.
2269-
*
2269+
*
22702270
* <pre><code>GET /projects/:id/forks</code></pre>
2271-
*
2271+
*
22722272
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
22732273
* @return a List of forked projects
22742274
* @throws GitLabApiException if any exception occurs
@@ -2382,7 +2382,7 @@ public Project transferProject(Object projectIdOrPath, String namespace) throws
23822382
}
23832383

23842384
/**
2385-
* Uploads and sets the project avatar for the specified project.
2385+
* Uploads and sets the project avatar for the specified project.
23862386
*
23872387
* <pre><code>PUT /projects/:id/uploads</code></pre>
23882388
*

0 commit comments

Comments
 (0)