32
32
import com .oracle .labs .mlrg .olcut .util .Pair ;
33
33
34
34
import java .util .Map ;
35
+ import java .util .Optional ;
35
36
36
37
/**
37
38
* A provenance object which records object fields.
@@ -83,7 +84,7 @@ default public String generateString(String name) {
83
84
/**
84
85
* Removes the specified Provenance from the supplied map and returns it. Checks that it's the right type,
85
86
* and casts to it before returning.
86
- *
87
+ * <p>
87
88
* Throws ProvenanceException if it's not found or it's an incorrect type.
88
89
* @param map The map to check.
89
90
* @param key The key to look up.
@@ -95,15 +96,40 @@ default public String generateString(String name) {
95
96
*/
96
97
@ SuppressWarnings ("unchecked" ) // Guarded by isInstance check
97
98
public static <T extends Provenance > T checkAndExtractProvenance (Map <String ,Provenance > map , String key , Class <T > type , String provClassName ) throws ProvenanceException {
99
+ Optional <T > prov = maybeExtractProvenance (map ,key ,type ,provClassName );
100
+ if (prov .isPresent ()) {
101
+ return prov .get ();
102
+ } else {
103
+ throw new ProvenanceException ("Failed to find " + key + " when constructing " + provClassName );
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Removes the specified Provenance from the supplied map and returns it. Checks that it's the right type,
109
+ * and casts to it before returning. Unlike {@link #checkAndExtractProvenance(Map, String, Class, String)} it doesn't
110
+ * throw if it fails to find the key, only if the value is of the wrong type.
111
+ * <p>
112
+ * This is used when evolving provenance classes by adding new fields to ensure that old serialized
113
+ * forms remain compatible.
114
+ * @param map The map to inspect.
115
+ * @param key The key to find.
116
+ * @param type The class of the value.
117
+ * @param provClassName The name of the requesting class (to ensure the exception has the appropriate error message).
118
+ * @param <T> The type of the value.
119
+ * @return An optional containing the value if present.
120
+ * @throws ProvenanceException If the value is the wrong type.
121
+ */
122
+ @ SuppressWarnings ("unchecked" ) // Guarded by isInstance check
123
+ public static <T extends Provenance > Optional <T > maybeExtractProvenance (Map <String ,Provenance > map , String key , Class <T > type , String provClassName ) throws ProvenanceException {
98
124
Provenance tmp = map .remove (key );
99
125
if (tmp != null ) {
100
126
if (type .isInstance (tmp )) {
101
- return ( T ) tmp ;
127
+ return Optional . of (( T ) tmp ) ;
102
128
} else {
103
129
throw new ProvenanceException ("Failed to cast " + key + " when constructing " + provClassName + ", found " + tmp );
104
130
}
105
131
} else {
106
- throw new ProvenanceException ( "Failed to find " + key + " when constructing " + provClassName );
132
+ return Optional . empty ( );
107
133
}
108
134
}
109
135
}
0 commit comments