Skip to content

Commit 8123f76

Browse files
committed
feat(gql-status-object): Introduce GqlNotification
Following up on the feedback received on the GQL Status Object feature, which is currently in preview, this update separates the new GQL Status Object hierarchy from the legacy `Notification` type by introducing a new `GqlNotification` interface that extends the `GqlStatusObject`. This should make it easier to understand the new GQL Status Objects and migrate from using the legacy `Notification` to the new types. Eventually, the new hierarchy is expected to replace the legacy `Notification` that is expected to be deprecated and phased out at a later date.
1 parent 9d0315e commit 8123f76

File tree

12 files changed

+321
-169
lines changed

12 files changed

+321
-169
lines changed

driver/clirr-ignored-differences.xml

+24
Original file line numberDiff line numberDiff line change
@@ -645,4 +645,28 @@
645645
<method>java.lang.Object as(java.lang.Class)</method>
646646
</difference>
647647

648+
<difference>
649+
<className>org/neo4j/driver/summary/Notification</className>
650+
<differenceType>4001</differenceType>
651+
<to>org/neo4j/driver/summary/GqlStatusObject</to>
652+
</difference>
653+
654+
<difference>
655+
<className>org/neo4j/driver/summary/Notification</className>
656+
<differenceType>7002</differenceType>
657+
<method>java.util.Optional inputPosition()</method>
658+
</difference>
659+
660+
<difference>
661+
<className>org/neo4j/driver/summary/Notification</className>
662+
<differenceType>7002</differenceType>
663+
<method>java.util.Optional classification()</method>
664+
</difference>
665+
666+
<difference>
667+
<className>org/neo4j/driver/summary/Notification</className>
668+
<differenceType>7002</differenceType>
669+
<method>java.util.Optional rawClassification()</method>
670+
</difference>
671+
648672
</differences>

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

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*
2424
* @since 5.7
2525
*/
26+
// to be deprecated
2627
public sealed interface NotificationCategory extends Serializable permits NotificationClassification {
2728
/**
2829
* A hint category.

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

-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.neo4j.driver.internal.InternalNotificationConfig;
2222
import org.neo4j.driver.internal.InternalNotificationSeverity;
2323
import org.neo4j.driver.summary.ResultSummary;
24-
import org.neo4j.driver.util.Preview;
2524

2625
/**
2726
* A notification configuration defining what notifications should be supplied by the server.
@@ -40,7 +39,6 @@
4039
* @see ResultSummary#notifications()
4140
* @see org.neo4j.driver.summary.Notification
4241
*/
43-
@Preview(name = "GQL-status object")
4442
public sealed interface NotificationConfig extends Serializable permits InternalNotificationConfig {
4543
/**
4644
* Returns a default notification configuration.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [https://neo4j.com]
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.neo4j.driver.internal.summary;
18+
19+
import java.util.Map;
20+
import java.util.Optional;
21+
import org.neo4j.driver.NotificationClassification;
22+
import org.neo4j.driver.NotificationSeverity;
23+
import org.neo4j.driver.Value;
24+
import org.neo4j.driver.summary.GqlNotification;
25+
import org.neo4j.driver.summary.InputPosition;
26+
27+
public class InternalGqlNotification extends InternalGqlStatusObject implements GqlNotification {
28+
private final InputPosition position;
29+
private final NotificationSeverity severityLevel;
30+
private final String rawSeverityLevel;
31+
private final NotificationClassification classification;
32+
private final String rawClassification;
33+
34+
public InternalGqlNotification(
35+
String gqlStatus,
36+
String statusDescription,
37+
Map<String, Value> diagnosticRecord,
38+
InputPosition position,
39+
NotificationSeverity severityLevel,
40+
String rawSeverityLevel,
41+
NotificationClassification classification,
42+
String rawClassification) {
43+
super(gqlStatus, statusDescription, diagnosticRecord);
44+
this.position = position;
45+
this.severityLevel = severityLevel;
46+
this.rawSeverityLevel = rawSeverityLevel;
47+
this.classification = classification;
48+
this.rawClassification = rawClassification;
49+
}
50+
51+
@Override
52+
public Optional<InputPosition> inputPosition() {
53+
return Optional.ofNullable(position);
54+
}
55+
56+
@Override
57+
public Optional<NotificationSeverity> severityLevel() {
58+
return Optional.ofNullable(severityLevel);
59+
}
60+
61+
@Override
62+
public Optional<String> rawSeverityLevel() {
63+
return Optional.ofNullable(rawSeverityLevel);
64+
}
65+
66+
@Override
67+
public Optional<NotificationClassification> classification() {
68+
return Optional.ofNullable(classification);
69+
}
70+
71+
@Override
72+
public Optional<String> rawClassification() {
73+
return Optional.ofNullable(rawClassification);
74+
}
75+
76+
@Override
77+
public String toString() {
78+
return "InternalGqlNotification{" + "gqlStatus='"
79+
+ gqlStatus + '\'' + ", statusDescription='"
80+
+ statusDescription + '\'' + ", diagnosticRecord="
81+
+ diagnosticRecord + '}';
82+
}
83+
}

driver/src/main/java/org/neo4j/driver/internal/summary/InternalGqlStatusObject.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public class InternalGqlStatusObject implements GqlStatusObject {
5252
Map.entry("OPERATION", Values.value("")),
5353
Map.entry("OPERATION_CODE", Values.value("0"))));
5454

55-
private final String gqlStatus;
56-
private final String statusDescription;
57-
private final Map<String, Value> diagnosticRecord;
55+
protected final String gqlStatus;
56+
protected final String statusDescription;
57+
protected final Map<String, Value> diagnosticRecord;
5858

5959
public InternalGqlStatusObject(String gqlStatus, String statusDescription, Map<String, Value> diagnosticRecord) {
6060
this.gqlStatus = Objects.requireNonNull(gqlStatus);

driver/src/main/java/org/neo4j/driver/internal/summary/InternalNotification.java

+40-63
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,20 @@
1616
*/
1717
package org.neo4j.driver.internal.summary;
1818

19+
import static org.neo4j.driver.internal.value.NullValue.NULL;
20+
1921
import java.util.Arrays;
20-
import java.util.Map;
21-
import java.util.Objects;
2222
import java.util.Optional;
23+
import java.util.function.Function;
2324
import org.neo4j.driver.NotificationCategory;
2425
import org.neo4j.driver.NotificationClassification;
2526
import org.neo4j.driver.NotificationSeverity;
2627
import org.neo4j.driver.Value;
28+
import org.neo4j.driver.internal.InternalNotificationSeverity;
2729
import org.neo4j.driver.summary.InputPosition;
2830
import org.neo4j.driver.summary.Notification;
2931

30-
public class InternalNotification extends InternalGqlStatusObject implements Notification {
32+
public class InternalNotification implements Notification {
3133
public static Optional<NotificationCategory> valueOf(String value) {
3234
return Arrays.stream(NotificationClassification.values())
3335
.filter(type -> type.toString().equals(value))
@@ -45,57 +47,73 @@ public static Optional<NotificationCategory> valueOf(String value) {
4547
});
4648
}
4749

50+
public static final Function<Value, Notification> VALUE_TO_NOTIFICATION = value -> {
51+
var code = value.get("code").asString();
52+
var title = value.get("title").asString();
53+
var description = value.get("description").asString();
54+
var rawSeverityLevel =
55+
value.containsKey("severity") ? value.get("severity").asString() : null;
56+
var severityLevel =
57+
InternalNotificationSeverity.valueOf(rawSeverityLevel).orElse(null);
58+
var rawCategory = value.containsKey("category") ? value.get("category").asString() : null;
59+
var category = valueOf(rawCategory).orElse(null);
60+
61+
var posValue = value.get("position");
62+
InputPosition position = null;
63+
if (posValue != NULL) {
64+
position = new InternalInputPosition(
65+
posValue.get("offset").asInt(),
66+
posValue.get("line").asInt(),
67+
posValue.get("column").asInt());
68+
}
69+
70+
return new InternalNotification(
71+
code, title, description, severityLevel, rawSeverityLevel, category, rawCategory, position);
72+
};
73+
4874
private final String code;
4975
private final String title;
5076
private final String description;
5177
private final NotificationSeverity severityLevel;
5278
private final String rawSeverityLevel;
53-
private final NotificationClassification classification;
54-
private final String rawClassification;
79+
private final NotificationCategory category;
80+
private final String rawCategory;
5581
private final InputPosition position;
5682

5783
public InternalNotification(
58-
String gqlStatus,
59-
String statusDescription,
60-
Map<String, Value> diagnosticRecord,
6184
String code,
6285
String title,
6386
String description,
6487
NotificationSeverity severityLevel,
6588
String rawSeverityLevel,
66-
NotificationClassification classification,
67-
String rawClassification,
89+
NotificationCategory category,
90+
String rawCategory,
6891
InputPosition position) {
69-
super(gqlStatus, statusDescription, diagnosticRecord);
70-
this.code = Objects.requireNonNull(code);
92+
this.code = code;
7193
this.title = title;
7294
this.description = description;
7395
this.severityLevel = severityLevel;
7496
this.rawSeverityLevel = rawSeverityLevel;
75-
this.classification = classification;
76-
this.rawClassification = rawClassification;
97+
this.category = category;
98+
this.rawCategory = rawCategory;
7799
this.position = position;
78100
}
79101

80-
@SuppressWarnings({"deprecation", "RedundantSuppression"})
81102
@Override
82103
public String code() {
83104
return code;
84105
}
85106

86-
@SuppressWarnings({"deprecation", "RedundantSuppression"})
87107
@Override
88108
public String title() {
89109
return title;
90110
}
91111

92-
@SuppressWarnings({"deprecation", "RedundantSuppression"})
93112
@Override
94113
public String description() {
95114
return description;
96115
}
97116

98-
@SuppressWarnings({"deprecation", "RedundantSuppression"})
99117
@Override
100118
public InputPosition position() {
101119
return position;
@@ -111,62 +129,21 @@ public Optional<String> rawSeverityLevel() {
111129
return Optional.ofNullable(rawSeverityLevel);
112130
}
113131

114-
@Override
115-
public Optional<NotificationClassification> classification() {
116-
return Optional.ofNullable(classification);
117-
}
118-
119-
@Override
120-
public Optional<String> rawClassification() {
121-
return Optional.ofNullable(rawClassification);
122-
}
123-
124132
@Override
125133
public Optional<NotificationCategory> category() {
126-
return Optional.ofNullable(classification);
134+
return Optional.ofNullable(category);
127135
}
128136

129137
@Override
130138
public Optional<String> rawCategory() {
131-
return Optional.ofNullable(rawClassification);
132-
}
133-
134-
@Override
135-
public boolean equals(Object o) {
136-
if (this == o) return true;
137-
if (o == null || getClass() != o.getClass()) return false;
138-
if (!super.equals(o)) return false;
139-
var that = (InternalNotification) o;
140-
return Objects.equals(code, that.code)
141-
&& Objects.equals(title, that.title)
142-
&& Objects.equals(description, that.description)
143-
&& Objects.equals(severityLevel, that.severityLevel)
144-
&& Objects.equals(rawSeverityLevel, that.rawSeverityLevel)
145-
&& classification == that.classification
146-
&& Objects.equals(rawClassification, that.rawClassification)
147-
&& Objects.equals(position, that.position);
148-
}
149-
150-
@Override
151-
public int hashCode() {
152-
return Objects.hash(
153-
super.hashCode(),
154-
code,
155-
title,
156-
description,
157-
severityLevel,
158-
rawSeverityLevel,
159-
classification,
160-
rawClassification,
161-
position);
139+
return Optional.ofNullable(rawCategory);
162140
}
163141

164142
@Override
165143
public String toString() {
166144
var info = "code=" + code + ", title=" + title + ", description=" + description + ", severityLevel="
167-
+ severityLevel + ", rawSeverityLevel=" + rawSeverityLevel + ", classification=" + classification
168-
+ ", rawClassification="
169-
+ rawClassification;
145+
+ severityLevel + ", rawSeverityLevel=" + rawSeverityLevel + ", category=" + category + ", rawCategory="
146+
+ rawCategory;
170147
return position == null ? info : info + ", position={" + position + "}";
171148
}
172149
}

0 commit comments

Comments
 (0)