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

knowledgepixels / nanodash / 17549674654

08 Sep 2025 11:45AM UTC coverage: 12.054% (+0.2%) from 11.88%
17549674654

push

github

tkuhn
Add pagination to more views

335 of 3858 branches covered (8.68%)

Branch coverage included in aggregate %.

970 of 6968 relevant lines covered (13.92%)

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/component/ExploreDataTable.java
1
package com.knowledgepixels.nanodash.component;
2

3
import java.io.Serializable;
4
import java.util.ArrayList;
5
import java.util.Comparator;
6
import java.util.HashMap;
7
import java.util.Iterator;
8
import java.util.List;
9

10
import org.apache.wicket.Component;
11
import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxNavigationToolbar;
12
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
13
import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortState;
14
import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractColumn;
15
import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
16
import org.apache.wicket.extensions.markup.html.repeater.data.table.HeadersToolbar;
17
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
18
import org.apache.wicket.extensions.markup.html.repeater.data.table.ISortableDataProvider;
19
import org.apache.wicket.extensions.markup.html.repeater.data.table.NoRecordsToolbar;
20
import org.apache.wicket.extensions.markup.html.repeater.util.SingleSortState;
21
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
22
import org.apache.wicket.markup.html.basic.Label;
23
import org.apache.wicket.markup.html.panel.Panel;
24
import org.apache.wicket.markup.repeater.Item;
25
import org.apache.wicket.model.IModel;
26
import org.apache.wicket.model.Model;
27
import org.nanopub.Nanopub;
28
import org.nanopub.extra.services.ApiResponse;
29
import org.nanopub.extra.services.ApiResponseEntry;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32

33
import com.knowledgepixels.nanodash.ApiCache;
34
import com.knowledgepixels.nanodash.User;
35
import com.knowledgepixels.nanodash.Utils;
36

37
/**
38
 * A component that displays a data table of nanopublication references.
39
 */
40
public class ExploreDataTable extends Panel {
41

42
    private static final long serialVersionUID = 1L;
43

44
    private static final String refQueryName = "find-uri-references";
45
    private static final Logger logger = LoggerFactory.getLogger(ExploreDataTable.class);
×
46

47
    private ExploreDataTable(String id, String ref, ApiResponse response) {
48
        super(id);
×
49
        setOutputMarkupId(true);
×
50

51
        List<IColumn<ApiResponseEntry, String>> columns = new ArrayList<>();
×
52
        DataProvider dp;
53
        try {
54
            columns.add(new Column("Nanopublication", "np", ref));
×
55
            columns.add(new Column("Part", "graphpred", ref));
×
56
            columns.add(new Column("Subject", "subj", ref));
×
57
            columns.add(new Column("Predicate", "pred", ref));
×
58
            columns.add(new Column("Object", "obj", ref));
×
59
            columns.add(new Column("Published By", "pubkey", ref));
×
60
            columns.add(new Column("Published On", "date", ref));
×
61
            dp = new DataProvider(filterData(response.getData(), ref));
×
62
            DataTable<ApiResponseEntry, String> table = new DataTable<>("datatable", columns, dp, 10);
×
63
            table.addBottomToolbar(new AjaxNavigationToolbar(table));
×
64
            table.addBottomToolbar(new NoRecordsToolbar(table));
×
65
            table.addTopToolbar(new HeadersToolbar<String>(table, dp));
×
66
            table.setOutputMarkupId(true);
×
67
            add(table);
×
68
            add(new Label("message", "").setVisible(false));
×
69
        } catch (Exception ex) {
×
70
            logger.error("Could not create data table for reference: {}", ref, ex);
×
71
            add(new Label("datatable", "").setVisible(false));
×
72
            add(new Label("message", "Could not load data table."));
×
73
            add(new Label("show-all").setVisible(false));
×
74
        }
×
75
    }
×
76

77

78
    private List<ApiResponseEntry> filterData(List<ApiResponseEntry> data, String nanopubUri) {
79
        List<ApiResponseEntry> filteredList = new ArrayList<>();
×
80
        Nanopub np = Utils.getAsNanopub(nanopubUri);
×
81
        if (np == null) return data;
×
82
        for (ApiResponseEntry e : data) {
×
83
            if (np == null || !nanopubUri.equals(e.get("np"))) {
×
84
                filteredList.add(e);
×
85
            }
86
        }
×
87
        return filteredList;
×
88
    }
89

90

91
    private class Column extends AbstractColumn<ApiResponseEntry, String> {
92

93
        private static final long serialVersionUID = 1L;
94

95
        private String key, current;
96

97
        /**
98
         * Constructor for a column in the data table.
99
         *
100
         * @param title   The title of the column.
101
         * @param key     The key used to retrieve data from ApiResponseEntry.
102
         * @param current The current value to highlight in the column.
103
         */
104
        public Column(String title, String key, String current) {
×
105
            super(new Model<String>(title), key);
×
106
            this.key = key;
×
107
            this.current = current;
×
108
        }
×
109

110
        @Override
111
        public void populateItem(Item<ICellPopulator<ApiResponseEntry>> cellItem, String componentId, IModel<ApiResponseEntry> rowModel) {
112
            String value = rowModel.getObject().get(key);
×
113
            if (value.equals(current)) {
×
114
                cellItem.add(new Label(componentId, "<strong>" + IriItem.getShortNameFromURI(value) + "</strong>").setEscapeModelStrings(false));
×
115
            } else if (value.matches("https?://.+")) {
×
116
                cellItem.add(new NanodashLink(componentId, value));
×
117
            } else {
118
                if (key.equals("pubkey")) {
×
119
                    cellItem.add(new Label(componentId, User.getShortDisplayNameForPubkeyhash(null, Utils.createSha256HexHash(value))));
×
120
                } else {
121
                    cellItem.add(new Label(componentId, value));
×
122
                }
123
            }
124
        }
×
125

126
    }
127

128

129
    private class DataProvider implements ISortableDataProvider<ApiResponseEntry, String> {
130

131
        private static final long serialVersionUID = 1L;
132

133
        private List<ApiResponseEntry> data = new ArrayList<>();
×
134
        private SingleSortState<String> sortState = new SingleSortState<>();
×
135

136
        /**
137
         * Default constructor that initializes the sort state.
138
         */
139
        public DataProvider() {
×
140
            sortState.setSort(new SortParam<String>("date", false));
×
141
        }
×
142

143
        /**
144
         * Constructor that initializes the data provider with a list of ApiResponseEntry.
145
         *
146
         * @param data The list of ApiResponseEntry to be used in the data provider.
147
         */
148
        public DataProvider(List<ApiResponseEntry> data) {
149
            this();
×
150
            this.data = data;
×
151
        }
×
152

153
        @Override
154
        public Iterator<? extends ApiResponseEntry> iterator(long first, long count) {
155
            List<ApiResponseEntry> copy = new ArrayList<>(data);
×
156
            ApiResponseComparator comparator = new ApiResponseComparator(sortState.getSort());
×
157
            copy.sort(comparator);
×
158
            return Utils.subList(copy, first, first + count).iterator();
×
159
        }
160

161
        @Override
162
        public IModel<ApiResponseEntry> model(ApiResponseEntry object) {
163
            return new Model<ApiResponseEntry>(object);
×
164
        }
165

166
        @Override
167
        public long size() {
168
            return data.size();
×
169
        }
170

171
        @Override
172
        public ISortState<String> getSortState() {
173
            return sortState;
×
174
        }
175

176
        @Override
177
        public void detach() {
178
        }
×
179

180
    }
181

182
    private class ApiResponseComparator implements Comparator<ApiResponseEntry>, Serializable {
183

184
        private static final long serialVersionUID = 1L;
185
        private SortParam<String> sortParam;
186

187
        /**
188
         * Constructor that initializes the comparator with a sort parameter.
189
         *
190
         * @param sortParam The sort parameter defining the property and order for comparison.
191
         */
192
        public ApiResponseComparator(SortParam<String> sortParam) {
×
193
            this.sortParam = sortParam;
×
194
        }
×
195

196
        @Override
197
        public int compare(ApiResponseEntry o1, ApiResponseEntry o2) {
198
            String p = sortParam.getProperty();
×
199
            int result = o1.get(p).compareTo(o2.get(p));
×
200
            if (!sortParam.isAscending()) result = -result;
×
201
            return result;
×
202
        }
203

204
    }
205

206
    /**
207
     * Creates a new ExploreDataTable component.
208
     *
209
     * @param markupId the Wicket markup ID for the component
210
     * @param ref      the reference URI to be displayed in the table
211
     * @return a new ExploreDataTable component or an ApiResultComponent if the data is not cached
212
     */
213
    public static Component createComponent(final String markupId, final String ref) {
214
        ApiResponse response = ApiCache.retrieveResponse(refQueryName, getParams(ref));
×
215
        if (response != null) {
×
216
            return new ExploreDataTable(markupId, ref, response);
×
217
        } else {
218
            return new ApiResultComponent(markupId, refQueryName, getParams(ref)) {
×
219

220
                private static final long serialVersionUID = 1L;
221

222
                @Override
223
                public Component getApiResultComponent(String markupId, ApiResponse response) {
224
                    return new ExploreDataTable(markupId, ref, response);
×
225
                }
226

227
            };
228
        }
229
    }
230

231
    private static HashMap<String, String> getParams(String ref) {
232
        final HashMap<String, String> params = new HashMap<>();
×
233
        params.put("ref", ref);
×
234
        return params;
×
235
    }
236

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