1 package eu.fbk.knowledgestore.server.http;
2
3 import java.io.Serializable;
4 import java.util.List;
5 import java.util.Set;
6
7 import javax.annotation.Nullable;
8
9 import com.google.common.base.MoreObjects;
10 import com.google.common.base.Objects;
11 import com.google.common.base.Preconditions;
12 import com.google.common.base.Splitter;
13 import com.google.common.collect.ImmutableList;
14 import com.google.common.collect.ImmutableSet;
15
16 import org.openrdf.model.URI;
17 import org.openrdf.model.impl.URIImpl;
18 import org.openrdf.model.vocabulary.DCTERMS;
19 import org.openrdf.model.vocabulary.RDF;
20
21 import eu.fbk.knowledgestore.data.XPath;
22 import eu.fbk.knowledgestore.vocabulary.KS;
23
24 public final class UIConfig implements Serializable {
25
26 private static final long serialVersionUID = 1L;
27
28 private static final int DEFAULT_RESULT_LIMIT = 100;
29
30 private static final Set<URI> DEFAULT_RESOURCE_OVERVIEW_PROPERTIES = ImmutableSet.of(
31 DCTERMS.CREATED, DCTERMS.TITLE);
32
33 private static final Set<URI> DEFAULT_MENTION_OVERVIEW_PROPERTIES = ImmutableSet.of(
34 RDF.TYPE, KS.REFERS_TO);
35
36 private static final URI DEFAULT_DENOTED_BY_PROPERTY = new URIImpl(
37 "http://groundedannotationframework.org/gaf#denotedBy");
38
39 private static final boolean DEFAULT_DENOTED_BY_ALLOWS_GRAPHS = true;
40
41 private static final boolean DEFAULT_REFERS_TO_FUNCTIONAL = true;
42
43 private final int resultLimit;
44
45 private final List<URI> resourceOverviewProperties;
46
47 private final List<URI> mentionOverviewProperties;
48
49 private final List<Category> mentionCategories;
50
51 private final List<Example> lookupExamples;
52
53 private final List<Example> sparqlExamples;
54
55 private final URI denotedByProperty;
56
57 private final boolean denotedByAllowsGraphs;
58
59 private final boolean refersToFunctional;
60
61 private UIConfig(final Builder builder) {
62 this.resultLimit = MoreObjects.firstNonNull(builder.resultLimit, DEFAULT_RESULT_LIMIT);
63 this.resourceOverviewProperties = ImmutableList.copyOf(MoreObjects.firstNonNull(
64 builder.resourceOverviewProperties, DEFAULT_RESOURCE_OVERVIEW_PROPERTIES));
65 this.mentionOverviewProperties = ImmutableList.copyOf(MoreObjects.firstNonNull(
66 builder.mentionOverviewProperties, DEFAULT_MENTION_OVERVIEW_PROPERTIES));
67 this.mentionCategories = builder.mentionCategories == null ? ImmutableList.<Category>of()
68 : ImmutableList.copyOf(builder.mentionCategories);
69 this.lookupExamples = builder.lookupExamples == null ? ImmutableList.<Example>of()
70 : ImmutableList.copyOf(builder.lookupExamples);
71 this.sparqlExamples = builder.sparqlExamples == null ? ImmutableList.<Example>of()
72 : ImmutableList.copyOf(builder.sparqlExamples);
73 this.denotedByProperty = builder.denotedByProperty == null ? DEFAULT_DENOTED_BY_PROPERTY
74 : builder.denotedByProperty;
75 this.denotedByAllowsGraphs = builder.denotedByAllowsGraphs == null ? DEFAULT_DENOTED_BY_ALLOWS_GRAPHS
76 : builder.denotedByAllowsGraphs;
77 this.refersToFunctional = builder.refersToFunctional == null ? DEFAULT_REFERS_TO_FUNCTIONAL
78 : builder.refersToFunctional;
79 }
80
81 public static Builder builder() {
82 return new Builder();
83 }
84
85 public int getResultLimit() {
86 return this.resultLimit;
87 }
88
89 public List<URI> getResourceOverviewProperties() {
90 return this.resourceOverviewProperties;
91 }
92
93 public List<URI> getMentionOverviewProperties() {
94 return this.mentionOverviewProperties;
95 }
96
97 public List<Category> getMentionCategories() {
98 return this.mentionCategories;
99 }
100
101 public List<Example> getLookupExamples() {
102 return this.lookupExamples;
103 }
104
105 public List<Example> getSparqlExamples() {
106 return this.sparqlExamples;
107 }
108
109 public URI getDenotedByProperty() {
110 return this.denotedByProperty;
111 }
112
113 public boolean isDenotedByAllowsGraphs() {
114 return this.denotedByAllowsGraphs;
115 }
116
117 public boolean isRefersToFunctional() {
118 return this.refersToFunctional;
119 }
120
121 @Override
122 public boolean equals(final Object object) {
123 if (object == this) {
124 return true;
125 }
126 if (!(object instanceof UIConfig)) {
127 return false;
128 }
129 final UIConfig other = (UIConfig) object;
130 return this.resultLimit == other.resultLimit
131 && this.resourceOverviewProperties.equals(other.resourceOverviewProperties)
132 && this.mentionOverviewProperties.equals(other.mentionOverviewProperties)
133 && this.mentionCategories.equals(other.mentionCategories)
134 && this.lookupExamples.equals(other.lookupExamples)
135 && this.sparqlExamples.equals(other.sparqlExamples);
136 }
137
138 @Override
139 public int hashCode() {
140 return Objects.hashCode(this.resultLimit, this.resourceOverviewProperties,
141 this.mentionOverviewProperties, this.mentionCategories, this.lookupExamples,
142 this.sparqlExamples);
143 }
144
145 @Override
146 public String toString() {
147 return MoreObjects.toStringHelper(this).add("resultLimit", this.resultLimit)
148 .add("resourceOverviewProperties", this.resourceOverviewProperties)
149 .add("mentionOverviewProperties", this.mentionOverviewProperties)
150 .add("mentionCategories", this.mentionCategories)
151 .add("lookupExamples", this.lookupExamples)
152 .add("sparqlExamples", this.sparqlExamples).toString();
153 }
154
155 public static final class Category implements Serializable {
156
157 private static final long serialVersionUID = 1L;
158
159 private final String label;
160
161 private final String style;
162
163 private final XPath condition;
164
165 public Category(final String label, final String style, final XPath condition) {
166 this.label = Preconditions.checkNotNull(label);
167 this.style = Preconditions.checkNotNull(style);
168 this.condition = Preconditions.checkNotNull(condition);
169 }
170
171 public String getLabel() {
172 return this.label;
173 }
174
175 public String getStyle() {
176 return this.style;
177 }
178
179 public XPath getCondition() {
180 return this.condition;
181 }
182
183 @Override
184 public boolean equals(final Object object) {
185 if (object == this) {
186 return true;
187 }
188 if (!(object instanceof Category)) {
189 return false;
190 }
191 final Category other = (Category) object;
192 return this.label.equals(other.label)
193 && this.style.equals(other.style)
194 && this.condition.equals(other.condition);
195 }
196
197 @Override
198 public int hashCode() {
199 return Objects.hashCode(this.label, this.style, this.condition);
200 }
201
202 @Override
203 public String toString() {
204 return MoreObjects.toStringHelper(this)
205 .add("label", this.label)
206 .add("style", this.style)
207 .add("condition", this.condition)
208 .toString();
209 }
210
211 }
212
213 public static final class Example implements Serializable {
214
215 private static final long serialVersionUID = 1L;
216
217 private final String label;
218
219 private final String value;
220
221 public Example(final String label, final String value) {
222 this.label = Preconditions.checkNotNull(label);
223 this.value = normalizeMultilineString(Preconditions.checkNotNull(value));
224 }
225
226 public String getLabel() {
227 return this.label;
228 }
229
230 public String getValue() {
231 return this.value;
232 }
233
234 @Override
235 public boolean equals(final Object object) {
236 if (object == this) {
237 return true;
238 }
239 if (!(object instanceof Example)) {
240 return false;
241 }
242 final Example other = (Example) object;
243 return this.label.equals(other.label) && this.value.equals(other.value);
244 }
245
246 @Override
247 public int hashCode() {
248 return Objects.hashCode(this.label, this.value);
249 }
250
251 @Override
252 public String toString() {
253 return MoreObjects.toStringHelper(this)
254 .add("label", this.label)
255 .add("value", this.value)
256 .toString();
257 }
258
259 private static final String normalizeMultilineString(final String string) {
260
261 final List<String> lines = ImmutableList.copyOf(Splitter.on('\n').split(string));
262
263 int start = Integer.MAX_VALUE;
264 for (final String line : lines) {
265 int index = 0;
266 while (index < line.length() && Character.isSpaceChar(line.charAt(index))) {
267 ++index;
268 }
269 if (index < line.length()) {
270 start = Math.min(start, index);
271 }
272 }
273
274 String separator = "";
275 final StringBuilder builder = new StringBuilder();
276 for (final String line : lines) {
277 if (!line.trim().isEmpty()) {
278 builder.append(separator).append(
279 line.substring(Math.min(line.length(), start)));
280 separator = "\n";
281 }
282 }
283
284 return builder.toString();
285 }
286
287 }
288
289 public static final class Builder {
290
291 @Nullable
292 private Integer resultLimit;
293
294 @Nullable
295 private Iterable<? extends URI> resourceOverviewProperties;
296
297 @Nullable
298 private Iterable<? extends URI> mentionOverviewProperties;
299
300 @Nullable
301 private Iterable<? extends Category> mentionCategories;
302
303 @Nullable
304 private Iterable<? extends Example> lookupExamples;
305
306 @Nullable
307 private Iterable<? extends Example> sparqlExamples;
308
309 @Nullable
310 private URI denotedByProperty;
311
312 @Nullable
313 private Boolean denotedByAllowsGraphs;
314
315 @Nullable
316 private Boolean refersToFunctional;
317
318 public Builder resultLimit(@Nullable final Integer resultLimit) {
319 this.resultLimit = resultLimit;
320 return this;
321 }
322
323 public Builder resourceOverviewProperties(
324 @Nullable final Iterable<? extends URI> resourceOverviewProperties) {
325 this.resourceOverviewProperties = resourceOverviewProperties;
326 return this;
327 }
328
329 public Builder mentionOverviewProperties(
330 @Nullable final Iterable<? extends URI> mentionOverviewProperties) {
331 this.mentionOverviewProperties = mentionOverviewProperties;
332 return this;
333 }
334
335 public Builder mentionCategories(
336 @Nullable final Iterable<? extends Category> mentionCategories) {
337 this.mentionCategories = mentionCategories;
338 return this;
339 }
340
341 public Builder lookupExamples(@Nullable final Iterable<? extends Example> lookupExamples) {
342 this.lookupExamples = lookupExamples;
343 return this;
344 }
345
346 public Builder sparqlExamples(@Nullable final Iterable<? extends Example> sparqlExamples) {
347 this.sparqlExamples = sparqlExamples;
348 return this;
349 }
350
351 public Builder denotedByProperty(@Nullable final URI denotedByProperty) {
352 this.denotedByProperty = denotedByProperty;
353 return this;
354 }
355
356 public Builder denotedByAllowsGraphs(@Nullable final Boolean denotedByAllowsGraphs) {
357 this.denotedByAllowsGraphs = denotedByAllowsGraphs;
358 return this;
359 }
360
361 public Builder refersToFunctional(@Nullable final Boolean refersToFunctional) {
362 this.refersToFunctional = refersToFunctional;
363 return this;
364 }
365
366 public UIConfig build() {
367 return new UIConfig(this);
368 }
369
370 }
371
372 }