Skip to content

Commit 3e9c55b

Browse files
authored
Merge pull request #436 from TAMULib/sprint-7-staging
Sprint 7 Staging
2 parents 669eef0 + 0f4c936 commit 3e9c55b

File tree

10 files changed

+136
-46
lines changed

10 files changed

+136
-46
lines changed

src/main/java/edu/tamu/scholars/middleware/discovery/argument/BoostArg.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ public static BoostArg of(String parameter) {
2929
return new BoostArg(parts[0], parts.length > 1 ? Float.valueOf(parts[1]) : 1.0f);
3030
}
3131

32+
@Override
33+
public String toString() {
34+
return "BoostArg [field=" + field + ", value=" + value + "]";
35+
}
36+
3237
}

src/main/java/edu/tamu/scholars/middleware/discovery/argument/FilterArg.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,9 @@ public static FilterArg of(String field, Optional<String> value, Optional<String
5454
return new FilterArg(field, valueParam, opKeyParam, tagParam);
5555
}
5656

57+
@Override
58+
public String toString() {
59+
return "FilterArg [field=" + field + ", value=" + value + ", opKey=" + opKey + ", tag=" + tag + "]";
60+
}
61+
5762
}

src/main/java/edu/tamu/scholars/middleware/discovery/argument/QueryArg.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,11 @@ public static QueryArg of(
8181
return new QueryArg(expression, defaultField, minimumShouldMatch, queryField, boostQuery, field);
8282
}
8383

84+
@Override
85+
public String toString() {
86+
return "QueryArg [expression=" + expression + ", defaultField=" + defaultField + ", minimumShouldMatch="
87+
+ minimumShouldMatch + ", queryField=" + queryField + ", boostQuery=" + boostQuery + ", fields="
88+
+ fields + "]";
89+
}
90+
8491
}

src/main/java/edu/tamu/scholars/middleware/discovery/model/Individual.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,9 @@ public static Individual from(Map<String, Object> content) {
118118
return new Individual(content);
119119
}
120120

121+
@Override
122+
public String toString() {
123+
return "Individual [content=" + content + "]";
124+
}
125+
121126
}

src/main/java/edu/tamu/scholars/middleware/discovery/model/repo/IndividualRepo.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import java.util.List;
1717
import java.util.Objects;
1818
import java.util.Optional;
19+
import java.util.UUID;
20+
import java.util.concurrent.atomic.AtomicBoolean;
1921
import java.util.concurrent.atomic.AtomicLong;
2022
import java.util.regex.Matcher;
2123
import java.util.regex.Pattern;
@@ -208,25 +210,37 @@ public Flux<Individual> export(QueryArg query, List<FilterArg> filters, List<Boo
208210
.withSort(sort)
209211
.withRows(Integer.MAX_VALUE);
210212

213+
logger.info("{}: Exporting {} {} {} {}", builder.getId(), query, filters, boosts, sort);
214+
211215
return Flux.create(emitter -> {
212216
try {
213217
solrClient.queryAndStreamResponse(collectionName, builder.query(), new StreamingResponseCallback() {
214218
private final AtomicLong remaining = new AtomicLong(0);
219+
private final AtomicBoolean docListInfoReceived = new AtomicBoolean(false);
215220

216221
@Override
217222
public void streamSolrDocument(SolrDocument document) {
218-
emitter.next(Individual.from(document));
219-
220-
if (remaining.decrementAndGet() == 0) {
223+
Individual individual = Individual.from(document);
224+
logger.debug("{}: streamSolrDocument: {}", builder.getId(), individual);
225+
emitter.next(individual);
226+
227+
long numRemaining = remaining.decrementAndGet();
228+
logger.debug("{}: streamSolrDocument remaining: {}", builder.getId(), numRemaining);
229+
if (numRemaining == 0 && docListInfoReceived.get()) {
230+
logger.info("{}: streamSolrDocument COMPLETE", builder.getId());
221231
emitter.complete();
222232
}
223233
}
224234

225235
@Override
226236
public void streamDocListInfo(long numFound, long start, Float maxScore) {
227-
if (numFound > 0) {
228-
remaining.set(numFound);
229-
} else {
237+
logger.debug("{}: streamDocListInfo {} {} {}", builder.getId(), numFound, start, maxScore);
238+
239+
remaining.set(numFound);
240+
docListInfoReceived.set(true);
241+
242+
if (numFound == 0) {
243+
logger.info("{}: streamDocListInfo COMPLETE", builder.getId());
230244
emitter.complete();
231245
}
232246
}
@@ -443,14 +457,16 @@ private Page<Individual> findAllQuery(SolrQuery query, Pageable pageable) {
443457

444458
private List<String> getValues(SolrDocument document, List<String> dataFields) {
445459
return dataFields.stream()
446-
.filter(v -> document.containsKey(v))
460+
.filter(document::containsKey)
447461
.flatMap(v -> document.getFieldValues(v).stream())
448462
.map(v -> (String) v)
449463
.collect(Collectors.toList());
450464
}
451465

452466
private class SolrQueryBuilder {
453467

468+
private final UUID id;
469+
454470
private final SolrQuery query;
455471

456472
private final List<String> filters;
@@ -460,13 +476,18 @@ private SolrQueryBuilder() {
460476
}
461477

462478
private SolrQueryBuilder(String query) {
479+
this.id = UUID.randomUUID();
463480
this.query = new SolrQuery()
464481
.setParam("defType", defType)
465482
.setParam("q.op", defaultOperator)
466483
.setQuery(query);
467484
this.filters = new ArrayList<>();
468485
}
469486

487+
public String getId() {
488+
return id.toString();
489+
}
490+
470491
public SolrQueryBuilder withQuery(QueryArg query) {
471492

472493
if (StringUtils.isNotEmpty(query.getDefaultField())) {

src/main/java/edu/tamu/scholars/middleware/export/argument/ExportArg.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,9 @@ public static ExportArg of(String parameter) {
3939
return new ExportArg(parts[0], parts.length > 1 ? parts[1] : parts[0]);
4040
}
4141

42+
@Override
43+
public String toString() {
44+
return "ExportArg [field=" + field + ", label=" + label + "]";
45+
}
46+
4247
}

src/main/java/edu/tamu/scholars/middleware/export/controller/IndividualSearchExportController.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import java.util.Optional;
1212
import java.util.concurrent.ExecutionException;
1313

14+
import org.slf4j.Logger;
15+
import org.slf4j.LoggerFactory;
1416
import org.springframework.beans.factory.annotation.Autowired;
1517
import org.springframework.context.annotation.Lazy;
1618
import org.springframework.data.domain.Sort;
@@ -40,6 +42,8 @@
4042
@RestController
4143
public class IndividualSearchExportController implements RepresentationModelProcessor<RepositorySearchesResource> {
4244

45+
private static final Logger logger = LoggerFactory.getLogger(IndividualSearchExportController.class);
46+
4347
@Lazy
4448
@Autowired
4549
private IndividualRepo repo;
@@ -58,7 +62,9 @@ public ResponseEntity<StreamingResponseBody> export(
5862
List<BoostArg> boosts,
5963
List<ExportArg> export
6064
) throws UnknownExporterTypeException, InterruptedException, ExecutionException {
65+
logger.info("/individual/search/export {} {} {} {} {} {} {}", view, type, query, sort, filters, boosts, export);
6166
Exporter exporter = exporterRegistry.getExporter(type);
67+
6268
return ResponseEntity.ok()
6369
.header(CONTENT_DISPOSITION, exporter.contentDisposition(FilenameUtility.normalizeExportFilename(view)))
6470
.header(CONTENT_TYPE, exporter.contentType())

src/main/java/edu/tamu/scholars/middleware/export/service/CsvExporter.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import java.io.IOException;
66
import java.io.OutputStreamWriter;
77
import java.util.ArrayList;
8+
import java.util.Date;
89
import java.util.List;
910
import java.util.Map;
1011
import java.util.stream.Collectors;
@@ -21,6 +22,7 @@
2122
import edu.tamu.scholars.middleware.discovery.exception.InvalidValuePathException;
2223
import edu.tamu.scholars.middleware.discovery.model.Individual;
2324
import edu.tamu.scholars.middleware.export.argument.ExportArg;
25+
import edu.tamu.scholars.middleware.utility.DateFormatUtility;
2426

2527
/**
2628
*
@@ -67,7 +69,14 @@ public StreamingResponseBody streamIndividuals(Flux<Individual> individuals, Lis
6769
.map(e -> e.getField())
6870
.collect(Collectors.toList());
6971
try (CSVPrinter printer = new CSVPrinter(outputStreamWriter, format)) {
70-
individuals.subscribe(
72+
individuals.doOnComplete(() -> {
73+
try {
74+
printer.flush();
75+
} catch (IOException e) {
76+
e.printStackTrace();
77+
throw new RuntimeException("Failed to flush CSV printer", e);
78+
}
79+
}).subscribe(
7180
individual -> {
7281
try {
7382
List<Object> row = getRow(individual, properties);
@@ -78,16 +87,11 @@ public StreamingResponseBody streamIndividuals(Flux<Individual> individuals, Lis
7887
| IOException e
7988
) {
8089
e.printStackTrace();
90+
throw new RuntimeException("Failed mapping and printing individuals", e);
8191
}
82-
}, error -> {
83-
throw new RuntimeException("Failed attempting to stream individuals", error);
84-
},
85-
() -> {
86-
try {
87-
printer.flush();
88-
} catch (IOException e) {
89-
e.printStackTrace();
90-
}
92+
}, e -> {
93+
e.printStackTrace();
94+
throw new RuntimeException("Failed attempting to stream individuals", e);
9195
}
9296
);
9397
} catch (IllegalArgumentException e) {
@@ -136,6 +140,8 @@ private List<Object> getRow(
136140
.collect(Collectors.toList()));
137141
}
138142

143+
} else if (Date.class.isAssignableFrom(value.getClass())) {
144+
data = DateFormatUtility.format((Date) value);
139145
} else {
140146
data = (String) value;
141147
}

src/main/java/edu/tamu/scholars/middleware/utility/DateFormatUtility.java

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.time.Instant;
55
import java.time.ZoneId;
66
import java.time.ZonedDateTime;
7+
import java.time.format.DateTimeFormatter;
78
import java.util.Date;
89
import java.util.Locale;
910

@@ -15,35 +16,50 @@
1516
*/
1617
public class DateFormatUtility {
1718

18-
private static final String[] datePatterns = {
19-
"yyyy",
20-
"E MMM dd HH:mm:ss z yyyy",
21-
"yyyy-MM-dd'T'HH:mm:ss'Z'",
22-
"yyyy-MM-dd'T'HH:mm:ss",
23-
"dd-MM-yy",
24-
"MM-dd-yyyy",
25-
"yyyy-MM-dd HH:mm:ss",
26-
"EEEEE MMMMM yyyy HH:mm:ss.SSSZ"
19+
private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
20+
21+
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT);
22+
23+
private static final String[] DATE_PATTERNS = {
24+
DATE_FORMAT,
25+
"yyyy",
26+
"E MMM dd HH:mm:ss z yyyy",
27+
"yyyy-MM-dd'T'HH:mm:ss'Z'",
28+
"yyyy-MM-dd'T'HH:mm:ss",
29+
"dd-MM-yy",
30+
"MM-dd-yyyy",
31+
"EEEEE MMMMM yyyy HH:mm:ss.SSSZ"
2732
};
2833

29-
public static String parseYear(String value) throws IllegalArgumentException, ParseException {
34+
private DateFormatUtility() {
35+
36+
}
37+
38+
public static String parseYear(String value) throws ParseException {
3039
return String.valueOf(parseZonedDateTime(value).getYear());
3140
}
3241

33-
public static ZonedDateTime parseZonedDateTime(String value) throws IllegalArgumentException, ParseException {
42+
public static String format(Date date) {
43+
return date.toInstant()
44+
.atZone(ZoneId.systemDefault())
45+
.toLocalDateTime()
46+
.format(DATE_FORMATTER);
47+
}
48+
49+
public static ZonedDateTime parseZonedDateTime(String value) throws ParseException {
3450
return parseDate(value)
35-
.toInstant()
36-
.atZone(ZoneId.systemDefault());
51+
.toInstant()
52+
.atZone(ZoneId.systemDefault());
3753
}
3854

39-
public static Date parseDate(String value) throws IllegalArgumentException, ParseException {
55+
public static Date parseDate(String value) throws ParseException {
4056
Locale locale = LocaleContextHolder.getLocale();
41-
return DateUtils.parseDate(value, locale, datePatterns);
57+
return DateUtils.parseDate(value, locale, DATE_PATTERNS);
4258
}
4359

4460
public static int getYear() {
4561
return ZonedDateTime.ofInstant(Instant.now(), ZoneId.systemDefault())
46-
.getYear();
62+
.getYear();
4763
}
4864

4965
}

src/main/resources/defaults/displayViews.yml

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,22 @@
322322
- field: title
323323
direction: ASC
324324
template: "defaults/displayViews/persons/publications/selectedPublications/default.html"
325-
- name: Theses
325+
- name: Datasets
326326
field: publications
327327
order: 6
328+
filters:
329+
- field: type
330+
value: Dataset
331+
sort:
332+
- field: publicationDate
333+
direction: DESC
334+
date: true
335+
- field: title
336+
direction: ASC
337+
template: "defaults/displayViews/persons/publications/selectedPublications/default.html"
338+
- name: Theses
339+
field: publications
340+
order: 7
328341
filters:
329342
- field: type
330343
value: Thesis
@@ -337,7 +350,7 @@
337350
template: "defaults/displayViews/persons/publications/selectedPublications/thesis.html"
338351
- name: Working Papers
339352
field: publications
340-
order: 7
353+
order: 8
341354
filters:
342355
- field: type
343356
value: WorkingPaper
@@ -350,7 +363,7 @@
350363
template: "defaults/displayViews/persons/publications/selectedPublications/default.html"
351364
- name: Internet Publications
352365
field: publications
353-
order: 8
366+
order: 9
354367
filters:
355368
- field: type
356369
value: Webpage
@@ -363,7 +376,7 @@
363376
template: "defaults/displayViews/persons/publications/selectedPublications/internetPublication.html"
364377
- name: Reports
365378
field: publications
366-
order: 9
379+
order: 10
367380
filters:
368381
- field: type
369382
value: Report
@@ -376,7 +389,7 @@
376389
template: "defaults/displayViews/persons/publications/selectedPublications/report.html"
377390
- name: Reviews
378391
field: publications
379-
order: 10
392+
order: 11
380393
filters:
381394
- field: type
382395
value: Review
@@ -1439,20 +1452,21 @@
14391452
- name: Documents
14401453
types:
14411454
- AcademicArticle
1442-
- ConferencePaper
1443-
- Thesis
1444-
- Chapter
14451455
- Book
1456+
- Capstone
1457+
- Chapter
1458+
- ConferencePaper
1459+
- Dataset
14461460
- GreyLiterature
1447-
- Patent
1448-
- WorkingPaper
14491461
- NewsRelease
1450-
- ERO_0000071
1451-
- Capstone
1452-
- Webpage
1462+
- Patent
14531463
- Report
14541464
- Review
14551465
- TeachingMaterial
1466+
- Thesis
1467+
- Webpage
1468+
- WorkingPaper
1469+
- ERO_0000071
14561470
mainContentTemplate: "defaults/displayViews/documents/mainContentTemplate.html"
14571471
rightScanTemplate: "defaults/displayViews/documents/rightScanTemplate.html"
14581472
metaTemplates:

0 commit comments

Comments
 (0)