Skip to content

Commit 098b81e

Browse files
author
Zhen Li
committed
Make bookmark to be Serializable so that the bookmark can be passed around without disclose the content of bookmark.
1 parent 143cc47 commit 098b81e

File tree

3 files changed

+44
-14
lines changed

3 files changed

+44
-14
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
package org.neo4j.driver.internal;
2020

21+
import java.io.Serializable;
22+
2123
/**
2224
* Causal chaining is carried out by passing bookmarks between transactions.
2325
*
@@ -29,6 +31,6 @@
2931
*
3032
* To opt out of this mechanism for unrelated units of work, applications can use multiple sessions.
3133
*/
32-
public interface Bookmark
34+
public interface Bookmark extends Serializable
3335
{
3436
}

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

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

21+
import java.io.Serializable;
2122
import java.util.Collection;
2223
import java.util.Collections;
2324
import java.util.HashSet;
2425
import java.util.Objects;
2526
import java.util.Set;
2627

28+
import static java.util.Objects.requireNonNull;
29+
2730
public final class InternalBookmark implements Bookmark
2831
{
2932
private static final InternalBookmark EMPTY = new InternalBookmark( Collections.emptySet() );
3033

31-
private final Iterable<String> values;
34+
private final Collection<String> values;
3235

33-
private InternalBookmark( Iterable<String> values )
36+
private InternalBookmark( Collection<String> values )
3437
{
38+
requireNonNull( values );
39+
if ( !(values instanceof Serializable) )
40+
{
41+
// The Collection interface does not enforce Serializable, but all built-in Collection implementations actually are Serializable.
42+
// This check ensures that we always provide values using these java built-in Collection objects.
43+
throw new IllegalArgumentException( "The bookmark value should only be of Java built-in types such as ArrayList, HashSet which are serializable." );
44+
}
3545
this.values = values;
3646
}
3747

@@ -65,10 +75,10 @@ else if ( size == 1 )
6575
{
6676
if ( value == null )
6777
{
68-
continue; // skip any null bookmark objects
78+
continue; // skip any null bookmark value
6979
}
7080
assertInternalBookmark( value );
71-
((InternalBookmark) value).values.forEach( newValues::add );
81+
newValues.addAll( ((InternalBookmark) value).values );
7282
}
7383
return new InternalBookmark( newValues );
7484
}
@@ -103,7 +113,7 @@ public static InternalBookmark parse( String value )
103113
/**
104114
* Used for test only
105115
*/
106-
public static InternalBookmark parse( Iterable<String> values )
116+
public static InternalBookmark parse( Collection<String> values )
107117
{
108118
if ( values == null )
109119
{
@@ -114,11 +124,7 @@ public static InternalBookmark parse( Iterable<String> values )
114124

115125
public boolean isEmpty()
116126
{
117-
if ( values instanceof Collection )
118-
{
119-
return ((Collection) values).isEmpty();
120-
}
121-
return !values.iterator().hasNext();
127+
return values.isEmpty();
122128
}
123129

124130
public Iterable<String> values()

driver/src/test/java/org/neo4j/driver/internal/InternalBookmarkTest.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020

2121
import org.junit.jupiter.api.Test;
2222

23+
import java.io.ByteArrayInputStream;
24+
import java.io.ByteArrayOutputStream;
25+
import java.io.ObjectInputStream;
26+
import java.io.ObjectOutputStream;
2327
import java.util.Arrays;
24-
import java.util.Collections;
2528
import java.util.List;
2629

2730
import org.neo4j.driver.internal.util.Iterables;
@@ -104,7 +107,7 @@ void asBeginTransactionParametersForNonEmptyBookmark()
104107
void bookmarkFromString()
105108
{
106109
InternalBookmark bookmark = InternalBookmark.parse( "Cat" );
107-
assertEquals( Collections.singletonList( "Cat" ), bookmark.values() );
110+
assertEquals( singletonList( "Cat" ), bookmark.values() );
108111
verifyValues( bookmark, "Cat" );
109112
}
110113

@@ -133,7 +136,7 @@ void bookmarkFromNullIterable()
133136
@Test
134137
void bookmarkFromEmptyIterable()
135138
{
136-
InternalBookmark bookmark = InternalBookmark.parse( Collections.<String>emptyList() );
139+
InternalBookmark bookmark = InternalBookmark.parse( emptyList() );
137140
assertTrue( bookmark.isEmpty() );
138141
}
139142

@@ -169,6 +172,25 @@ void shouldReturnAllBookmarks()
169172
assertIterableEquals( bookmarks, InternalBookmark.parse( bookmarks ).values() );
170173
}
171174

175+
@Test
176+
void objectShouldBeTheSameWhenSerializingAndDeserializing() throws Throwable
177+
{
178+
Bookmark bookmark = InternalBookmark.parse( Arrays.asList( "neo4j:1000", "neo4j:2000" ) );
179+
180+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
181+
ObjectOutputStream objectOutputStream = new ObjectOutputStream( outputStream );
182+
objectOutputStream.writeObject( bookmark );
183+
objectOutputStream.flush();
184+
objectOutputStream.close();
185+
186+
ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() );
187+
ObjectInputStream objectInputStream = new ObjectInputStream( inputStream );
188+
Bookmark readBookmark = (InternalBookmark) objectInputStream.readObject();
189+
objectInputStream.close();
190+
191+
assertEquals( bookmark, readBookmark );
192+
}
193+
172194
private static void verifyValues( InternalBookmark bookmark, String... expectedValues )
173195
{
174196
verifyValues( bookmark, asList( expectedValues ) );

0 commit comments

Comments
 (0)