Mercurial > hg > LGDataverses
diff src/main/java/edu/harvard/iq/dataverse/SearchIncludeFragment.java @ 10:a50cf11e5178
Rewrite LGDataverse completely upgrading to dataverse4.0
| author | Zoe Hong <zhong@mpiwg-berlin.mpg.de> |
|---|---|
| date | Tue, 08 Sep 2015 17:00:21 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/edu/harvard/iq/dataverse/SearchIncludeFragment.java Tue Sep 08 17:00:21 2015 +0200 @@ -0,0 +1,1101 @@ +package edu.harvard.iq.dataverse; + +import edu.harvard.iq.dataverse.search.SearchFields; +import edu.harvard.iq.dataverse.authorization.users.GuestUser; +import edu.harvard.iq.dataverse.search.SearchException; +import edu.harvard.iq.dataverse.settings.SettingsServiceBean; +import edu.harvard.iq.dataverse.util.SystemConfig; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; +import javax.ejb.EJB; +import javax.faces.view.ViewScoped; +import javax.inject.Inject; +import javax.inject.Named; +import org.apache.commons.lang.StringUtils; + +@ViewScoped +@Named("SearchIncludeFragment") +public class SearchIncludeFragment implements java.io.Serializable { + + private static final Logger logger = Logger.getLogger(SearchIncludeFragment.class.getCanonicalName()); + + @EJB + SearchServiceBean searchService; + @EJB + DataverseServiceBean dataverseService; + @EJB + DatasetServiceBean datasetService; + @EJB + DatasetVersionServiceBean datasetVersionService; + @EJB + DataFileServiceBean dataFileService; + @EJB + PermissionServiceBean permissionService; + @EJB + SettingsServiceBean settingsService; + @EJB + SystemConfig systemConfig; + @Inject + DataverseSession session; + + private String browseModeString = "browse"; + private String searchModeString = "search"; + private String mode; + private String query; + private List<String> filterQueries = new ArrayList<>(); + private List<FacetCategory> facetCategoryList = new ArrayList<>(); + private List<SolrSearchResult> searchResultsList = new ArrayList<>(); + private int searchResultsCount; + private String fq0; + private String fq1; + private String fq2; + private String fq3; + private String fq4; + private String fq5; + private String fq6; + private String fq7; + private String fq8; + private String fq9; + private String dataverseAlias; + private Dataverse dataverse; + // commenting out dataverseSubtreeContext. it was not well-loved in the GUI +// private String dataverseSubtreeContext; + private String selectedTypesString; + private List<String> selectedTypesList = new ArrayList<String>(); + private String selectedTypesHumanReadable; + private String searchFieldType = SearchFields.TYPE; + private String searchFieldSubtree = SearchFields.SUBTREE; +// private String searchFieldHostDataverse = SearchFields.HOST_DATAVERSE; + private String searchFieldNameSort = SearchFields.NAME_SORT; + private String searchFieldRelevance = SearchFields.RELEVANCE; +// private String searchFieldReleaseDate = SearchFields.RELEASE_DATE_YYYY; + private String searchFieldReleaseOrCreateDate = SearchFields.RELEASE_OR_CREATE_DATE; + final private String ASCENDING = "asc"; + final private String DESCENDING = "desc"; + private String typeFilterQuery; + private Long facetCountDataverses = 0L; + private Long facetCountDatasets = 0L; + private Long facetCountFiles = 0L; + Map<String, Long> previewCountbyType = new HashMap<>(); + private SolrQueryResponse solrQueryResponseAllTypes; + private String sortField; + private String sortOrder; + private String currentSort; + private String currentSortFriendly; + private int page = 1; + private int paginationGuiStart = 1; + private int paginationGuiEnd = 10; + private int paginationGuiRows = 10; + Map<String, String> datasetfieldFriendlyNamesBySolrField = new HashMap<>(); + Map<String, String> staticSolrFieldFriendlyNamesBySolrField = new HashMap<>(); + private boolean solrIsDown = false; + private Map<String, Integer> numberOfFacets = new HashMap<>(); + private boolean debug = false; +// private boolean showUnpublished; + List<String> filterQueriesDebug = new ArrayList<>(); +// private Map<String, String> friendlyName = new HashMap<>(); + private String errorFromSolr; + private SearchException searchException; + + /** + * @todo: + * + * better style and icons for facets + * + * replace * with watermark saying "Search this Dataverse" + * + * get rid of "_s" et al. (human eyeball friendly) + * + * pagination (previous/next links) + * + * test dataset cards + * + * test files cards + * + * test dataset cards when Solr is down + * + * make results sortable: https://redmine.hmdc.harvard.edu/issues/3482 + * + * always show all types, even if zero count: + * https://redmine.hmdc.harvard.edu/issues/3488 + * + * make subtree facet look like amazon widget (i.e. a tree) + * + * see also https://trello.com/c/jmry3BJR/28-browse-dataverses + */ + public String searchRedirect(String dataverseRedirectPage) { + /** + * These are our decided-upon search/browse rules, the way we expect + * users to search/browse and how we want the app behave: + * + * 1. When a user is browsing (i.e. hasn't entered a search term) we + * only show dataverses and datasets. Files are hidden. See + * https://redmine.hmdc.harvard.edu/issues/3573 + * + * 2. A search is always brand new. Don't keep around old facets that + * were selected. Show page 1 of results. Make the results bookmarkable: + * https://redmine.hmdc.harvard.edu/issues/3664 + * + * 3. When you add or remove a facet, you should always go to page 1 of + * search results. Search terms should be preserved. Sorting should be + * preserved. + * + * 4. After search terms have been entered and facets have been + * selected, we expect users to (optionally) page through search results + * and as they do so we will preserve the state of their search terms, + * their facet selections, and their sorting. + * + * 5. Someday the default sort order for browse mode will be by "release + * date" (newest first) but that functionality is not yet available in + * the system ( see https://redmine.hmdc.harvard.edu/issues/3628 and + * https://redmine.hmdc.harvard.edu/issues/3629 ) so for now the default + * sort order for browse mode will by alphabetical (sort by name, + * ascending). The default sort order for search mode will be by + * relevance. (We only offer ascending ordering for relevance since + * descending order is unlikely to be useful.) When you sort, facet + * selections and what page you are on should be preserved. + * + */ + + dataverseRedirectPage = StringUtils.isBlank(dataverseRedirectPage) ? "dataverse.xhtml" : dataverseRedirectPage; + String optionalDataverseScope = "&alias=" + dataverse.getAlias(); + + return dataverseRedirectPage + "?faces-redirect=true&q=" + query + optionalDataverseScope; + + } + + public void search() { + search(false); + } + + public void search(boolean onlyDataRelatedToMe) { + logger.fine("search called"); + + // wildcard/browse (*) unless user supplies a query + String queryToPassToSolr = "*"; + if (this.query == null) { + mode = browseModeString; + } else if (this.query.isEmpty()) { + mode = browseModeString; + } else { + mode = searchModeString; + } + + if (mode.equals(browseModeString)) { + queryToPassToSolr = "*"; + if (sortField == null) { + sortField = searchFieldReleaseOrCreateDate; + } + if (sortOrder == null) { + sortOrder = DESCENDING; + } + if (selectedTypesString == null || selectedTypesString.isEmpty()) { + selectedTypesString = "dataverses:datasets"; + } + } else if (mode.equals(searchModeString)) { + queryToPassToSolr = query; + if (sortField == null) { + sortField = searchFieldRelevance; + } + if (sortOrder == null) { + sortOrder = DESCENDING; + } + if (selectedTypesString == null || selectedTypesString.isEmpty()) { + selectedTypesString = "dataverses:datasets:files"; + } + } + + filterQueries = new ArrayList<>(); + for (String fq : Arrays.asList(fq0, fq1, fq2, fq3, fq4, fq5, fq6, fq7, fq8, fq9)) { + if (fq != null) { + filterQueries.add(fq); + } + } + + SolrQueryResponse solrQueryResponse = null; + + List<String> filterQueriesFinal = new ArrayList<>(); + if (dataverseAlias != null) { + this.dataverse = dataverseService.findByAlias(dataverseAlias); + } + if (this.dataverse != null) { + String dataversePath = dataverseService.determineDataversePath(this.dataverse); + String filterDownToSubtree = SearchFields.SUBTREE + ":\"" + dataversePath + "\""; + if (!this.dataverse.equals(dataverseService.findRootDataverse())) { + /** + * @todo centralize this into SearchServiceBean + */ + filterQueriesFinal.add(filterDownToSubtree); +// this.dataverseSubtreeContext = dataversePath; + } else { +// this.dataverseSubtreeContext = "all"; + } + } else { + this.dataverse = dataverseService.findRootDataverse(); +// this.dataverseSubtreeContext = "all"; + } + + selectedTypesList = new ArrayList<>(); + String[] parts = selectedTypesString.split(":"); +// int count = 0; + for (String string : parts) { + selectedTypesList.add(string); + } + + List<String> filterQueriesFinalAllTypes = new ArrayList<>(); + String[] arr = selectedTypesList.toArray(new String[selectedTypesList.size()]); + selectedTypesHumanReadable = combine(arr, " OR "); + if (!selectedTypesHumanReadable.isEmpty()) { + typeFilterQuery = SearchFields.TYPE + ":(" + selectedTypesHumanReadable + ")"; + } + filterQueriesFinal.addAll(filterQueries); + filterQueriesFinalAllTypes.addAll(filterQueriesFinal); + filterQueriesFinal.add(typeFilterQuery); + String allTypesFilterQuery = SearchFields.TYPE + ":(dataverses OR datasets OR files)"; + filterQueriesFinalAllTypes.add(allTypesFilterQuery); + + int paginationStart = (page - 1) * paginationGuiRows; + /** + * @todo + * + * design/make room for sort widget drop down: + * https://redmine.hmdc.harvard.edu/issues/3482 + * + */ + + try { + logger.fine("query from user: " + query); + logger.fine("queryToPassToSolr: " + queryToPassToSolr); + logger.fine("sort by: " + sortField); + + /** + * @todo Number of search results per page should be configurable - + * https://github.com/IQSS/dataverse/issues/84 + */ + int numRows = 10; + solrQueryResponse = searchService.search(session.getUser(), dataverse, queryToPassToSolr, filterQueriesFinal, sortField, sortOrder, paginationStart, onlyDataRelatedToMe, numRows); + solrQueryResponseAllTypes = searchService.search(session.getUser(), dataverse, queryToPassToSolr, filterQueriesFinalAllTypes, sortField, sortOrder, paginationStart, onlyDataRelatedToMe, numRows); + } catch (SearchException ex) { + Throwable cause = ex; + StringBuilder sb = new StringBuilder(); + sb.append(cause + " "); + while (cause.getCause() != null) { + cause = cause.getCause(); + sb.append(cause.getClass().getCanonicalName() + " "); + sb.append(cause + " "); + } + String message = "Exception running search for [" + queryToPassToSolr + "] with filterQueries " + filterQueries + " and paginationStart [" + paginationStart + "]: " + sb.toString(); + logger.info(message); + this.solrIsDown = true; + this.searchException = ex; + } + if (!solrIsDown) { + this.facetCategoryList = solrQueryResponse.getFacetCategoryList(); + this.searchResultsList = solrQueryResponse.getSolrSearchResults(); + this.searchResultsCount = solrQueryResponse.getNumResultsFound().intValue(); + this.datasetfieldFriendlyNamesBySolrField = solrQueryResponse.getDatasetfieldFriendlyNamesBySolrField(); + this.staticSolrFieldFriendlyNamesBySolrField = solrQueryResponse.getStaticSolrFieldFriendlyNamesBySolrField(); + this.filterQueriesDebug = solrQueryResponse.getFilterQueriesActual(); + this.errorFromSolr = solrQueryResponse.getError(); + paginationGuiStart = paginationStart + 1; + paginationGuiEnd = Math.min(page * paginationGuiRows, searchResultsCount); + List<SolrSearchResult> searchResults = solrQueryResponse.getSolrSearchResults(); + + /** + * @todo consider creating Java objects called DatasetCard, + * DatasetCart, and FileCard since that's what we call them in the + * UI. These objects' fields (affiliation, citation, etc.) would be + * populated from Solr if possible (for performance, to avoid extra + * database calls) or by a database call (if it's tricky or doesn't + * make sense to get the data in and out of Solr). We would continue + * to iterate through all the SolrSearchResult objects as we build + * up the new card objects. Think about how we have a + * solrSearchResult.setCitation method but only the dataset card in + * the UI (currently) shows this "citation" field. + */ + for (SolrSearchResult solrSearchResult : searchResults) { + if (solrSearchResult.getEntityId() == null) { + // avoiding EJBException a la https://redmine.hmdc.harvard.edu/issues/3809 + logger.warning(SearchFields.ENTITY_ID + " was null for Solr document id:" + solrSearchResult.getId() + ", skipping. Bad Solr data?"); + break; + } + if (solrSearchResult.getType().equals("dataverses")) { + Dataverse dataverseInCard = dataverseService.find(solrSearchResult.getEntityId()); + String parentId = solrSearchResult.getParent().get("id"); + solrSearchResult.setIsInTree(false); + if (parentId != null) { + Dataverse parentDataverseInCard = dataverseService.find(Long.parseLong(parentId)); + solrSearchResult.setDataverseParentAlias(parentDataverseInCard.getAlias()); + List<Dataverse> dvTree = new ArrayList(); + Dataverse testDV = parentDataverseInCard; + dvTree.add(testDV); + while (testDV.getOwner() != null) { + dvTree.add(testDV.getOwner()); + testDV = testDV.getOwner(); + } + if (dvTree.contains(dataverse)) { + solrSearchResult.setIsInTree(true); + } + } + + if (dataverseInCard != null) { + solrSearchResult.setDataverseAffiliation(dataverseInCard.getAffiliation()); + solrSearchResult.setStatus(getCreatedOrReleasedDate(dataverseInCard, solrSearchResult.getReleaseOrCreateDate())); + solrSearchResult.setDataverseAlias(dataverseInCard.getAlias()); + } + } else if (solrSearchResult.getType().equals("datasets")) { + Long dataverseId = Long.parseLong(solrSearchResult.getParent().get("id")); + Dataverse parentDataverse = dataverseService.find(dataverseId); + solrSearchResult.setIsInTree(false); + List<Dataverse> dvTree = new ArrayList(); + Dataverse testDV = parentDataverse; + dvTree.add(testDV); + /** + * @todo Why is a NPE being thrown at this `while + * (testDV.getOwner() != null){` line? An NPE was being + * thrown while browsing the site *after* issuing the + * DestroyDatasetCommand but before a fix was put in to + * remove the dataset "card" from Solr. The ticket tracking + * this that fix is + * https://github.com/IQSS/dataverse/issues/1316 but it's + * unclear why the NPE was thrown. The users see a nasty + * "Internal Server Error - An unexpected error was + * encountered, no more information is available." and + * server.log has a stacktrace with the NPE. + */ + while (testDV.getOwner() != null) { + dvTree.add(testDV.getOwner()); + testDV = testDV.getOwner(); + } + if (dvTree.contains(dataverse)) { + solrSearchResult.setIsInTree(true); + } + /** + * @todo can a dataverse alias ever be null? + */ + solrSearchResult.setDataverseAlias(parentDataverse.getAlias()); + Long datasetVersionId = solrSearchResult.getDatasetVersionId(); + if (datasetVersionId != null) { + DatasetVersion datasetVersion = datasetVersionService.find(datasetVersionId); + if (datasetVersion != null) { + if (datasetVersion.isDeaccessioned()) { + solrSearchResult.setDeaccessionedState(true); + } + + } + } + String deaccesssionReason = solrSearchResult.getDeaccessionReason(); + if (deaccesssionReason != null) { + solrSearchResult.setDescriptionNoSnippet(deaccesssionReason); + } + } else if (solrSearchResult.getType().equals("files")) { + DataFile dataFile = dataFileService.find(solrSearchResult.getEntityId()); + if (dataFile != null) { + solrSearchResult.setStatus(getCreatedOrReleasedDate(dataFile, solrSearchResult.getReleaseOrCreateDate())); + } + Long datasetId = Long.parseLong(solrSearchResult.getParent().get("id")); + Dataset parentDS = datasetService.find(datasetId); + Dataverse parentDataverse = parentDS.getOwner(); + solrSearchResult.setIsInTree(false); + List<Dataverse> dvTree = new ArrayList(); + Dataverse testDV = parentDataverse; + dvTree.add(testDV); + /** + * @todo Why is a NPE being thrown at this `while + * (testDV.getOwner() != null){` line? An NPE was being + * thrown while browsing the site *after* issuing the + * DestroyDatasetCommand but before a fix was put in to + * remove the dataset "card" from Solr. The ticket tracking + * this that fix is + * https://github.com/IQSS/dataverse/issues/1316 but it's + * unclear why the NPE was thrown. The users see a nasty + * "Internal Server Error - An unexpected error was + * encountered, no more information is available." and + * server.log has a stacktrace with the NPE. + */ + if (testDV != null) { + while (testDV.getOwner() != null) { + dvTree.add(testDV.getOwner()); + testDV = testDV.getOwner(); + } + } + + if (dvTree.contains(dataverse)) { + solrSearchResult.setIsInTree(true); + } + /** + * @todo: show DataTable variables + */ + } + } + + // populate preview counts: https://redmine.hmdc.harvard.edu/issues/3560 + previewCountbyType.put("dataverses", 0L); + previewCountbyType.put("datasets", 0L); + previewCountbyType.put("files", 0L); + if (solrQueryResponseAllTypes != null) { + for (FacetCategory facetCategory : solrQueryResponseAllTypes.getTypeFacetCategories()) { + for (FacetLabel facetLabel : facetCategory.getFacetLabel()) { + previewCountbyType.put(facetLabel.getName(), facetLabel.getCount()); + } + } + } + + } else { + List contentsList = dataverseService.findByOwnerId(dataverse.getId()); + contentsList.addAll(datasetService.findByOwnerId(dataverse.getId())); +// directChildDvObjectContainerList.addAll(contentsList); + } + /** + * @todo: pull values from datasetField.getTitle() rather than hard + * coding them here + */ +// friendlyName.put(SearchFields.SUBTREE, "Dataverse Subtree"); +// friendlyName.put(SearchFields.HOST_DATAVERSE, "Original Dataverse"); +// friendlyName.put(SearchFields.AUTHOR_STRING, "Author"); +// friendlyName.put(SearchFields.AFFILIATION, "Affiliation"); +// friendlyName.put(SearchFields.KEYWORD, "Keyword"); +// friendlyName.put(SearchFields.DISTRIBUTOR, "Distributor"); +// friendlyName.put(SearchFields.FILE_TYPE, "File Type"); +// friendlyName.put(SearchFields.PRODUCTION_DATE_YEAR_ONLY, "Production Date"); +// friendlyName.put(SearchFields.DISTRIBUTION_DATE_YEAR_ONLY, "Distribution Date"); + } + +// public boolean isShowUnpublished() { +// return showUnpublished; +// } +// +// public void setShowUnpublished(boolean showUnpublished) { +// this.showUnpublished = showUnpublished; +// } + public String getBrowseModeString() { + return browseModeString; + } + + public String getSearchModeString() { + return searchModeString; + } + + public String getMode() { + // enum would be prefered but we can't reference enums from JSF: + // http://stackoverflow.com/questions/2524420/how-to-testing-for-enum-equality-in-jsf/2524901#2524901 + return mode; + } + + public int getNumberOfFacets(String name, int defaultValue) { + Integer numFacets = numberOfFacets.get(name); + if (numFacets == null) { + numberOfFacets.put(name, defaultValue); + numFacets = defaultValue; + } + return numFacets; + } + + public void incrementFacets(String name, int incrementNum) { + Integer numFacets = numberOfFacets.get(name); + if (numFacets == null) { + numFacets = incrementNum; + } + numberOfFacets.put(name, numFacets + incrementNum); + } + + // http://stackoverflow.com/questions/1515437/java-function-for-arrays-like-phps-join/1515548#1515548 + String combine(String[] s, String glue) { + int k = s.length; + if (k == 0) { + return null; + } + StringBuilder out = new StringBuilder(); + out.append(s[0]); + for (int x = 1; x < k; ++x) { + out.append(glue).append(s[x]); + } + return out.toString(); + } + + private Long findFacetCountByType(String type) { + return previewCountbyType.get(type); + } + + public boolean isAllowedToClickAddData() { + /** + * @todo is this the right permission to check? + */ + // being explicit about the user, could just call permissionService.on(dataverse) + + // TODO: decide on rules for this button and check actual permissions + return session.getUser() != null && session.getUser().isAuthenticated(); + //return permissionService.userOn(session.getUser(), dataverse).has(Permission.UndoableEdit); + } + + private String getCreatedOrReleasedDate(DvObject dvObject, Date date) { + // the hedge is for https://redmine.hmdc.harvard.edu/issues/3806 + String hedge = ""; + if (dvObject instanceof Dataverse) { + hedge = ""; + } else if (dvObject instanceof Dataset) { + hedge = " maybe"; + } else if (dvObject instanceof DataFile) { + hedge = " maybe"; + } else { + hedge = " what object is this?"; + } + if (dvObject.isReleased()) { + return date + " released" + hedge; + } else { + return date + " created" + hedge; + } + } + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + public List<String> getFilterQueries() { + return filterQueries; + } + + public void setFilterQueries(List<String> filterQueries) { + this.filterQueries = filterQueries; + } + + public List<FacetCategory> getFacetCategoryList() { + return facetCategoryList; + } + + public void setFacetCategoryList(List<FacetCategory> facetCategoryList) { + this.facetCategoryList = facetCategoryList; + } + + public List<SolrSearchResult> getSearchResultsList() { + return searchResultsList; + } + + public void setSearchResultsList(List<SolrSearchResult> searchResultsList) { + this.searchResultsList = searchResultsList; + } + + public int getSearchResultsCount() { + return searchResultsCount; + } + + public void setSearchResultsCount(int searchResultsCount) { + this.searchResultsCount = searchResultsCount; + } + + public String getFq0() { + return fq0; + } + + public void setFq0(String fq0) { + this.fq0 = fq0; + } + + public String getFq1() { + return fq1; + } + + public void setFq1(String fq1) { + this.fq1 = fq1; + } + + public String getFq2() { + return fq2; + } + + public void setFq2(String fq2) { + this.fq2 = fq2; + } + + public String getFq3() { + return fq3; + } + + public void setFq3(String fq3) { + this.fq3 = fq3; + } + + public String getFq4() { + return fq4; + } + + public void setFq4(String fq4) { + this.fq4 = fq4; + } + + public String getFq5() { + return fq5; + } + + public void setFq5(String fq5) { + this.fq5 = fq5; + } + + public String getFq6() { + return fq6; + } + + public void setFq6(String fq6) { + this.fq6 = fq6; + } + + public String getFq7() { + return fq7; + } + + public void setFq7(String fq7) { + this.fq7 = fq7; + } + + public String getFq8() { + return fq8; + } + + public void setFq8(String fq8) { + this.fq8 = fq8; + } + + public String getFq9() { + return fq9; + } + + public void setFq9(String fq9) { + this.fq9 = fq9; + } + + public Dataverse getDataverse() { + return dataverse; + } + + public void setDataverse(Dataverse dataverse) { + this.dataverse = dataverse; + } + +// public String getDataverseSubtreeContext() { +// return dataverseSubtreeContext; +// } +// +// public void setDataverseSubtreeContext(String dataverseSubtreeContext) { +// this.dataverseSubtreeContext = dataverseSubtreeContext; +// } + public String getSelectedTypesString() { + return selectedTypesString; + } + + public void setSelectedTypesString(String selectedTypesString) { + this.selectedTypesString = selectedTypesString; + } + + public List<String> getSelectedTypesList() { + return selectedTypesList; + } + + public void setSelectedTypesList(List<String> selectedTypesList) { + this.selectedTypesList = selectedTypesList; + } + + public String getSelectedTypesHumanReadable() { + return selectedTypesHumanReadable; + } + + public void setSelectedTypesHumanReadable(String selectedTypesHumanReadable) { + this.selectedTypesHumanReadable = selectedTypesHumanReadable; + } + + public String getSearchFieldType() { + return searchFieldType; + } + + public void setSearchFieldType(String searchFieldType) { + this.searchFieldType = searchFieldType; + } + + public String getSearchFieldSubtree() { + return searchFieldSubtree; + } + + public void setSearchFieldSubtree(String searchFieldSubtree) { + this.searchFieldSubtree = searchFieldSubtree; + } + +// public String getSearchFieldHostDataverse() { +// return searchFieldHostDataverse; +// } +// +// public void setSearchFieldHostDataverse(String searchFieldHostDataverse) { +// this.searchFieldHostDataverse = searchFieldHostDataverse; +// } + public String getTypeFilterQuery() { + return typeFilterQuery; + } + + public void setTypeFilterQuery(String typeFilterQuery) { + this.typeFilterQuery = typeFilterQuery; + } + + public Long getFacetCountDatasets() { + return findFacetCountByType("datasets"); + } + + public Long getFacetCountDataverses() { + return findFacetCountByType("dataverses"); + } + + public Long getFacetCountFiles() { + return findFacetCountByType("files"); + } + + public String getSearchFieldRelevance() { + return searchFieldRelevance; + } + + public void setSearchFieldRelevance(String searchFieldRelevance) { + this.searchFieldRelevance = searchFieldRelevance; + } + + public String getSearchFieldNameSort() { + return searchFieldNameSort; + } + + public void setSearchFieldNameSort(String searchFieldNameSort) { + this.searchFieldNameSort = searchFieldNameSort; + } + + public String getSearchFieldReleaseOrCreateDate() { + return searchFieldReleaseOrCreateDate; + } + + public String getASCENDING() { + return ASCENDING; + } + + public String getDESCENDING() { + return DESCENDING; + } + + public String getSortField() { + return sortField; + } + + public void setSortField(String sortField) { + this.sortField = sortField; + } + + public String getSortOrder() { + return sortOrder; + } + + public void setSortOrder(String sortOrder) { + this.sortOrder = sortOrder; + } + + public String getCurrentSortFriendly() { + String friendlySortField = sortField; + String friendlySortOrder = sortOrder; + if (sortField.equals(SearchFields.NAME_SORT)) { + friendlySortField = "Name"; + if (sortOrder.equals(ASCENDING)) { + friendlySortOrder = " (A-Z)"; + } else if (sortOrder.equals(DESCENDING)) { + friendlySortOrder = " (Z-A)"; + } + } else if (sortField.equals(SearchFields.RELEVANCE)) { + friendlySortField = "Relevance"; + friendlySortOrder = ""; + } + return friendlySortField + friendlySortOrder; + } + + public String getCurrentSort() { + return sortField + ":" + sortOrder; + } + + public boolean isSortedByNameAsc() { + return getCurrentSort().equals(searchFieldNameSort + ":" + ASCENDING) ? true : false; + } + + public boolean isSortedByNameDesc() { + return getCurrentSort().equals(searchFieldNameSort + ":" + DESCENDING) ? true : false; + } + + public boolean isSortedByReleaseDateAsc() { + return getCurrentSort().equals(searchFieldReleaseOrCreateDate + ":" + ASCENDING) ? true : false; + } + + public boolean isSortedByReleaseDateDesc() { + return getCurrentSort().equals(searchFieldReleaseOrCreateDate + ":" + DESCENDING) ? true : false; + } + + public boolean isSortedByRelevance() { + return getCurrentSort().equals(searchFieldRelevance + ":" + DESCENDING) ? true : false; + } + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + // helper method + public int getTotalPages() { + return ((searchResultsCount - 1) / paginationGuiRows) + 1; + } + + public int getPaginationGuiStart() { + return paginationGuiStart; + } + + public void setPaginationGuiStart(int paginationGuiStart) { + this.paginationGuiStart = paginationGuiStart; + } + + public int getPaginationGuiEnd() { + return paginationGuiEnd; + } + + public void setPaginationGuiEnd(int paginationGuiEnd) { + this.paginationGuiEnd = paginationGuiEnd; + } + + public int getPaginationGuiRows() { + return paginationGuiRows; + } + + public void setPaginationGuiRows(int paginationGuiRows) { + this.paginationGuiRows = paginationGuiRows; + } + + public boolean isSolrIsDown() { + return solrIsDown; + } + + public void setSolrIsDown(boolean solrIsDown) { + this.solrIsDown = solrIsDown; + } + + public boolean isDebug() { + return (debug && session.getUser().isSuperuser()) || + systemConfig.isDebugEnabled(); + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + public List<String> getFilterQueriesDebug() { + return filterQueriesDebug; + } + + public boolean userLoggedIn() { + return session.getUser().isAuthenticated(); + } + + public boolean publishedSelected() { + String expected = SearchFields.PUBLICATION_STATUS + ":\"" + getPUBLISHED() + "\""; + logger.info("published expected: " + expected + " actual: " + selectedTypesList); + return filterQueries.contains(SearchFields.PUBLICATION_STATUS + ":\"" + getPUBLISHED() + "\""); + } + + public boolean unpublishedSelected() { + String expected = SearchFields.PUBLICATION_STATUS + ":\"" + getUNPUBLISHED() + "\""; + logger.info("unpublished expected: " + expected + " actual: " + selectedTypesList); + return filterQueries.contains(SearchFields.PUBLICATION_STATUS + ":\"" + getUNPUBLISHED() + "\""); + } + + public String getPUBLISHED() { + return IndexServiceBean.getPUBLISHED_STRING(); + } + + public String getUNPUBLISHED() { + return IndexServiceBean.getUNPUBLISHED_STRING(); + } + + public String getDRAFT() { + return IndexServiceBean.getDRAFT_STRING(); + } + + public String getDEACCESSIONED() { + return IndexServiceBean.getDEACCESSIONED_STRING(); + } + + public List<String> getFriendlyNamesFromFilterQuery(String filterQuery) { + String[] parts = filterQuery.split(":"); + String key = parts[0]; + String value = parts[1]; + List<String> friendlyNames = new ArrayList<>(); + String datasetfieldFriendyName = datasetfieldFriendlyNamesBySolrField.get(key); + if (datasetfieldFriendyName != null) { + friendlyNames.add(datasetfieldFriendyName); + } else { + String nonDatasetSolrField = staticSolrFieldFriendlyNamesBySolrField.get(key); + if (nonDatasetSolrField != null) { + friendlyNames.add(nonDatasetSolrField); + } else if (key.equals(SearchFields.PUBLICATION_STATUS)) { + /** + * @todo Refactor this quick fix for + * https://github.com/IQSS/dataverse/issues/618 . We really need + * to get rid of all the reflection that's happening with + * solrQueryResponse.getStaticSolrFieldFriendlyNamesBySolrField() + * and + */ + friendlyNames.add("Publication Status"); + } else { + // meh. better than nuthin' + friendlyNames.add(key); + } + } + String noLeadingQuote = value.replaceAll("^\"", ""); + String noTrailingQuote = noLeadingQuote.replaceAll("\"$", ""); + String valueWithoutQuotes = noTrailingQuote; + friendlyNames.add(valueWithoutQuotes); + return friendlyNames; + } + + public String getNewSelectedTypes(String typeClicked) { + List<String> newTypesSelected = new ArrayList<>(); + for (String selectedType : selectedTypesList) { + if (selectedType.equals(typeClicked)) { + + } else { + newTypesSelected.add(selectedType); + } + + } + if (selectedTypesList.contains(typeClicked)) { + + } else { + newTypesSelected.add(typeClicked); + } + + String[] arr = newTypesSelected.toArray(new String[newTypesSelected.size()]); + return combine(arr, ":"); + + } + + public String getErrorFromSolr() { + return errorFromSolr; + } + + /** + * @return the dataverseAlias + */ + public String getDataverseAlias() { + return dataverseAlias; + } + + /** + * @param dataverseAlias the dataverseAlias to set + */ + public void setDataverseAlias(String dataverseAlias) { + this.dataverseAlias = dataverseAlias; + } + + public boolean isTabular(Long fileId) { + if (fileId == null) { + return false; + } + + DataFile datafile = dataFileService.find(fileId); + + if (datafile == null) { + logger.warning("isTabular: datafile service could not locate a DataFile object for id " + fileId + "!"); + return false; + } + + return datafile.isTabularData(); + } + + public SearchException getSearchException() { + return searchException; + } + + public String tabularDataDisplayInfo(Long fileId) { + String ret = ""; + + if (fileId == null) { + return ""; + } + + DataFile datafile = dataFileService.find(fileId); + + if (datafile == null) { + logger.warning("isTabular: datafile service could not locate a DataFile object for id " + fileId + "!"); + return ""; + } + + if (datafile.isTabularData() && datafile.getDataTable() != null) { + DataTable datatable = datafile.getDataTable(); + String unf = datatable.getUnf(); + Long varNumber = datatable.getVarQuantity(); + Long obsNumber = datatable.getCaseQuantity(); + if (varNumber != null && varNumber.intValue() != 0) { + ret = ret.concat(varNumber + " Variables"); + if (obsNumber != null && obsNumber.intValue() != 0) { + ret = ret.concat(", " + obsNumber + " Observations"); + } + ret = ret.concat(" - "); + } + if (unf != null && !unf.equals("")) { + ret = ret.concat("UNF: " + unf); + } + } + + return ret; + } + + public String dataFileSizeDisplay(Long fileId) { + DataFile datafile = dataFileService.find(fileId); + if (datafile == null) { + logger.warning("isTabular: datafile service could not locate a DataFile object for id " + fileId + "!"); + return ""; + } + + return datafile.getFriendlySize(); + + } + + public String dataFileMD5Display(Long fileId) { + DataFile datafile = dataFileService.find(fileId); + if (datafile == null) { + logger.warning("isTabular: datafile service could not locate a DataFile object for id " + fileId + "!"); + return ""; + } + + if (datafile.getmd5() != null && datafile.getmd5() != "") { + return " MD5: " + datafile.getmd5() + " "; + } + + return ""; + } + + public void setDisplayCardValues() { + for (SolrSearchResult result : searchResultsList) { + boolean valueSet = false; + if (result.getType().equals("dataverses") && result.getEntity() instanceof Dataverse){ + result.setDisplayImage(dataverseService.isDataverseCardImageAvailable((Dataverse) result.getEntity(), session.getUser())); + valueSet = true; + } else if (result.getType().equals("datasets") && result.getEntity() instanceof Dataset) { + result.setDisplayImage(datasetService.isDatasetCardImageAvailable(datasetVersionService.find(result.getDatasetVersionId()), session.getUser())); + valueSet = true; + } else if (result.getType().equals("files") && result.getEntity() instanceof DataFile) { + result.setDisplayImage(dataFileService.isThumbnailAvailable((DataFile) result.getEntity(), session.getUser())); + valueSet = true; + } + + if (!valueSet) { + logger.warning("Index result / entity mismatch (id:resultType) - " + result.getId() + ":" + result.getType()); + } + } + } +}
