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

knowledgepixels / nanodash / 17320701451

29 Aug 2025 09:55AM UTC coverage: 12.02% (+0.01%) from 12.007%
17320701451

push

github

ashleycaselli
refactor: minor code style update

330 of 3842 branches covered (8.59%)

Branch coverage included in aggregate %.

950 of 6807 relevant lines covered (13.96%)

0.61 hits per line

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

0.0
src/main/java/com/knowledgepixels/nanodash/page/SearchPage.java
1
package com.knowledgepixels.nanodash.page;
2

3
import com.knowledgepixels.nanodash.*;
4
import com.knowledgepixels.nanodash.component.NanopubResults;
5
import com.knowledgepixels.nanodash.component.TitleBar;
6
import org.apache.wicket.ajax.AjaxRequestTarget;
7
import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior;
8
import org.apache.wicket.extensions.ajax.markup.html.AjaxLazyLoadPanel;
9
import org.apache.wicket.markup.html.WebMarkupContainer;
10
import org.apache.wicket.markup.html.basic.Label;
11
import org.apache.wicket.markup.html.form.CheckBox;
12
import org.apache.wicket.markup.html.form.Form;
13
import org.apache.wicket.markup.html.form.RadioChoice;
14
import org.apache.wicket.markup.html.form.TextField;
15
import org.apache.wicket.model.Model;
16
import org.apache.wicket.request.mapper.parameter.PageParameters;
17
import org.nanopub.extra.services.ApiResponseEntry;
18
import org.slf4j.Logger;
19
import org.slf4j.LoggerFactory;
20

21
import java.time.Duration;
22
import java.util.*;
23

24
/**
25
 * SearchPage allows users to search for nanopublications by URI or free text.
26
 */
27
public class SearchPage extends NanodashPage {
28

29
    private static final long serialVersionUID = 1L;
30
    private static final Logger logger = LoggerFactory.getLogger(SearchPage.class);
×
31

32
    /**
33
     * The mount path for this page.
34
     */
35
    public static final String MOUNT_PATH = "/search";
36

37
    /**
38
     * {@inheritDoc}
39
     */
40
    @Override
41
    public String getMountPath() {
42
        return MOUNT_PATH;
×
43
    }
44

45
    private TextField<String> searchField;
46
    private CheckBox filterUser;
47
    private Model<String> progress;
48

49
    private Map<String, String> pubKeyMap;
50
    private RadioChoice<String> pubkeySelection;
51

52
    /**
53
     * Constructor for SearchPage.
54
     *
55
     * @param parameters Page parameters containing the search query, filter option, and public key.
56
     */
57
    public SearchPage(final PageParameters parameters) {
58
        super(parameters);
×
59

60
        add(new TitleBar("titlebar", this, "search"));
×
61

62
        final String searchText = parameters.get("query").toString();
×
63
        final Boolean filterCheck = Boolean.valueOf(parameters.get("filter").toString());
×
64
        final String pubkey = parameters.get("pubkey").toString();
×
65

66
        Form<?> form = new Form<Void>("form") {
×
67

68
            private static final long serialVersionUID = 1L;
69

70
            protected void onSubmit() {
71
                String searchText = searchField.getModelObject().trim();
×
72
                Boolean filterCheck = filterUser.getModelObject();
×
73
                String pubkey = pubkeySelection.getModelObject();
×
74
                PageParameters params = new PageParameters();
×
75
                params.add("query", searchText);
×
76
                params.add("filter", filterCheck);
×
77
                if (pubkey != null) params.add("pubkey", pubkey);
×
78
                setResponsePage(SearchPage.class, params);
×
79
            }
×
80
        };
81
        add(form);
×
82

83
        form.add(searchField = new TextField<String>("search", Model.of(searchText)));
×
84
        WebMarkupContainer ownFilter = new WebMarkupContainer("own-filter");
×
85
        ownFilter.add(filterUser = new CheckBox("filter", Model.of(filterCheck)));
×
86
        NanodashSession session = NanodashSession.get();
×
87
        ownFilter.setVisible(!NanodashPreferences.get().isReadOnlyMode() && session.getUserIri() != null);
×
88
        ArrayList<String> pubKeyList = new ArrayList<>();
×
89
        if (session.getUserIri() != null) {
×
90
            pubKeyMap = new HashMap<>();
×
91
            String lKeyShort = Utils.getShortPubkeyhashLabel(session.getPubkeyString(), session.getUserIri());
×
92
            pubKeyList.add(lKeyShort);
×
93
            pubKeyMap.put(lKeyShort, session.getPubkeyString());
×
94
            for (String pk : User.getPubkeyhashes(session.getUserIri(), null)) {
×
95
                String keyShort = Utils.getShortPubkeyhashLabel(pk, session.getUserIri());
×
96
                if (!pubKeyMap.containsKey(keyShort)) {
×
97
                    pubKeyList.add(keyShort);
×
98
                    pubKeyMap.put(keyShort, pk);
×
99
                }
100
            }
×
101
        }
102

103
        pubkeySelection = new RadioChoice<String>("pubkeygroup", Model.of(pubkey), pubKeyList);
×
104
        if (!pubKeyList.isEmpty() && pubkeySelection.getModelObject() == null) {
×
105
            pubkeySelection.setDefaultModelObject(pubKeyList.get(0));
×
106
        }
107
        ownFilter.add(pubkeySelection);
×
108

109
        form.add(ownFilter);
×
110

111
        // TODO: Progress bar doesn't update at the moment:
112
        progress = new Model<>();
×
113
        final Label progressLabel = new Label("progress", progress);
×
114
        progressLabel.setOutputMarkupId(true);
×
115
        progressLabel.add(new AjaxSelfUpdatingTimerBehavior(Duration.ofMillis(1000)));
×
116
        add(progressLabel);
×
117

118
        if (searchText == null || searchText.isEmpty()) {
×
119
            add(new Label("nanopubs", "Enter a search term above."));
×
120
        } else {
121
            add(new AjaxLazyLoadPanel<NanopubResults>("nanopubs") {
×
122

123
                private static final long serialVersionUID = 1L;
124

125
                @Override
126
                public NanopubResults getLazyLoadComponent(String markupId) {
127
                    Map<String, String> nanopubParams = new HashMap<>();
×
128
                    List<ApiResponseEntry> nanopubResults = new ArrayList<>();
×
129
                    String s = searchText;
×
130
                    if (s != null) {
×
131
                        s = s.trim();
×
132
                        if (s.matches("https?://[^\\s]+")) {
×
133
                            logger.info("URI QUERY: {}", s);
×
134
                            nanopubParams.put("ref", s);
×
135
                            if (Boolean.TRUE.equals(filterCheck)) {
×
136
                                String pubkey = pubKeyMap.get(pubkeySelection.getModelObject());
×
137
                                logger.info("Filter for PUBKEY: {}", pubkey);
×
138
                                nanopubParams.put("pubkey", pubkey);
×
139
                            }
140
                            try {
141
                                // nanopubResults = ApiAccess.getAll("find_nanopubs_with_uri", nanopubParams).getData();
142
                                nanopubResults = QueryApiAccess.get("find-uri-references", nanopubParams).getData();
×
143
                            } catch (Exception ex) {
×
144
                                ex.printStackTrace();
×
145
                            }
×
146
//                                                        nanopubResults = ApiAccess.getRecent("find_nanopubs_with_uri", nanopubParams, progress);
147
                        } else {
148
                            String freeTextQuery = getFreeTextQuery(s);
×
149
                            if (!freeTextQuery.isEmpty()) {
×
150
                                logger.info("FREE TEXT QUERY: {}", freeTextQuery);
×
151
                                nanopubParams.put("query", freeTextQuery);
×
152
                                if (filterCheck != null && Boolean.TRUE.equals(filterCheck)) {
×
153
                                    String pubkey = pubKeyMap.get(pubkeySelection.getModelObject());
×
154
                                    logger.info("Filter for PUBKEY: {}", pubkey);
×
155
                                    nanopubParams.put("pubkey", pubkey);
×
156
                                }
157
                                try {
158
                                    // nanopubResults = ApiAccess.getAll("find_nanopubs_with_text", nanopubParams).getData();
159
                                    nanopubResults = QueryApiAccess.get("fulltext-search-on-labels", nanopubParams).getData();
×
160
                                } catch (Exception ex) {
×
161
                                    ex.printStackTrace();
×
162
                                }
×
163
//                                                                nanopubResults = ApiAccess.getRecent("find_nanopubs_with_text", nanopubParams, progress);
164
                            }
165
                        }
166
                    }
167
                    nanopubResults.sort(new ApiResponseEntry.DataComparator());
×
168
                    List<String> nanopubIds = new ArrayList<>();
×
169
                    while (!nanopubResults.isEmpty() && nanopubIds.size() < 100) {
×
170
                        String npUri = nanopubResults.remove(0).get("np");
×
171
                        if (!nanopubIds.contains(npUri)) nanopubIds.add(npUri);
×
172
                    }
×
173
                    progress.setObject("");
×
174
                    if (nanopubIds.isEmpty()) progress.setObject("nothing found");
×
175
                    List<NanopubElement> nanopubs = new ArrayList<>();
×
176
                    for (String id : nanopubIds) nanopubs.add(NanopubElement.get(id));
×
177
                    return NanopubResults.fromList(markupId, nanopubs);
×
178
                }
179

180
                @Override
181
                protected void onContentLoaded(NanopubResults content, Optional<AjaxRequestTarget> target) {
182
                    super.onContentLoaded(content, target);
×
183
                    if (target.isPresent()) {
×
184
                        target.get().appendJavaScript("updateElements();");
×
185
                    }
186
                }
×
187

188
            });
189

190
        }
191
    }
×
192

193
    private static String getFreeTextQuery(String searchText) {
194
        String freeTextQuery = "";
×
195
        String previous = "AND";
×
196
        String preprocessed = "";
×
197
        boolean inQuote = true;
×
198
        for (String s : searchText.replaceAll("\\(\\s+", "(").replaceAll("\\s+\\)", ")").replaceAll("@", "").split("\"")) {
×
199
            inQuote = !inQuote;
×
200
            if (inQuote) {
×
201
                s = "\\\"" + String.join("@", s.split("[^\\p{L}0-9\\-_]+")) + "\\\"";
×
202
            }
203
            preprocessed += s;
×
204
        }
205
        preprocessed = preprocessed.trim();
×
206
        for (String s : preprocessed.split("[^\\p{L}0-9\\-_\\(\\)@\\\"\\\\]+")) {
×
207
            if (s.matches("[0-9].*")) continue;
×
208
            if (!s.matches("AND|OR|\\(+|\\)+|\\(?NOT")) {
×
209
                if (s.toLowerCase().matches("and|or|not")) {
×
210
                    // ignore lower-case and/or/not
211
                    continue;
×
212
                }
213
                if (!previous.matches("AND|OR|\\(?NOT")) {
×
214
                    freeTextQuery += " AND";
×
215
                }
216
            }
217
            freeTextQuery += " " + s.toLowerCase();
×
218
            previous = s;
×
219
        }
220
        freeTextQuery = freeTextQuery.replaceAll("@", " ").trim();
×
221
        return freeTextQuery;
×
222
    }
223

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