16
16
package com .diffplug .spotless ;
17
17
18
18
import java .io .IOException ;
19
- import java .io .ObjectStreamException ;
20
19
import java .io .Serializable ;
20
+ import java .util .Objects ;
21
21
22
22
import edu .umd .cs .findbugs .annotations .Nullable ;
23
23
24
- class FormatterStepSerializationRoundtrip <RoundtripState extends Serializable , EqualityState extends Serializable > extends FormatterStepEqualityOnStateSerialization <EqualityState > {
24
+ final class FormatterStepSerializationRoundtrip <RoundtripState extends Serializable , EqualityState extends Serializable > extends FormatterStepEqualityOnStateSerialization <EqualityState > {
25
25
private static final long serialVersionUID = 1L ;
26
26
private final String name ;
27
27
private final transient ThrowingEx .Supplier <RoundtripState > initializer ;
@@ -30,7 +30,7 @@ class FormatterStepSerializationRoundtrip<RoundtripState extends Serializable, E
30
30
private final SerializedFunction <RoundtripState , EqualityState > equalityStateExtractor ;
31
31
private final SerializedFunction <EqualityState , FormatterFunc > equalityStateToFormatter ;
32
32
33
- public FormatterStepSerializationRoundtrip (String name , ThrowingEx .Supplier <RoundtripState > initializer , SerializedFunction <RoundtripState , EqualityState > equalityStateExtractor , SerializedFunction <EqualityState , FormatterFunc > equalityStateToFormatter ) {
33
+ FormatterStepSerializationRoundtrip (String name , ThrowingEx .Supplier <RoundtripState > initializer , SerializedFunction <RoundtripState , EqualityState > equalityStateExtractor , SerializedFunction <EqualityState , FormatterFunc > equalityStateToFormatter ) {
34
34
this .name = name ;
35
35
this .initializer = initializer ;
36
36
this .equalityStateExtractor = equalityStateExtractor ;
@@ -42,13 +42,17 @@ public String getName() {
42
42
return name ;
43
43
}
44
44
45
+ private RoundtripState roundtripStateSupplier () throws Exception {
46
+ if (roundtripStateInternal == null ) {
47
+ roundtripStateInternal = initializer .get ();
48
+ }
49
+ return roundtripStateInternal ;
50
+ }
51
+
45
52
@ Override
46
53
protected EqualityState stateSupplier () throws Exception {
47
54
if (equalityStateInternal == null ) {
48
- if (roundtripStateInternal == null ) {
49
- roundtripStateInternal = initializer .get ();
50
- }
51
- equalityStateInternal = equalityStateExtractor .apply (roundtripStateInternal );
55
+ equalityStateInternal = equalityStateExtractor .apply (roundtripStateSupplier ());
52
56
}
53
57
return equalityStateInternal ;
54
58
}
@@ -58,25 +62,55 @@ protected FormatterFunc stateToFormatter(EqualityState equalityState) throws Exc
58
62
return equalityStateToFormatter .apply (equalityState );
59
63
}
60
64
61
- // override serialize output
62
- private void writeObject (java .io .ObjectOutputStream out ) throws IOException {
63
- if (ConfigurationCacheHack .SERIALIZE_FOR_ROUNDTRIP ) {
64
- if (roundtripStateInternal == null ) {
65
- roundtripStateInternal = ThrowingEx .get (initializer ::get );
65
+ HackClone <?, ?> hackClone (boolean optimizeForEquality ) {
66
+ return new HackClone <>(this , optimizeForEquality );
67
+ }
68
+
69
+ static class HackClone <RoundtripState extends Serializable , EqualityState extends Serializable > implements Serializable {
70
+ transient FormatterStepSerializationRoundtrip <?, ?> original ;
71
+ boolean optimizeForEquality ;
72
+ @ Nullable
73
+ FormatterStepSerializationRoundtrip cleaned ;
74
+
75
+ HackClone (@ Nullable FormatterStepSerializationRoundtrip <RoundtripState , EqualityState > original , boolean optimizeForEquality ) {
76
+ this .original = original ;
77
+ this .optimizeForEquality = optimizeForEquality ;
78
+ }
79
+
80
+ private void writeObject (java .io .ObjectOutputStream out ) throws IOException {
81
+ if (cleaned == null ) {
82
+ cleaned = new FormatterStepSerializationRoundtrip (original .name , null , original .equalityStateExtractor , original .equalityStateToFormatter );
83
+ if (optimizeForEquality ) {
84
+ cleaned .equalityStateInternal = ThrowingEx .get (original ::stateSupplier );
85
+ } else {
86
+ cleaned .roundtripStateInternal = ThrowingEx .get (original ::roundtripStateSupplier );
87
+ }
66
88
}
67
- equalityStateInternal = null ;
68
- } else {
69
- equalityStateInternal = ThrowingEx .get (this ::stateSupplier );
70
- roundtripStateInternal = null ;
89
+ out .defaultWriteObject ();
71
90
}
72
- out .defaultWriteObject ();
73
- }
74
91
75
- private void readObject (java .io .ObjectInputStream in ) throws IOException , ClassNotFoundException {
76
- in .defaultReadObject ();
77
- }
92
+ public FormatterStep rehydrate () {
93
+ try {
94
+ throw new Exception ("rehydrate optimizeForEquality=" + optimizeForEquality + " orig=" + original + " cleaned=" + cleaned );
95
+ } catch (Exception e ) {
96
+ e .printStackTrace ();
97
+ }
98
+ return original != null ? original : Objects .requireNonNull (cleaned , "how is clean null if this has been serialized?" );
99
+ }
100
+
101
+ @ Override
102
+ public boolean equals (Object o ) {
103
+ if (this == o )
104
+ return true ;
105
+ if (o == null || getClass () != o .getClass ())
106
+ return false ;
107
+ HackClone <?, ?> that = (HackClone <?, ?>) o ;
108
+ return optimizeForEquality == that .optimizeForEquality && rehydrate ().equals (that .rehydrate ());
109
+ }
78
110
79
- private void readObjectNoData () throws ObjectStreamException {
80
- throw new UnsupportedOperationException ();
111
+ @ Override
112
+ public int hashCode () {
113
+ return rehydrate ().hashCode () ^ Boolean .hashCode (optimizeForEquality );
114
+ }
81
115
}
82
116
}
0 commit comments