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

knowledgepixels / nanodash / 17837235071

18 Sep 2025 05:58PM UTC coverage: 13.87%. Remained the same
17837235071

push

github

tkuhn
chore: Remove serialVersionUIDs

443 of 4022 branches covered (11.01%)

Branch coverage included in aggregate %.

1133 of 7341 relevant lines covered (15.43%)

0.68 hits per line

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

76.86
src/main/java/com/knowledgepixels/nanodash/NanopubElement.java
1
package com.knowledgepixels.nanodash;
2

3
import org.eclipse.rdf4j.model.IRI;
4
import org.eclipse.rdf4j.model.Statement;
5
import org.eclipse.rdf4j.model.vocabulary.RDF;
6
import org.nanopub.Nanopub;
7
import org.nanopub.NanopubUtils;
8
import org.nanopub.SimpleTimestampPattern;
9
import org.nanopub.extra.security.MalformedCryptoElementException;
10
import org.nanopub.extra.security.NanopubSignatureElement;
11
import org.nanopub.extra.security.SignatureUtils;
12
import org.slf4j.Logger;
13
import org.slf4j.LoggerFactory;
14

15
import java.io.Serializable;
16
import java.security.GeneralSecurityException;
17
import java.util.*;
18

19
/**
20
 * Represents a wrapper for a Nanopub object, providing additional metadata and utility methods.
21
 * This class includes caching mechanisms to avoid redundant Nanopub retrievals.
22
 */
23
public class NanopubElement implements Serializable {
24

25
    private static Map<String, NanopubElement> nanopubCache = new HashMap<>();
4✔
26
    private static final Logger logger = LoggerFactory.getLogger(NanopubElement.class);
4✔
27

28
    /**
29
     * Retrieves a NanopubElement instance for the given URI.
30
     * If the instance is not already cached, it creates a new one and caches it.
31
     *
32
     * @param uri The URI of the Nanopub.
33
     * @return The NanopubElement instance.
34
     */
35
    public static NanopubElement get(String uri) {
36
        if (!nanopubCache.containsKey(uri)) {
4!
37
            nanopubCache.put(uri, new NanopubElement(uri));
8✔
38
        }
39
        return nanopubCache.get(uri);
5✔
40
    }
41

42
    /**
43
     * Retrieves a NanopubElement instance for the given Nanopub object.
44
     * If the instance is not already cached, it creates a new one and caches it.
45
     *
46
     * @param nanopub The Nanopub object.
47
     * @return The NanopubElement instance.
48
     */
49
    public static NanopubElement get(Nanopub nanopub) {
50
        if (nanopub == null) {
2✔
51
            throw new IllegalArgumentException("Nanopub cannot be null");
5✔
52
        }
53
        String uri = nanopub.getUri().stringValue();
4✔
54
        if (!nanopubCache.containsKey(uri)) {
4✔
55
            nanopubCache.put(uri, new NanopubElement(nanopub));
8✔
56
        }
57
        return nanopubCache.get(uri);
5✔
58
    }
59

60
    private Nanopub nanopub;
61
    private String uriString; // Keeping URI separately, as nanopub might be null when it cannot be fetched
62
    private String label;
63
    private Calendar creationTime;
64
    private Boolean seemsToHaveSignature;
65
    private Boolean hasValidSignature;
66
    private IRI signerId;
67
    private List<IRI> types;
68
    private Map<String, String> foafNameMap;
69

70
    /**
71
     * Constructs a NanopubElement for the given URI.
72
     * Fetches the Nanopub object using the URI.
73
     *
74
     * @param uri The URI of the Nanopub.
75
     * @throws IllegalArgumentException If no Nanopub is found for the given URI.
76
     */
77
    private NanopubElement(String uri) {
2✔
78
        this.uriString = uri;
3✔
79
        this.nanopub = Utils.getNanopub(uri);
4✔
80
        if (nanopub == null) {
3!
81
            throw new IllegalArgumentException("No nanopublication found for URI: " + uri);
×
82
        }
83
    }
1✔
84

85
    /**
86
     * Constructs a NanopubElement for the given Nanopub object.
87
     *
88
     * @param nanopub The Nanopub object.
89
     */
90
    private NanopubElement(Nanopub nanopub) {
2✔
91
        this.uriString = nanopub.getUri().stringValue();
5✔
92
        this.nanopub = nanopub;
3✔
93
    }
1✔
94

95
    /**
96
     * Returns the Nanopub object.
97
     *
98
     * @return The Nanopub object.
99
     */
100
    public Nanopub getNanopub() {
101
        return nanopub;
3✔
102
    }
103

104
    /**
105
     * Returns the URI of the Nanopub.
106
     *
107
     * @return The URI as a string.
108
     */
109
    public String getUri() {
110
        return uriString;
3✔
111
    }
112

113
    /**
114
     * Returns the label of the Nanopub.
115
     * If the label is not already set, it retrieves it from the Nanopub.
116
     *
117
     * @return The label of the Nanopub.
118
     */
119
    public String getLabel() {
120
        if (label != null) return label;
6✔
121
        if (nanopub == null) return null;
3!
122
        label = NanopubUtils.getLabel(nanopub);
5✔
123
        if (label == null) label = "";
3!
124
        return label;
3✔
125
    }
126

127
    /**
128
     * Returns the creation time of the Nanopub.
129
     * If the creation time is not already set, it retrieves it using a timestamp pattern.
130
     *
131
     * @return The creation time as a Calendar object.
132
     */
133
    public Calendar getCreationTime() {
134
        if (nanopub == null) return null;
3!
135
        if (creationTime == null) {
3✔
136
            creationTime = SimpleTimestampPattern.getCreationTime(nanopub);
5✔
137
        }
138
        return creationTime;
3✔
139
    }
140

141
    /**
142
     * Checks if the Nanopub seems to have a signature.
143
     *
144
     * @return True if the Nanopub seems to have a signature, false otherwise.
145
     */
146
    public boolean seemsToHaveSignature() {
147
        if (nanopub == null) return false;
3!
148
        if (seemsToHaveSignature == null) {
3✔
149
            seemsToHaveSignature = SignatureUtils.seemsToHaveSignature(nanopub);
6✔
150
        }
151
        return seemsToHaveSignature;
4✔
152
    }
153

154
    /**
155
     * Returns the public key of the Nanopub's signature.
156
     * If the signature is not valid, returns null.
157
     *
158
     * @return The public key as a string, or null if invalid.
159
     */
160
    public String getPubkey() {
161
        if (!hasValidSignature()) return null;
3!
162
        try {
163
            return SignatureUtils.getSignatureElement(nanopub).getPublicKeyString();
5✔
164
        } catch (MalformedCryptoElementException ex) {
×
165
            logger.error("Error in getting the signature element of the nanopub {}", uriString, ex);
×
166
            return null;
×
167
        }
168
    }
169

170
    /**
171
     * Returns the SHA-256 hash of the public key of the Nanopub's signature
172
     *
173
     * @return The SHA-256 hash of the public key as a hexadecimal string, or null if the public key is not available.
174
     */
175
    public String getPubkeyhash() {
176
        String pubkey = getPubkey();
3✔
177
        if (pubkey == null) return null;
2!
178
        return Utils.createSha256HexHash(pubkey);
3✔
179
    }
180

181
    /**
182
     * Checks if the Nanopub has a valid signature.
183
     *
184
     * @return True if the Nanopub has a valid signature, false otherwise.
185
     */
186
    public boolean hasValidSignature() {
187
        if (nanopub == null) return false;
3!
188
        if (hasValidSignature == null) {
3✔
189
            try {
190
                NanopubSignatureElement se;
191
                se = SignatureUtils.getSignatureElement(nanopub);
4✔
192
                if (se != null) {
2!
193
                    hasValidSignature = SignatureUtils.hasValidSignature(se);
5✔
194
                    if (se.getSigners().size() == 1) signerId = se.getSigners().iterator().next();
13!
195
                } else {
196
                    hasValidSignature = false;
×
197
                }
198
            } catch (MalformedCryptoElementException | GeneralSecurityException ex) {
×
199
                logger.error("Error in checking the signature of the nanopub {}", uriString, ex);
×
200
                return false;
×
201
            }
1✔
202
        }
203
        return hasValidSignature;
4✔
204
    }
205

206
    /**
207
     * Returns the ID of the signer of the Nanopub.
208
     * If the signature is not valid, returns null.
209
     *
210
     * @return The signer ID as an IRI, or null if invalid.
211
     */
212
    public IRI getSignerId() {
213
        if (nanopub == null) return null;
3!
214
        if (!hasValidSignature()) return null;
3!
215
        return signerId;
3✔
216
    }
217

218
    /**
219
     * Returns the list of RDF types associated with the Nanopub.
220
     * If the types are not already set, it retrieves them from the Nanopub's pubinfo.
221
     *
222
     * @return A list of RDF types as IRIs.
223
     */
224
    public List<IRI> getTypes() {
225
        if (types == null) {
3!
226
            types = new ArrayList<>();
5✔
227
            if (nanopub == null) return types;
3!
228
            for (Statement st : nanopub.getPubinfo()) {
12✔
229
                if (st.getSubject().equals(nanopub.getUri()) && st.getPredicate().equals(RDF.TYPE) && st.getObject() instanceof IRI) {
16!
230
                    types.add((IRI) st.getObject());
7✔
231
                }
232
            }
1✔
233
        }
234
        return types;
3✔
235
    }
236

237
    /**
238
     * Returns a map of FOAF names associated with the Nanopub.
239
     * If the map is not already set, it retrieves it using a utility method.
240
     *
241
     * @return A map of FOAF names.
242
     */
243
    public Map<String, String> getFoafNameMap() {
244
        if (foafNameMap == null) foafNameMap = Utils.getFoafNameMap(nanopub);
×
245
        return foafNameMap;
×
246
    }
247

248
}
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