1919 */
2020package org .neo4j .gds .projection ;
2121
22- import org .jetbrains .annotations .Contract ;
2322import org .jetbrains .annotations .NotNull ;
2423import org .jetbrains .annotations .Nullable ;
2524import org .neo4j .gds .NodeLabel ;
@@ -225,7 +224,7 @@ public void update(
225224 }
226225 }
227226
228- private void initConfig (Map <String , Object > config ) {
227+ private void initConfig (@ Nullable Map <String , Object > config ) {
229228 if (this .config == null ) {
230229 initObjectUnderLock (() -> this .config , () -> {
231230 this .config = GraphProjectFromCypherAggregationConfig .of (username , Objects .requireNonNull (graphName ), config );
@@ -264,8 +263,8 @@ private void initGraphName(String graphName) {
264263 }
265264
266265 private void initIdMapBuilder (
267- Map <String , Value > sourceNodePropertyValues ,
268- Map <String , Value > targetNodePropertyValues ,
266+ @ Nullable Map <String , Value > sourceNodePropertyValues ,
267+ @ Nullable Map <String , Value > targetNodePropertyValues ,
269268 @ Nullable NodeLabelToken sourceNodeLabels ,
270269 @ Nullable NodeLabelToken targetNodeLabels
271270 ) {
@@ -303,6 +302,8 @@ private LazyIdMapBuilder newIdMapBuilder(
303302 @ Nullable NodeLabelToken targetNodeLabels ,
304303 @ Nullable Map <String , Value > targetNodeProperties
305304 ) {
305+ assert this .config != null ;
306+
306307 boolean hasLabelInformation = !(sourceNodeLabels == null && targetNodeLabels == null );
307308 boolean hasProperties = !(sourceNodeProperties == null && targetNodeProperties == null );
308309 return new LazyIdMapBuilder (config .readConcurrency (), hasLabelInformation , hasProperties );
@@ -331,7 +332,7 @@ private Map<String, Value> propertiesConfig(
331332 ));
332333 }
333334
334- private @ Nullable NodeLabelToken labelsConfig (
335+ private NodeLabelToken labelsConfig (
335336 Object node ,
336337 String nodeLabelKey ,
337338 @ NotNull Map <String , Object > nodesConfig
@@ -340,27 +341,28 @@ private Map<String, Value> propertiesConfig(
340341 return tryLabelsConfig (node , nodeLabelsEntry , nodeLabelKey );
341342 }
342343
343- @ Contract ("_, null, _ -> null" )
344- private @ Nullable NodeLabelToken tryLabelsConfig (
344+ private NodeLabelToken tryLabelsConfig (
345345 Object node ,
346346 @ Nullable Object nodeLabels ,
347347 String nodeLabelKey
348348 ) {
349349 if (nodeLabels == null || Boolean .FALSE .equals (nodeLabels )) {
350- return null ;
350+ return NodeLabelTokens . empty () ;
351351 }
352352
353+ NodeLabelToken nodeLabelToken ;
354+
353355 if (Boolean .TRUE .equals (nodeLabels )) {
354- if (node instanceof Node ) {
355- return NodeLabelTokens .ofNullable (((Node ) node ).getLabels ());
356+ if (!(node instanceof Node )) {
357+ throw new IllegalArgumentException (
358+ "Using `true` to load all labels does only work if the node is a Neo4j node object"
359+ );
356360 }
357- throw new IllegalArgumentException (
358- "Using `true` to load all labels does only work if the node is a Neo4j node object"
359- );
361+ nodeLabelToken = NodeLabelTokens . ofNullable ((( Node ) node ). getLabels ());
362+ } else {
363+ nodeLabelToken = NodeLabelTokens . ofNullable ( nodeLabels );
360364 }
361365
362- var nodeLabelToken = NodeLabelTokens .ofNullable (nodeLabels );
363-
364366 if (nodeLabelToken == null ) {
365367 throw new IllegalArgumentException (formatWithLocale (
366368 "The value of `%s` must be either a `List of Strings`, a `String`, or a `Boolean`, but was `%s`." ,
@@ -392,6 +394,7 @@ private RelationshipType typeConfig(
392394
393395 private RelationshipsBuilder newRelImporter (RelationshipType relType ) {
394396 assert this .idMapBuilder != null ;
397+ assert this .config != null ;
395398
396399 var undirectedTypes = config .undirectedRelationshipTypes ();
397400 var orientation = undirectedTypes .contains (relType .name ) || undirectedTypes .contains ("*" )
@@ -447,6 +450,7 @@ private RelationshipsBuilder newRelImporter(RelationshipType relType) {
447450
448451 private long extractNodeId (@ Nullable Object node ) {
449452 if (node instanceof Node ) {
453+ //noinspection removal
450454 return ((Node ) node ).getId ();
451455 } else if (node instanceof Long ) {
452456 return (Long ) node ;
@@ -509,6 +513,9 @@ private long loadNode(
509513 assert this .idMapBuilder != null ;
510514
511515 var originalNodeId = extractNodeId (node );
516+ if (nodeLabels == null ) {
517+ nodeLabels = NodeLabelTokens .empty ();
518+ }
512519
513520 return nodeProperties == null
514521 ? this .idMapBuilder .addNode (originalNodeId , nodeLabels )
@@ -560,6 +567,8 @@ private static double[] loadMultipleRelationshipProperties(
560567 return this .result ;
561568 }
562569
570+ assert this .config != null ;
571+
563572 // in case something else has written something with the same graph name
564573 // validate again before doing the heavier graph building
565574 validateGraphName (graphName );
@@ -719,7 +728,6 @@ default Aggregation aggregation() {
719728 }
720729
721730 @ org .immutables .value .Value .Default
722- @ NotNull
723731 default List <String > undirectedRelationshipTypes () {
724732 return List .of ();
725733 }
@@ -744,7 +752,7 @@ default Set<String> outputFieldDenylist() {
744752 );
745753 }
746754
747- static GraphProjectFromCypherAggregationConfig of (String userName , String graphName , Map <String , Object > config ) {
755+ static GraphProjectFromCypherAggregationConfig of (String userName , String graphName , @ Nullable Map <String , Object > config ) {
748756 return new GraphProjectFromCypherAggregationConfigImpl (userName , graphName , CypherMapWrapper .create (config ));
749757 }
750758
0 commit comments