Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ public interface SearchEngine {
*/
ResultPage search(String searchTerm, String groupId, int page, int pageSize);

/**
* Search for a given term in a collection within the group.
*
* @param searchTerm Term to search for.
* @param groupId Group id of the group that should be searched.
* @param collectionId id of the collection that should be searched.
* @param page Current page.
* @param pageSize page size of results.
* @return Page of results
*/
ResultPage search(String searchTerm, String groupId, String collectionId, int page, int pageSize);


/**
* Fetches the next and previous citation keys for the given search term in group and the current index and page number.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public ResultPage search(String searchTerm, String groupId, int page, int pageSi
.should(QueryBuilders.queryStringQuery(searchTerm).field("title").field("creators.name"));
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
boolBuilder.must(orFieldsBuilder).must(QueryBuilders.matchQuery("deleted", false)).must(QueryBuilders.matchQuery("group", groupId));

NativeSearchQueryBuilder b = new NativeSearchQueryBuilder().withQuery(boolBuilder).withPageable(PageRequest.of(page, pageSize));

AggregatedPage<Reference> results = template.queryForPage(b.build(), Reference.class);
Expand All @@ -65,6 +66,29 @@ public ResultPage search(String searchTerm, String groupId, int page, int pageSi
});
return new ResultPage(foundCitations, results.getTotalElements(), results.getTotalPages());
}

/**
* {@inheritDoc}
*
* This method searches in the title and creators name field for references that are
* not deleted in a collection within a group.
*
*/
@Override
public ResultPage search(String searchTerm, String groupId, String collectionId, int page, int pageSize) {
BoolQueryBuilder orFieldsBuilder = QueryBuilders.boolQuery()
.should(QueryBuilders.queryStringQuery(searchTerm).field("title").field("creators.name"));
BoolQueryBuilder boolBuilder = QueryBuilders.boolQuery();
boolBuilder.must(orFieldsBuilder).must(QueryBuilders.matchQuery("deleted", false)).must(QueryBuilders.matchQuery("group", groupId)).must(QueryBuilders.matchQuery("collections", collectionId));
NativeSearchQueryBuilder b = new NativeSearchQueryBuilder().withQuery(boolBuilder).withPageable(PageRequest.of(page, pageSize));
AggregatedPage<Reference> results = template.queryForPage(b.build(), Reference.class);
List<ICitation> foundCitations = new ArrayList<ICitation>();
results.get().forEach(r -> {

foundCitations.add(mapReference(r));
});
return new ResultPage(foundCitations, results.getTotalElements(), results.getTotalPages());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this pretty much the same code as in the search method above? DRY


@Override
public CitationPage getPrevAndNextCitation(String searchTerm, String groupId, int page, int index, int pageSize) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@

import edu.asu.diging.citesphere.core.search.service.SearchEngine;
import edu.asu.diging.citesphere.core.search.service.impl.ResultPage;
import edu.asu.diging.citesphere.core.service.ICitationCollectionManager;
import edu.asu.diging.citesphere.core.service.IGroupManager;
import edu.asu.diging.citesphere.model.bib.ICitation;
import edu.asu.diging.citesphere.model.bib.ICitationCollection;
import edu.asu.diging.citesphere.model.bib.ICitationGroup;
import edu.asu.diging.citesphere.user.IUser;
import edu.asu.diging.citesphere.web.BreadCrumb;
Expand All @@ -37,6 +39,9 @@ public class SearchController {

@Autowired
private IGroupManager groupManager;

@Autowired
private ICitationCollectionManager collectionManager;

@Value("${_zotero_page_size}")
private Integer zoteroPageSize;
Expand Down Expand Up @@ -101,4 +106,78 @@ public String search(@PathVariable String zoteroGroupId,
model.addAttribute("breadCrumbs", breadCrumbs);
return "auth/group/items";
}

@RequestMapping(value = {"/auth/group/{zoteroGroupId}/collection/{collectionId}/search"})
public String searchCollection(@PathVariable String zoteroGroupId,
@PathVariable(value="collectionId", required=false) String collectionId,
@RequestParam(value = "searchTerm", required = false) String searchTerm, Model model,
@RequestParam(defaultValue = "0", required = false, value = "page") String page,
@RequestParam(defaultValue = "title", required = false, value = "sort") String sort,
@RequestParam(required = false, value = "columns") String[] columns, Authentication authentication) {
IUser user = (IUser) authentication.getPrincipal();
ICitationGroup group = groupManager.getGroup(user, zoteroGroupId);

if (group == null) {
logger.error("User " + user.getUsername() + " does not have access to group " + zoteroGroupId);
return "error/404";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the user doesn't have access they should get a 403.

}

if (searchTerm == null || searchTerm.trim().isEmpty()) {
return "redirect:/auth/group/" + zoteroGroupId + "/collection/" + collectionId + "/items";
}

Integer pageInt = 1;
try {
pageInt = new Integer(page);
} catch (NumberFormatException ex) {
logger.warn("Trying to access invalid page number: " + page);
}

pageInt = pageInt > 0 ? pageInt : 1;

ResultPage citations = engine.search(searchTerm, zoteroGroupId, collectionId, pageInt-1, 50);

model.addAttribute("searchTerm", searchTerm);
model.addAttribute("items", citations.getResults());
model.addAttribute("totalPages", Math.max(1, citations.getTotalPages()));
model.addAttribute("total", citations.getTotalResults());
model.addAttribute("currentPage", pageInt);
model.addAttribute("zoteroGroupId", zoteroGroupId);
model.addAttribute("collectionId", collectionId);
model.addAttribute("group", groupManager.getGroup(user, zoteroGroupId));
model.addAttribute("sort", sort);

List<String> allowedColumns = Arrays.asList(availableColumns.split(","));
List<String> shownColumns = new ArrayList<>();
if (columns != null && columns.length > 0) {
for (String column : columns) {
if (allowedColumns.contains(column)) {
shownColumns.add(column);
}
}
}
model.addAttribute("columns", shownColumns);
model.addAttribute("availableColumns", allowedColumns);

List<BreadCrumb> breadCrumbs = new ArrayList<>();
ICitationCollection collection = null;
if (collectionId != null) {
collection = collectionManager.getCollection(user, zoteroGroupId, collectionId);
if(collection != null) {
model.addAttribute("collectionName", collection.getName());
}
}
while(collection != null) {
breadCrumbs.add(new BreadCrumb(collection.getName(), BreadCrumbType.COLLECTION, collection.getKey(), collection));
if (collection.getParentCollectionKey() != null) {
collection = collectionManager.getCollection(user, zoteroGroupId, collection.getParentCollectionKey());
} else {
collection = null;
}
}
breadCrumbs.add(new BreadCrumb(group.getName(), BreadCrumbType.GROUP, group.getGroupId() + "", group));
Collections.reverse(breadCrumbs);
model.addAttribute("breadCrumbs", breadCrumbs);
return "auth/group/items";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that looks like a lot of duplicate code; should be more DRY.

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, looks like pretty much the same as the above method. I actually doubt you'll need two separate methods.

}