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

knowledgepixels / nanodash / 17406147119

02 Sep 2025 02:07PM UTC coverage: 12.066% (-0.005%) from 12.071%
17406147119

push

github

tkuhn
Make our own AjaxLazyLoadPanel that doesn't introduce a <div>

331 of 3866 branches covered (8.56%)

Branch coverage included in aggregate %.

969 of 6908 relevant lines covered (14.03%)

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

3
import com.knowledgepixels.nanodash.ApiCache;
4
import org.apache.wicket.Component;
5
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
6
import org.apache.wicket.markup.html.basic.Label;
7
import org.apache.wicket.request.IRequestHandler;
8
import org.apache.wicket.request.cycle.RequestCycle;
9
import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
10
import org.nanopub.extra.services.ApiResponse;
11
import org.slf4j.Logger;
12
import org.slf4j.LoggerFactory;
13

14
import java.util.HashMap;
15

16
/**
17
 * A component that retrieves and displays the result of an API call.
18
 * It uses AjaxLazyLoadPanel to load the content lazily and shows a loading indicator while waiting for the response.
19
 */
20
public abstract class ApiResultComponent extends AjaxLazyLoadPanel<Component> {
21

22
    private static final long serialVersionUID = 1L;
23

24
    private final String queryName;
25
    private final HashMap<String, String> params;
26
    private boolean waitIconEnabled = true;
×
27
    private ApiResponse response = null;
×
28
    private String waitMessage = null;
×
29
    private String waitComponentHtml = null;
×
30
    private static final Logger logger = LoggerFactory.getLogger(ApiResultComponent.class);
×
31

32
    /**
33
     * Constructor for ApiResultComponent.
34
     *
35
     * @param id        the component id
36
     * @param queryName the name of the API query to be executed
37
     * @param params    a map of parameters to be passed to the API query
38
     */
39
    public ApiResultComponent(String id, String queryName, HashMap<String, String> params) {
40
        super(id);
×
41
        this.queryName = queryName;
×
42
        this.params = params;
×
43
    }
×
44

45
    /**
46
     * Constructor for ApiResultComponent with a single parameter.
47
     *
48
     * @param id         the component id
49
     * @param queryName  the name of the API query to be executed
50
     * @param paramKey   the key of the parameter to be passed to the API query
51
     * @param paramValue the value of the parameter to be passed to the API query
52
     */
53
    public ApiResultComponent(String id, String queryName, String paramKey, String paramValue) {
54
        this(id, queryName, getParams(paramKey, paramValue));
×
55
    }
×
56

57
    private static HashMap<String, String> getParams(String paramKey, String paramValue) {
58
        final HashMap<String, String> params = new HashMap<>();
×
59
        params.put(paramKey, paramValue);
×
60
        return params;
×
61
    }
62

63
    /**
64
     * Sets whether to show a loading icon while waiting for the API response.
65
     *
66
     * @param waitIconEnabled true to enable the wait icon, false to disable it
67
     */
68
    public void setWaitIconEnabled(boolean waitIconEnabled) {
69
        this.waitIconEnabled = waitIconEnabled;
×
70
    }
×
71

72
    /**
73
     * Sets a custom message to be displayed while waiting for the API response.
74
     *
75
     * @param waitMessage the message to display
76
     */
77
    public void setWaitMessage(String waitMessage) {
78
        this.waitMessage = waitMessage;
×
79
    }
×
80

81
    /**
82
     * Sets a custom HTML component to be displayed while waiting for the API response.
83
     *
84
     * @param waitComponentHtml the HTML string to display
85
     */
86
    public void setWaitComponentHtml(String waitComponentHtml) {
87
        this.waitComponentHtml = waitComponentHtml;
×
88
    }
×
89

90
    /**
91
     * {@inheritDoc}
92
     */
93
    @Override
94
    public Component getLazyLoadComponent(String markupId) {
95
        while (true) {
96
            if (!ApiCache.isRunning(queryName, params)) {
×
97
                try {
98
                    response = ApiCache.retrieveResponse(queryName, params);
×
99
                    if (response != null) break;
×
100
                } catch (Exception ex) {
×
101
                    return new Label(markupId, "<span class=\"negative\">API call failed.</span>").setEscapeModelStrings(false);
×
102
                }
×
103
            }
104
            try {
105
                Thread.sleep(100);
×
106
            } catch (InterruptedException ex) {
×
107
                logger.error("Interrupted while waiting for API response", ex);
×
108
            }
×
109
        }
110
        return getApiResultComponent(markupId, response);
×
111
    }
112

113
    /**
114
     * {@inheritDoc}
115
     */
116
    @Override
117
    public Component getLoadingComponent(String id) {
118
        if (!waitIconEnabled) {
×
119
            return new Label(id);
×
120
        } else if (waitComponentHtml != null) {
×
121
            return new Label(id, waitComponentHtml).setEscapeModelStrings(false);
×
122
        } else if (waitMessage != null) {
×
123
            return new Label(id, getWaitComponentHtml(waitMessage)).setEscapeModelStrings(false);
×
124
        } else {
125
            return super.getLoadingComponent(id);
×
126
        }
127
    }
128

129
    /**
130
     * {@inheritDoc}
131
     */
132
    @Override
133
    protected boolean isContentReady() {
134
        return response != null || !ApiCache.isRunning(queryName, params);
×
135
    }
136

137
    /**
138
     * Abstract method to be implemented by subclasses to provide the component that displays the API result.
139
     *
140
     * @param markupId the markup ID for the component
141
     * @param response the API response to display
142
     * @return a Component that displays the API result
143
     */
144
    // TODO Use lambda instead of abstract method?
145
    public abstract Component getApiResultComponent(String markupId, ApiResponse response);
146

147
    /**
148
     * Returns the HTML for a loading icon.
149
     *
150
     * @return a string containing the HTML for the loading icon
151
     */
152
    public static String getWaitIconHtml() {
153
        IRequestHandler handler = new ResourceReferenceRequestHandler(AbstractDefaultAjaxBehavior.INDICATOR);
×
154
        return "<img alt=\"Loading...\" src=\"" + RequestCycle.get().urlFor(handler) + "\"/>";
×
155
    }
156

157
    /**
158
     * Returns the HTML for a waiting message with an icon.
159
     *
160
     * @param waitMessage the message to display while waiting
161
     * @return a string containing the HTML for the waiting message
162
     */
163
    public static String getWaitComponentHtml(String waitMessage) {
164
        return "<p class=\"waiting\">" + waitMessage + " " + getWaitIconHtml() + "</p>";
×
165
    }
166

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