Skip to content

Commit 449fc2b

Browse files
author
Zhen Li
committed
Simplify bookmark impl by exposing internal values
This makes serialization of the bookmark easier to end users. End users could serialize and deserialize bookmark in whatever way they like using `Set<String> values`
1 parent f5d21ff commit 449fc2b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+261
-352
lines changed

driver/src/main/java/org/neo4j/driver/Bookmark.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@
1818
*/
1919
package org.neo4j.driver;
2020

21-
import java.io.Serializable;
21+
import java.util.Arrays;
22+
import java.util.Set;
23+
24+
import org.neo4j.driver.internal.InternalBookmark;
2225

2326
/**
2427
* Causal chaining is carried out by passing bookmarks between transactions.
@@ -31,6 +34,50 @@
3134
*
3235
* To opt out of this mechanism for unrelated units of work, applications can use multiple sessions.
3336
*/
34-
public interface Bookmark extends Serializable
37+
public interface Bookmark
3538
{
39+
/**
40+
* Returns a read-only set of bookmark strings that this bookmark instance identifies.
41+
* This method shall only be used to serialize bookmarks.
42+
* @return a read-only set of bookmark strings that this bookmark instance identifies.
43+
*/
44+
Set<String> values();
45+
46+
/**
47+
* Reconstruct bookmark from de-serialized bookmarks string values.
48+
* This method shall not be used to create non-existing bookmarks from random string values.
49+
* To create a bookmark from two and more existing bookmarks, using {@link this#merge(Bookmark...)} and {@link this#merge(Iterable)} instead.
50+
* @param values values obtained from a previous bookmark.
51+
* @return A bookmark.
52+
*/
53+
static Bookmark parse( Set<String> values )
54+
{
55+
return InternalBookmark.parse( values );
56+
}
57+
58+
/**
59+
* Return true if the bookmark is empty.
60+
* @return true if the bookmark is empty.
61+
*/
62+
boolean isEmpty();
63+
64+
/**
65+
* Merge more than one bookmarks together into one bookmark.
66+
* @param bookmarks bookmarks to merge
67+
* @return Merged single bookmark.
68+
*/
69+
static Bookmark merge( Bookmark... bookmarks )
70+
{
71+
return merge( Arrays.asList( bookmarks ) );
72+
}
73+
74+
/**
75+
* Merge more than one bookmarks together into one bookmark.
76+
* @param bookmarks bookmarks to merge
77+
* @return Merged singled bookmark.
78+
*/
79+
static Bookmark merge( Iterable<Bookmark> bookmarks )
80+
{
81+
return InternalBookmark.from( bookmarks );
82+
}
3683
}

driver/src/main/java/org/neo4j/driver/internal/BookmarkHolder.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,24 @@
1818
*/
1919
package org.neo4j.driver.internal;
2020

21+
import org.neo4j.driver.Bookmark;
22+
2123
public interface BookmarkHolder
2224
{
23-
InternalBookmark getBookmark();
25+
Bookmark getBookmark();
2426

25-
void setBookmark( InternalBookmark bookmark );
27+
void setBookmark( Bookmark bookmark );
2628

2729
BookmarkHolder NO_OP = new BookmarkHolder()
2830
{
2931
@Override
30-
public InternalBookmark getBookmark()
32+
public Bookmark getBookmark()
3133
{
3234
return InternalBookmark.empty();
3335
}
3436

3537
@Override
36-
public void setBookmark( InternalBookmark bookmark )
38+
public void setBookmark( Bookmark bookmark )
3739
{
3840
}
3941
};

driver/src/main/java/org/neo4j/driver/internal/DefaultBookmarkHolder.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,33 @@
1818
*/
1919
package org.neo4j.driver.internal;
2020

21+
import org.neo4j.driver.Bookmark;
22+
2123
/**
2224
* @since 2.0
2325
*/
2426
public class DefaultBookmarkHolder implements BookmarkHolder
2527
{
26-
private volatile InternalBookmark bookmark;
28+
private volatile Bookmark bookmark;
2729

2830
public DefaultBookmarkHolder()
2931
{
3032
this( InternalBookmark.empty() );
3133
}
3234

33-
public DefaultBookmarkHolder( InternalBookmark bookmark )
35+
public DefaultBookmarkHolder( Bookmark bookmark )
3436
{
3537
this.bookmark = bookmark;
3638
}
3739

3840
@Override
39-
public InternalBookmark getBookmark()
41+
public Bookmark getBookmark()
4042
{
4143
return bookmark;
4244
}
4345

4446
@Override
45-
public void setBookmark( InternalBookmark bookmark )
47+
public void setBookmark( Bookmark bookmark )
4648
{
4749
if ( bookmark != null && !bookmark.isEmpty() )
4850
{

driver/src/main/java/org/neo4j/driver/internal/InternalBookmark.java

Lines changed: 27 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,58 +18,48 @@
1818
*/
1919
package org.neo4j.driver.internal;
2020

21-
import java.io.Serializable;
22-
import java.util.Collection;
2321
import java.util.Collections;
2422
import java.util.HashSet;
2523
import java.util.Objects;
2624
import java.util.Set;
2725

2826
import org.neo4j.driver.Bookmark;
27+
import org.neo4j.driver.internal.util.Iterables;
2928

3029
import static java.util.Objects.requireNonNull;
3130

3231
public final class InternalBookmark implements Bookmark
3332
{
3433
private static final InternalBookmark EMPTY = new InternalBookmark( Collections.emptySet() );
3534

36-
private final Collection<String> values;
35+
private final Set<String> values;
3736

38-
private InternalBookmark( Collection<String> values )
37+
private InternalBookmark( Set<String> values )
3938
{
4039
requireNonNull( values );
41-
if ( !(values instanceof Serializable) )
42-
{
43-
// The Collection interface does not enforce Serializable, but all built-in Collection implementations actually are Serializable.
44-
// This check ensures that we always provide values using these java built-in Collection objects.
45-
throw new IllegalArgumentException( "The bookmark value should only be of Java built-in types such as ArrayList, HashSet which are serializable." );
46-
}
4740
this.values = values;
4841
}
4942

50-
public static InternalBookmark empty()
43+
public static Bookmark empty()
5144
{
5245
return EMPTY;
5346
}
5447

55-
public static InternalBookmark from( Iterable<Bookmark> bookmarks )
48+
public static Bookmark from( Iterable<Bookmark> bookmarks )
5649
{
5750
if ( bookmarks == null )
5851
{
5952
return empty();
6053
}
6154

62-
if ( bookmarks instanceof Collection )
55+
int size = Iterables.count( bookmarks );
56+
if ( size == 0 )
6357
{
64-
int size = ((Collection) bookmarks).size();
65-
if ( size == 0 )
66-
{
67-
return empty();
68-
}
69-
else if ( size == 1 )
70-
{
71-
return from( bookmarks.iterator().next() );
72-
}
58+
return empty();
59+
}
60+
else if ( size == 1 )
61+
{
62+
return from( bookmarks.iterator().next() );
7363
}
7464

7565
Set<String> newValues = new HashSet<>();
@@ -79,43 +69,37 @@ else if ( size == 1 )
7969
{
8070
continue; // skip any null bookmark value
8171
}
82-
assertInternalBookmark( value );
83-
newValues.addAll( ((InternalBookmark) value).values );
72+
newValues.addAll( value.values() );
8473
}
8574
return new InternalBookmark( newValues );
8675
}
8776

88-
private static InternalBookmark from( Bookmark bookmark )
77+
private static Bookmark from( Bookmark bookmark )
8978
{
9079
if ( bookmark == null )
9180
{
9281
return empty();
9382
}
94-
assertInternalBookmark( bookmark );
95-
return (InternalBookmark) bookmark; // we directly return the same bookmark back
83+
// it is safe to return the given bookmark as bookmarks values can not be modified once it is created.
84+
return bookmark;
9685
}
9786

98-
private static void assertInternalBookmark( Bookmark bookmark )
99-
{
100-
if ( !(bookmark instanceof InternalBookmark) )
101-
{
102-
throw new IllegalArgumentException( String.format( "Received bookmark '%s' is not generated by a driver session.", bookmark ) );
103-
}
104-
}
105-
106-
public static InternalBookmark parse( String value )
87+
/**
88+
* Used to extract bookmark from metadata from server.
89+
*/
90+
public static Bookmark parse( String value )
10791
{
10892
if ( value == null )
10993
{
11094
return empty();
11195
}
112-
return parse( Collections.singletonList( value ) );
96+
return new InternalBookmark( Collections.singleton( value ) );
11397
}
11498

11599
/**
116-
* Used for test only
100+
* Used to reconstruct bookmark from values.
117101
*/
118-
public static InternalBookmark parse( Collection<String> values )
102+
public static Bookmark parse( Set<String> values )
119103
{
120104
if ( values == null )
121105
{
@@ -124,14 +108,16 @@ public static InternalBookmark parse( Collection<String> values )
124108
return new InternalBookmark( values );
125109
}
126110

111+
@Override
127112
public boolean isEmpty()
128113
{
129114
return values.isEmpty();
130115
}
131116

132-
public Iterable<String> values()
117+
@Override
118+
public Set<String> values()
133119
{
134-
return values;
120+
return Collections.unmodifiableSet( values );
135121
}
136122

137123
@Override

driver/src/main/java/org/neo4j/driver/internal/ReadOnlyBookmarkHolder.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,28 @@
1818
*/
1919
package org.neo4j.driver.internal;
2020

21+
import org.neo4j.driver.Bookmark;
22+
2123
/**
2224
* @since 2.0
2325
*/
2426
public class ReadOnlyBookmarkHolder implements BookmarkHolder
2527
{
26-
private final InternalBookmark bookmark;
28+
private final Bookmark bookmark;
2729

28-
public ReadOnlyBookmarkHolder( InternalBookmark bookmark )
30+
public ReadOnlyBookmarkHolder( Bookmark bookmark )
2931
{
3032
this.bookmark = bookmark;
3133
}
3234

3335
@Override
34-
public InternalBookmark getBookmark()
36+
public Bookmark getBookmark()
3537
{
3638
return bookmark;
3739
}
3840

3941
@Override
40-
public void setBookmark( InternalBookmark bookmark )
42+
public void setBookmark( Bookmark bookmark )
4143
{
4244
// NO_OP
4345
}

driver/src/main/java/org/neo4j/driver/internal/async/ConnectionContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
package org.neo4j.driver.internal.async;
2020

2121
import org.neo4j.driver.AccessMode;
22+
import org.neo4j.driver.Bookmark;
2223
import org.neo4j.driver.internal.DatabaseName;
23-
import org.neo4j.driver.internal.InternalBookmark;
2424

2525
public interface ConnectionContext
2626
{
2727
DatabaseName databaseName();
2828

2929
AccessMode mode();
3030

31-
InternalBookmark rediscoveryBookmark();
31+
Bookmark rediscoveryBookmark();
3232
}

driver/src/main/java/org/neo4j/driver/internal/async/ExplicitTransaction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@
2222
import java.util.concurrent.CompletionStage;
2323
import java.util.function.BiFunction;
2424

25+
import org.neo4j.driver.Bookmark;
2526
import org.neo4j.driver.Session;
2627
import org.neo4j.driver.Statement;
2728
import org.neo4j.driver.TransactionConfig;
2829
import org.neo4j.driver.async.StatementResultCursor;
2930
import org.neo4j.driver.exceptions.ClientException;
3031
import org.neo4j.driver.internal.BookmarkHolder;
31-
import org.neo4j.driver.internal.InternalBookmark;
3232
import org.neo4j.driver.internal.cursor.AsyncStatementResultCursor;
3333
import org.neo4j.driver.internal.cursor.RxStatementResultCursor;
3434
import org.neo4j.driver.internal.messaging.BoltProtocol;
@@ -75,7 +75,7 @@ public ExplicitTransaction( Connection connection, BookmarkHolder bookmarkHolder
7575
this.fetchSize = fetchSize;
7676
}
7777

78-
public CompletionStage<ExplicitTransaction> beginAsync( InternalBookmark initialBookmark, TransactionConfig config )
78+
public CompletionStage<ExplicitTransaction> beginAsync( Bookmark initialBookmark, TransactionConfig config )
7979
{
8080
return protocol.beginTransaction( connection, initialBookmark, config )
8181
.handle( ( ignore, beginError ) ->

driver/src/main/java/org/neo4j/driver/internal/async/ImmutableConnectionContext.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
package org.neo4j.driver.internal.async;
2020

2121
import org.neo4j.driver.AccessMode;
22+
import org.neo4j.driver.Bookmark;
2223
import org.neo4j.driver.internal.DatabaseName;
23-
import org.neo4j.driver.internal.InternalBookmark;
2424
import org.neo4j.driver.internal.spi.Connection;
2525

2626
import static org.neo4j.driver.internal.DatabaseNameUtil.defaultDatabase;
@@ -35,9 +35,9 @@ public class ImmutableConnectionContext implements ConnectionContext
3535

3636
private final DatabaseName databaseName;
3737
private final AccessMode mode;
38-
private final InternalBookmark rediscoveryBookmark;
38+
private final Bookmark rediscoveryBookmark;
3939

40-
public ImmutableConnectionContext( DatabaseName databaseName, InternalBookmark bookmark, AccessMode mode )
40+
public ImmutableConnectionContext( DatabaseName databaseName, Bookmark bookmark, AccessMode mode )
4141
{
4242
this.databaseName = databaseName;
4343
this.rediscoveryBookmark = bookmark;
@@ -57,7 +57,7 @@ public AccessMode mode()
5757
}
5858

5959
@Override
60-
public InternalBookmark rediscoveryBookmark()
60+
public Bookmark rediscoveryBookmark()
6161
{
6262
return rediscoveryBookmark;
6363
}

0 commit comments

Comments
 (0)