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

Nanopublication / nanopub-java / 17038267114

18 Aug 2025 10:41AM UTC coverage: 47.35% (-1.7%) from 49.072%
17038267114

push

github

Ziroli Plutschow
Now all Unit Tests run successful without network connection.

- Moved the GetIndex test to an Integration Test.

881 of 2880 branches covered (30.59%)

Branch coverage included in aggregate %.

4729 of 8968 relevant lines covered (52.73%)

2.51 hits per line

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

53.47
src/main/java/org/nanopub/extra/server/ServerIterator.java
1
package org.nanopub.extra.server;
2

3
import org.nanopub.extra.server.RegistryInfo.RegistryInfoException;
4

5
import java.io.*;
6
import java.util.*;
7

8
/**
9
 * An iterator that provides access to a list of nanopub servers.
10
 */
11
public class ServerIterator implements Iterator<RegistryInfo> {
12

13
    private static Map<String, RegistryInfo> serverInfos = new HashMap<>();
4✔
14
    private static long serverInfoRefreshed = System.currentTimeMillis();
3✔
15
    private static final long serverInfoRefreshInterval = 24 * 60 * 60 * 1000;
16

17
    private List<RegistryInfo> cachedServers = null;
3✔
18
    private List<String> serversToContact = new ArrayList<>();
5✔
19
    private Map<String, Boolean> serversContacted = new HashMap<>();
5✔
20
    private RegistryInfo next = null;
3✔
21

22
    /**
23
     * Creates a new ServerIterator.
24
     */
25
    public ServerIterator() {
26
        this(false);
3✔
27
    }
1✔
28

29
    /**
30
     * Creates a new ServerIterator, optionally forcing a reload of the server list.
31
     *
32
     * @param forceServerReload if true, forces a reload of the server list from the cache
33
     */
34
    public ServerIterator(boolean forceServerReload) {
2✔
35
        if (!forceServerReload) {
2!
36
            try {
37
                loadCachedServers();
2✔
38
            } catch (Exception ex) {
×
39
            }
1✔
40
        }
41
        if (cachedServers == null) {
3!
42
            serversToContact.addAll(NanopubServerUtils.getBootstrapServerList());
5✔
43
        }
44
    }
1✔
45

46
    /**
47
     * Creates a new ServerIterator with a list of bootstrap servers.
48
     *
49
     * @param bootstrapServers the bootstrap server URLs
50
     */
51
    public ServerIterator(String... bootstrapServers) {
×
52
        serversToContact.addAll(Arrays.asList(bootstrapServers));
×
53
    }
×
54

55
    /**
56
     * Creates a new ServerIterator with a list of bootstrap servers.
57
     *
58
     * @param bootstrapServers the list of bootstrap server URLs
59
     */
60
    public ServerIterator(List<String> bootstrapServers) {
×
61
        serversToContact.addAll(bootstrapServers);
×
62
    }
×
63

64
    /**
65
     * {@inheritDoc}
66
     * <p>
67
     * Checks if there are more servers to iterate over.
68
     */
69
    @Override
70
    public boolean hasNext() {
71
        if (next == null) {
3!
72
            next = getNextServer();
4✔
73
        }
74
        return next != null;
6!
75
    }
76

77
    /**
78
     * {@inheritDoc}
79
     * <p>
80
     * Returns the next server in the iteration.
81
     */
82
    @Override
83
    public RegistryInfo next() {
84
        RegistryInfo n = next;
3✔
85
        next = null;
3✔
86
        if (n == null) {
2!
87
            n = getNextServer();
×
88
        }
89
        return n;
2✔
90
    }
91

92
    /**
93
     * {@inheritDoc}
94
     * <p>
95
     * Removes the current server from the iteration.
96
     */
97
    @Override
98
    public void remove() {
99
        throw new UnsupportedOperationException();
×
100
    }
101

102
    private RegistryInfo getNextServer() {
103
        if (cachedServers != null) {
3!
104
            if (cachedServers.isEmpty()) return null;
×
105
            return cachedServers.removeFirst();
×
106
        } else {
107
            while (!serversToContact.isEmpty()) {
4!
108
                if (!serversToContact.isEmpty()) {
4!
109
                    String url = serversToContact.removeFirst();
5✔
110
                    if (serversContacted.containsKey(url)) continue;
5!
111
                    serversContacted.put(url, true);
7✔
112
                    RegistryInfo info = getServerInfo(url);
4✔
113
                    if (info == null) continue;
2!
114
                    return info;
2✔
115
                }
116
            }
117
        }
118
        return null;
×
119
    }
120

121
    private RegistryInfo getServerInfo(String url) {
122
        if (System.currentTimeMillis() - serverInfoRefreshed > serverInfoRefreshInterval) {
6!
123
            serverInfos.clear();
×
124
            serverInfoRefreshed = System.currentTimeMillis();
×
125
        }
126
        if (!serverInfos.containsKey(url)) {
4✔
127
            try {
128
                serverInfos.put(url, RegistryInfo.load(url));
6✔
129
            } catch (RegistryInfoException ex) {
×
130
                // ignore
131
            }
1✔
132
        }
133
        return serverInfos.get(url);
5✔
134
    }
135

136
    @SuppressWarnings("unchecked")
137
    private void loadCachedServers() throws Exception {
138
        File serverListFile = getServerListFile();
2✔
139
        if (serverListFile.exists()) {
3!
140
            long now = System.currentTimeMillis();
×
141
            long fileTime = serverListFile.lastModified();
×
142
            if (fileTime > now || now - fileTime > 1000 * 60 * 60 * 24) {
×
143
                return;
×
144
            }
145
            try (ObjectInputStream oin = new ObjectInputStream(new FileInputStream(serverListFile))) {
×
146
                cachedServers = (List<RegistryInfo>) oin.readObject();
×
147
            }
148
        }
149
    }
1✔
150

151
    /**
152
     * Writes the cached servers to a file.
153
     *
154
     * @param cachedServers the list of cached servers to write
155
     * @throws java.io.IOException if an I/O error occurs
156
     */
157
    public static void writeCachedServers(List<RegistryInfo> cachedServers) throws IOException {
158
        if (cachedServers.size() < 5) return;
×
159
        File serverListFile = getServerListFile();
×
160
        serverListFile.getParentFile().mkdir();
×
161
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(serverListFile))) {
×
162
            oos.writeObject(cachedServers);
×
163
        }
164
    }
×
165

166
    private static File getServerListFile() {
167
        return new File(System.getProperty("user.home") + "/.nanopub/cachedservers");
7✔
168
    }
169

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