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

knowledgepixels / nanodash / 18941803064

30 Oct 2025 01:12PM UTC coverage: 14.299% (+0.1%) from 14.184%
18941803064

push

github

ashleycaselli
refactor(Utils): merge IriItem.getShortNameFromURI with Utils.getShortNameFromURI

512 of 4504 branches covered (11.37%)

Branch coverage included in aggregate %.

1331 of 8385 relevant lines covered (15.87%)

0.71 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 com.knowledgepixels.nanodash.ApiCache;
4
import com.knowledgepixels.nanodash.User;
5
import com.knowledgepixels.nanodash.Utils;
6
import org.apache.wicket.Component;
7
import org.apache.wicket.extensions.ajax.markup.html.repeater.data.table.AjaxNavigationToolbar;
8
import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
9
import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortState;
10
import org.apache.wicket.extensions.markup.html.repeater.data.table.*;
11
import org.apache.wicket.extensions.markup.html.repeater.util.SingleSortState;
12
import org.apache.wicket.extensions.markup.html.repeater.util.SortParam;
13
import org.apache.wicket.markup.html.basic.Label;
14
import org.apache.wicket.markup.html.panel.Panel;
15
import org.apache.wicket.markup.repeater.Item;
16
import org.apache.wicket.model.IModel;
17
import org.apache.wicket.model.Model;
18
import org.nanopub.Nanopub;
19
import org.nanopub.extra.services.ApiResponse;
20
import org.nanopub.extra.services.ApiResponseEntry;
21
import org.nanopub.extra.services.QueryRef;
22
import org.slf4j.Logger;
23
import org.slf4j.LoggerFactory;
24

25
import java.io.Serializable;
26
import java.util.ArrayList;
27
import java.util.Comparator;
28
import java.util.Iterator;
29
import java.util.List;
30

31
/**
32
 * A component that displays a data table of nanopublication references.
33
 */
34
public class ExploreDataTable extends Panel {
35

36
    private static final String refQueryName = "find-uri-references";
37
    private static final Logger logger = LoggerFactory.getLogger(ExploreDataTable.class);
×
38

39
    private ExploreDataTable(String id, String ref, ApiResponse response) {
40
        super(id);
×
41
        setOutputMarkupId(true);
×
42

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

69

70
    private List<ApiResponseEntry> filterData(List<ApiResponseEntry> data, String nanopubUri) {
71
        List<ApiResponseEntry> filteredList = new ArrayList<>();
×
72
        Nanopub np = Utils.getAsNanopub(nanopubUri);
×
73
        if (np == null) return data;
×
74
        for (ApiResponseEntry e : data) {
×
75
            if (np == null || !nanopubUri.equals(e.get("np"))) {
×
76
                filteredList.add(e);
×
77
            }
78
        }
×
79
        return filteredList;
×
80
    }
81

82

83
    private class Column extends AbstractColumn<ApiResponseEntry, String> {
84

85
        private String key, current;
86

87
        /**
88
         * Constructor for a column in the data table.
89
         *
90
         * @param title   The title of the column.
91
         * @param key     The key used to retrieve data from ApiResponseEntry.
92
         * @param current The current value to highlight in the column.
93
         */
94
        public Column(String title, String key, String current) {
×
95
            super(new Model<String>(title), key);
×
96
            this.key = key;
×
97
            this.current = current;
×
98
        }
×
99

100
        @Override
101
        public void populateItem(Item<ICellPopulator<ApiResponseEntry>> cellItem, String componentId, IModel<ApiResponseEntry> rowModel) {
102
            String value = rowModel.getObject().get(key);
×
103
            if (value.equals(current)) {
×
104
                cellItem.add(new Label(componentId, "<strong>" + Utils.getShortNameFromURI(value) + "</strong>").setEscapeModelStrings(false));
×
105
            } else if (value.matches("https?://.+")) {
×
106
                cellItem.add(new NanodashLink(componentId, value));
×
107
            } else {
108
                if (key.equals("pubkey")) {
×
109
                    cellItem.add(new Label(componentId, User.getShortDisplayNameForPubkeyhash(null, Utils.createSha256HexHash(value))));
×
110
                } else {
111
                    cellItem.add(new Label(componentId, value));
×
112
                }
113
            }
114
        }
×
115

116
    }
117

118

119
    private class DataProvider implements ISortableDataProvider<ApiResponseEntry, String> {
120

121
        private List<ApiResponseEntry> data = new ArrayList<>();
×
122
        private SingleSortState<String> sortState = new SingleSortState<>();
×
123

124
        /**
125
         * Default constructor that initializes the sort state.
126
         */
127
        public DataProvider() {
×
128
            sortState.setSort(new SortParam<String>("date", false));
×
129
        }
×
130

131
        /**
132
         * Constructor that initializes the data provider with a list of ApiResponseEntry.
133
         *
134
         * @param data The list of ApiResponseEntry to be used in the data provider.
135
         */
136
        public DataProvider(List<ApiResponseEntry> data) {
137
            this();
×
138
            this.data = data;
×
139
        }
×
140

141
        @Override
142
        public Iterator<? extends ApiResponseEntry> iterator(long first, long count) {
143
            List<ApiResponseEntry> copy = new ArrayList<>(data);
×
144
            ApiResponseComparator comparator = new ApiResponseComparator(sortState.getSort());
×
145
            copy.sort(comparator);
×
146
            return Utils.subList(copy, first, first + count).iterator();
×
147
        }
148

149
        @Override
150
        public IModel<ApiResponseEntry> model(ApiResponseEntry object) {
151
            return new Model<ApiResponseEntry>(object);
×
152
        }
153

154
        @Override
155
        public long size() {
156
            return data.size();
×
157
        }
158

159
        @Override
160
        public ISortState<String> getSortState() {
161
            return sortState;
×
162
        }
163

164
        @Override
165
        public void detach() {
166
        }
×
167

168
    }
169

170
    private class ApiResponseComparator implements Comparator<ApiResponseEntry>, Serializable {
171

172
        private SortParam<String> sortParam;
173

174
        /**
175
         * Constructor that initializes the comparator with a sort parameter.
176
         *
177
         * @param sortParam The sort parameter defining the property and order for comparison.
178
         */
179
        public ApiResponseComparator(SortParam<String> sortParam) {
×
180
            this.sortParam = sortParam;
×
181
        }
×
182

183
        @Override
184
        public int compare(ApiResponseEntry o1, ApiResponseEntry o2) {
185
            String p = sortParam.getProperty();
×
186
            int result = o1.get(p).compareTo(o2.get(p));
×
187
            if (!sortParam.isAscending()) result = -result;
×
188
            return result;
×
189
        }
190

191
    }
192

193
    /**
194
     * Creates a new ExploreDataTable component.
195
     *
196
     * @param markupId the Wicket markup ID for the component
197
     * @param ref      the reference URI to be displayed in the table
198
     * @return a new ExploreDataTable component or an ApiResultComponent if the data is not cached
199
     */
200
    public static Component createComponent(final String markupId, final String ref) {
201
        QueryRef queryRef = new QueryRef(refQueryName, "ref", ref);
×
202
        ApiResponse response = ApiCache.retrieveResponse(queryRef);
×
203
        if (response != null) {
×
204
            return new ExploreDataTable(markupId, ref, response);
×
205
        } else {
206
            return new ApiResultComponent(markupId, queryRef) {
×
207

208
                @Override
209
                public Component getApiResultComponent(String markupId, ApiResponse response) {
210
                    return new ExploreDataTable(markupId, ref, response);
×
211
                }
212

213
            };
214
        }
215
    }
216

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