• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

link-intersystems / lis-commons / #224

03 Sep 2023 09:34AM UTC coverage: 89.823% (-0.2%) from 89.982%
#224

push

renelink
Migrated to Java 11.

7379 of 8215 relevant lines covered (89.82%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/lis-commons-lang/src/main/java/com/link_intersystems/lang/ref/AbstractSerializableReference.java
1
/**
2
 * Copyright 2011 Link Intersystems GmbH <rene.link@link-intersystems.com>
3
 * <p>
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 * <p>
8
 * http://www.apache.org/licenses/LICENSE-2.0
9
 * <p>
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.link_intersystems.lang.ref;
17

18
import java.io.IOException;
19
import java.io.ObjectInputStream;
20
import java.io.ObjectOutputStream;
21
import java.io.Serializable;
22
import java.util.Arrays;
23

24
/**
25
 * A reference to an object that is not serializable but can be restored out of
26
 * other information (e.g. Class object can be restored from a full qualified
27
 * class name that is a string).
28
 *
29
 * @param <T> of the wrapped non serializable object.
30
 * @author René Link <a
31
 * href="mailto:rene.link@link-intersystems.com">[rene.link@link-
32
 * intersystems.com]</a>
33
 * @version 1.2.0;
34
 * @since 1.0.0;
35
 */
36
public abstract class AbstractSerializableReference<T> implements
37
        SerializableReference<T> {
38

39
    /**
40
     * Member field that holds a reference to the wrapped non-serializable
41
     * object.
42
     *
43
     * @since 1.2.0;
44
     */
45
    private transient T transientReferent;
46

47
    /**
48
     *
49
     */
50
    private static final long serialVersionUID = -7758428790458970417L;
51

52
    private Serializable restoreInfo;
53

54
    /**
55
     * Constructor that does not initialize the referent.
56
     *
57
     * @since 1.2.0;
58
     */
59
    protected AbstractSerializableReference() {
60
        this(null);
1✔
61
    }
1✔
62

63
    /**
64
     * Constructor that initializes the referent.
65
     *
66
     * @param transientReferent the referent that this {@link Reference} refers to.
67
     * @since 1.2.0;
68
     */
69
    protected AbstractSerializableReference(T transientReferent) {
1✔
70
        this.transientReferent = transientReferent;
1✔
71
    }
1✔
72

73
    /**
74
     * {@inheritDoc}
75
     *
76
     * @return the wrapped object that is not serializable by either returning
77
     * the object that this {@link SerializableReference} was construted
78
     * with or in case of deserialization delegates to the restore
79
     * routine to create one.
80
     * @since 1.0.0;
81
     */
82
    public T get() {
83
        return transientReferent;
1✔
84
    }
85

86
    private void writeObject(ObjectOutputStream out) throws IOException {
87
        if (transientReferent != null) {
1✔
88
            try {
89
                restoreInfo = serialize(transientReferent);
1✔
90
            } catch (Exception e) {
×
91

92
                Class<?> transientReferentClass = transientReferent.getClass();
×
93
                throw new IOException("Unable to serialize object of " + transientReferentClass, e);
×
94
            }
1✔
95
        }
96
        out.defaultWriteObject();
1✔
97
    }
1✔
98

99
    /**
100
     * Convert the non-serializable referent to a serializable form. Called when
101
     * the serialization is in progress.
102
     *
103
     * @param nonSerializableObject the referent that must be converted to a serializable form.
104
     * @return the serializable form that contains all information needed to
105
     * restore the referent on deserialization.
106
     * @throws Exception if any exception occurs.
107
     * @since 1.2.0;
108
     */
109
    protected abstract Serializable serialize(T nonSerializableObject)
110
            throws Exception;
111

112
    private void readObject(ObjectInputStream in) throws IOException,
113
            ClassNotFoundException {
114
        in.defaultReadObject();
1✔
115
        if (restoreInfo != null) {
1✔
116
            try {
117
                transientReferent = deserialize(restoreInfo);
1✔
118
            } catch (Exception e) {
1✔
119
                throw new IOException("Unable to deserialize object reference", e);
1✔
120
            }
1✔
121
        }
122
    }
1✔
123

124
    /**
125
     * Restore the referent from it's serializable form that was created by
126
     * {@link #serialize(Object)}. Called when the de-serialization is in
127
     * progress.
128
     *
129
     * @param restoreInfo the serialized form that was created by
130
     *                    {@link #serialize(Object)}.
131
     * @return the restored non-serializable referent.
132
     * @throws Exception if any exception occurs.
133
     * @since 1.2.0;
134
     */
135
    protected abstract T deserialize(Serializable restoreInfo) throws Exception;
136

137
    /**
138
     * {@inheritDoc}.
139
     *
140
     * @since 1.2.0;
141
     */
142
    @Override
143
    public String toString() {
144
        T referent = get();
1✔
145
        StringBuilder stringBuilder = new StringBuilder();
1✔
146
        stringBuilder.append("Reference[");
1✔
147
        if (referent != null) {
1✔
148
            stringBuilder.append(referent);
1✔
149
        } else {
150
            stringBuilder.append("null");
1✔
151
        }
152
        stringBuilder.append("]");
1✔
153
        return stringBuilder.toString();
1✔
154
    }
155

156
    /**
157
     * {@inheritDoc}. The hash code is based on the referent's hash code.
158
     *
159
     * @since 1.2.0;
160
     */
161
    @Override
162
    public int hashCode() {
163
        final int prime = 31;
1✔
164
        int result = 1;
1✔
165
        result = prime
1✔
166
                * result
167
                + ((transientReferent == null) ? 0 : transientReferent
1✔
168
                .hashCode());
1✔
169
        return result;
1✔
170
    }
171

172
    /**
173
     * {@inheritDoc}. Delegates to the referent's equals method. So a
174
     * {@link AbstractSerializableReference} is considert equal to another
175
     * {@link AbstractSerializableReference} if their referents are equal
176
     * according to their equal method's implementation.
177
     *
178
     * @since 1.2.0;
179
     */
180
    @SuppressWarnings("rawtypes")
181
    @Override
182
    public boolean equals(Object obj) {
183
        if (this == obj) {
1✔
184
            return true;
1✔
185
        }
186
        if (obj == null) {
1✔
187
            return false;
1✔
188
        }
189
        if (getClass() != obj.getClass()) {
1✔
190
            return false;
1✔
191
        }
192

193
        AbstractSerializableReference other = AbstractSerializableReference.class
1✔
194
                .cast(obj);
1✔
195

196
        if (transientReferent == null && other.transientReferent != null) {
1✔
197
            return false;
1✔
198
        }
199

200
        boolean referentsAreEqual = transientReferent
1✔
201
                .equals(other.transientReferent);
1✔
202
        return referentsAreEqual;
1✔
203
    }
204

205
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc