diff --git a/dspace-api/src/main/java/org/dspace/discovery/ClarinSolrItemsCommunityIndexPlugin.java b/dspace-api/src/main/java/org/dspace/discovery/ClarinSolrItemsCommunityIndexPlugin.java index fe419cb6d2ff..36e60e3af816 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/ClarinSolrItemsCommunityIndexPlugin.java +++ b/dspace-api/src/main/java/org/dspace/discovery/ClarinSolrItemsCommunityIndexPlugin.java @@ -39,7 +39,11 @@ public void additionalIndex(Context context, IndexableObject indexableObject, So Community owningCommunity = clarinItemService.getOwningCommunity(context, item); String communityName = Objects.isNull(owningCommunity) ? " " : owningCommunity.getName(); + // _keyword and _filter because + // they are needed in order to work as a facet and filter. document.addField("items_owning_community", communityName); + document.addField("items_owning_community_keyword", communityName); + document.addField("items_owning_community_filter", communityName); } } } diff --git a/dspace-api/src/test/data/dspaceFolder/config/local.cfg b/dspace-api/src/test/data/dspaceFolder/config/local.cfg index 8a9decfa3318..a842905c53ab 100644 --- a/dspace-api/src/test/data/dspaceFolder/config/local.cfg +++ b/dspace-api/src/test/data/dspaceFolder/config/local.cfg @@ -219,6 +219,10 @@ featured.service.teitok.description = A web-based platform for viewing, creating ##### Shibboleth ##### +authentication-shibboleth.netid-header = SHIB-NETID +authentication-shibboleth.email-header = SHIB-MAIL +authentication-shibboleth.firstname-header = SHIB-GIVENNAME +authentication-shibboleth.lastname-header = SHIB-SURNAME # Turn off the discofeed, it is allowed by default shibboleth.discofeed.allowed = false # File where is DiscoJuiceFeed response diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinRefBoxController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinRefBoxController.java index 8c8490f1d53e..710a96648152 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinRefBoxController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ClarinRefBoxController.java @@ -21,10 +21,15 @@ import java.util.Map; import java.util.Objects; import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.NotFoundException; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.stream.XMLStreamException; import com.hp.hpl.jena.rdf.model.Model; @@ -67,6 +72,9 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; /** * A Controller for fetching the data for the ref-box in the Item View (FE). @@ -77,6 +85,9 @@ @RestController @RequestMapping("/api/core/refbox") public class ClarinRefBoxController { + + private final static String BIBTEX_TYPE = "bibtex"; + private final Logger log = org.apache.logging.log4j.LogManager.getLogger(ClarinRefBoxController.class); @Autowired @@ -228,7 +239,7 @@ public ResponseEntity getCitationText(@RequestParam(name = "type") String type, XmlOutputContext xmlOutContext = XmlOutputContext.emptyContext(output); xmlOutContext.getWriter().writeStartDocument(); - //Try to obtain just the metadata, if that fails return "normal" response + // Try to obtain just the metadata, if that fails return "normal" response try { oaipmh.getInfo().getGetRecord().getRecord().getMetadata().write(xmlOutContext); } catch (Exception e) { @@ -246,8 +257,10 @@ public ResponseEntity getCitationText(@RequestParam(name = "type") String type, response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unexpected error while writing the output. For more information visit the log files."); } catch (XOAIManagerResolverException e) { - throw new ServletException("OAI 2.0 wasn't correctly initialized," + - " please check the log for previous errors", e); + String errMessage = "OAI 2.0 wasn't correctly initialized, please check the log for previous errors. " + + "Error message: " + e.getMessage(); + log.error(errMessage); + throw new ServletException(errMessage); } catch (OAIException e) { response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Unexpected error. For more information visit the log files."); @@ -263,8 +276,11 @@ public ResponseEntity getCitationText(@RequestParam(name = "type") String type, HttpStatus.valueOf(HttpServletResponse.SC_NO_CONTENT)); } + // Update the output string and remove the unwanted parts. + String outputString = updateOutput(type, output.toString()); + // Wrap the String output to the class for better parsing in the FE - OaiMetadataWrapper oaiMetadataWrapper = new OaiMetadataWrapper(output.toString()); + OaiMetadataWrapper oaiMetadataWrapper = new OaiMetadataWrapper(StringUtils.defaultIfEmpty(outputString, "")); return new ResponseEntity<>(oaiMetadataWrapper, HttpStatus.valueOf(SC_OK)); } @@ -331,6 +347,56 @@ private List mapFeaturedServiceLinks(List tag from the string. + return getXmlTextContent(output); + } else { + // Remove the XML header tag from the string. + return removeXmlHeaderTag(output); + } + } catch (Exception e) { + log.error("Cannot update the xml string for citation because of: " + e.getMessage()); + return null; + } + } + + /** + * Remove the XML header tag from the string. + * + * @param xml + * @return + */ + private String removeXmlHeaderTag(String xml) { + String xmlHeaderPattern = "<\\?xml[^>]*\\?>"; + Pattern xmlHeaderRegex = Pattern.compile(xmlHeaderPattern); + Matcher xmlHeaderMatcher = xmlHeaderRegex.matcher(xml); + if (xmlHeaderMatcher.find()) { + return xml.replaceFirst(xmlHeaderPattern, ""); + } else { + return xml; + } + } + + /** + * Get the text content from the xml string. + */ + private String getXmlTextContent(String xml) throws ParserConfigurationException, IOException, SAXException { + // Parse the XML string + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(new org.xml.sax.InputSource(new java.io.StringReader(xml))); + + // Get the root element + Node root = document.getDocumentElement(); + + // Get the text content of the root element + return root.getTextContent().trim(); + } } /** diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataBitstreamWrapperConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataBitstreamWrapperConverter.java index 49728da0b899..e42c023f72a5 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataBitstreamWrapperConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/MetadataBitstreamWrapperConverter.java @@ -10,7 +10,6 @@ import org.dspace.app.rest.model.MetadataBitstreamWrapperRest; import org.dspace.app.rest.model.wrapper.MetadataBitstreamWrapper; import org.dspace.app.rest.projection.Projection; -import org.dspace.util.FileTreeViewGenerator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; @@ -41,8 +40,7 @@ public MetadataBitstreamWrapperRest convert(MetadataBitstreamWrapper modelObject bitstreamWrapperRest.setId(modelObject.getBitstream().getID().toString()); bitstreamWrapperRest.setDescription(modelObject.getDescription()); bitstreamWrapperRest.setChecksum(modelObject.getBitstream().getChecksum()); - bitstreamWrapperRest.setFileSize(FileTreeViewGenerator.humanReadableFileSize( - modelObject.getBitstream().getSizeBytes())); + bitstreamWrapperRest.setFileSize(modelObject.getBitstream().getSizeBytes()); bitstreamWrapperRest.setFileInfo(modelObject.getFileInfo()); bitstreamWrapperRest.setHref(modelObject.getHref()); bitstreamWrapperRest.setFormat(modelObject.getFormat()); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataBitstreamWrapperRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataBitstreamWrapperRest.java index 7e3c1c03568e..8e4d60d4bfab 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataBitstreamWrapperRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/MetadataBitstreamWrapperRest.java @@ -23,14 +23,14 @@ public class MetadataBitstreamWrapperRest extends BaseObjectRest { private String name; private String description; - private String fileSize; + private long fileSize; private String checksum; private List fileInfo; private String format; private String href; private boolean canPreview; - public MetadataBitstreamWrapperRest(String name, String description, String fileSize, String checksum, + public MetadataBitstreamWrapperRest(String name, String description, long fileSize, String checksum, List fileInfo, String format, String href, boolean canPreview) { this.name = name; this.description = description; @@ -93,11 +93,11 @@ public void setDescription(String description) { this.description = description; } - public String getFileSize() { + public long getFileSize() { return fileSize; } - public void setFileSize(String fileSize) { + public void setFileSize(long fileSize) { this.fileSize = fileSize; } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/UsageReportRestPermissionEvaluatorPlugin.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/UsageReportRestPermissionEvaluatorPlugin.java index 06254d561ace..8e0b57e6791a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/UsageReportRestPermissionEvaluatorPlugin.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/security/UsageReportRestPermissionEvaluatorPlugin.java @@ -18,6 +18,7 @@ import org.dspace.app.rest.utils.DSpaceObjectUtils; import org.dspace.authorize.service.AuthorizeService; import org.dspace.content.DSpaceObject; +import org.dspace.content.Site; import org.dspace.core.Context; import org.dspace.services.ConfigurationService; import org.dspace.services.RequestService; @@ -93,6 +94,15 @@ public boolean hasDSpacePermission(Authentication authentication, Serializable t if (Objects.isNull(dso)) { return true; } + + // Show Site usage reports to anonymous users if the configuration is set to do so + // This Site usage reports are used in the home page and are not sensitive + if (dso instanceof Site) { + if (!configurationService.getBooleanProperty("site.usage-reports.enable.auth.anonymous", + false)) { + return true; + } + } return authorizeService.authorizeActionBoolean(context, dso, restPermission.getDspaceApiActionId()); } catch (SQLException e) { log.error(e.getMessage(), e); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinDiscoveryRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinDiscoveryRestControllerIT.java index 72b12c7962af..460373091d27 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinDiscoveryRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ClarinDiscoveryRestControllerIT.java @@ -122,7 +122,8 @@ public void discoverFacetsTestWithoutParameters() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false))) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false))) ); } @@ -1006,9 +1007,11 @@ public void discoverSearchTest() throws Exception { SortOptionMatcher.sortOptionMatcher( "dc.title", DiscoverySortFieldConfiguration.SORT_ORDER.asc.name()), SortOptionMatcher.sortOptionMatcher( - "dc.date.issued", DiscoverySortFieldConfiguration.SORT_ORDER.desc.name()), + "dc.title", DiscoverySortFieldConfiguration.SORT_ORDER.desc.name()), + SortOptionMatcher.sortOptionMatcher( + "dc.date.issued", DiscoverySortFieldConfiguration.SORT_ORDER.asc.name()), SortOptionMatcher.sortOptionMatcher( - "dc.date.accessioned", DiscoverySortFieldConfiguration.SORT_ORDER.desc.name()) + "dc.date.issued", DiscoverySortFieldConfiguration.SORT_ORDER.desc.name()) ))); } @@ -1146,7 +1149,8 @@ public void discoverSearchObjectsTest() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -1287,7 +1291,8 @@ public void discoverSearchObjectsTestHasMoreAuthorFacet() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -1379,7 +1384,8 @@ public void discoverSearchObjectsTestHasMoreSubjectFacet() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -1461,7 +1467,8 @@ public void discoverSearchObjectsTestWithBasicQuery() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -1571,7 +1578,8 @@ public void discoverSearchObjectsTestWithScope() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -1653,7 +1661,8 @@ public void discoverSearchObjectsTestWithDsoType() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))); @@ -1690,7 +1699,8 @@ public void discoverSearchObjectsTestWithDsoType() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))); @@ -1728,7 +1738,8 @@ public void discoverSearchObjectsTestWithDsoType() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))); @@ -1770,7 +1781,8 @@ public void discoverSearchObjectsTestWithDsoType() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))); @@ -1859,7 +1871,8 @@ public void discoverSearchObjectsTestWithDsoTypeAndSort() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //We want to get the sort that's been used as well in the response .andExpect(jsonPath("$.sort", is( @@ -2073,7 +2086,8 @@ public void discoverSearchObjectsTestForPaginationAndNextLinks() throws Exceptio FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), FacetEntryMatcher.hasContentInOriginalBundleFacet(false), - FacetEntryMatcher.entityTypeFacet(false) + FacetEntryMatcher.entityTypeFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -2165,7 +2179,8 @@ public void discoverSearchObjectsTestWithContentInABitstream() throws Exception FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -2257,7 +2272,8 @@ public void discoverSearchObjectsTestForEmbargoedItemsAndPrivateItems() throws E FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -2343,7 +2359,8 @@ public void discoverSearchObjectsTestWithContentInAPrivateBitstream() throws Exc FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -2424,7 +2441,8 @@ public void discoverSearchObjectsTestForScope() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -2511,7 +2529,8 @@ public void discoverSearchObjectsTestForScopeWithPrivateItem() throws Exception FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -2693,7 +2712,8 @@ public void discoverSearchObjectsTestForHitHighlights() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -2839,7 +2859,8 @@ public void discoverSearchObjectsWithQueryOperatorContains_query() throws Except FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -2917,7 +2938,8 @@ public void discoverSearchObjectsWithQueryOperatorContains() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -2993,7 +3015,8 @@ public void discoverSearchObjectsWithQueryOperatorNotContains_query() throws Exc FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -3070,7 +3093,8 @@ public void discoverSearchObjectsWithQueryOperatorNotContains() throws Exception FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -3157,7 +3181,8 @@ public void discoverSearchObjectsTestForMinMaxValues() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -3228,7 +3253,8 @@ public void discoverSearchFacetsTestForMinMaxValues() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/facets"))) @@ -3304,7 +3330,8 @@ public void discoverSearchObjectsWithQueryOperatorEquals_query() throws Exceptio FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -3381,7 +3408,8 @@ public void discoverSearchObjectsWithQueryOperatorEquals() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -3458,7 +3486,8 @@ public void discoverSearchObjectsWithQueryOperatorNotEquals_query() throws Excep FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -3536,7 +3565,8 @@ public void discoverSearchObjectsWithQueryOperatorNotEquals() throws Exception { FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -3612,7 +3642,8 @@ public void discoverSearchObjectsWithQueryOperatorNotAuthority_query() throws Ex FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -3689,7 +3720,8 @@ public void discoverSearchObjectsWithQueryOperatorNotAuthority() throws Exceptio FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.hasContentInOriginalBundleFacet(false) + FacetEntryMatcher.hasContentInOriginalBundleFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link available .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) @@ -4138,7 +4170,8 @@ public void discoverSearchObjectsWithInProgressSubmissionTest() throws Exception FacetEntryMatcher.clarinItemsLanguageFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), FacetEntryMatcher.hasContentInOriginalBundleFacet(false), - FacetEntryMatcher.entityTypeFacet(false) + FacetEntryMatcher.entityTypeFacet(false), + FacetEntryMatcher.typeFacet(false) ))) //There always needs to be a self link .andExpect(jsonPath("$._links.self.href", containsString("/api/discover/search/objects"))) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryScopeBasedRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryScopeBasedRestControllerIT.java index 67e514d5084d..4a83a0ea593b 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryScopeBasedRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/DiscoveryScopeBasedRestControllerIT.java @@ -509,7 +509,8 @@ public void ScopeBasedIndexingAndSearchTestParentCommunity2() throws Exception { FacetEntryMatcher.entityTypeFacet(false), FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.clarinItemsLanguageFacet(false) + FacetEntryMatcher.clarinItemsLanguageFacet(false), + FacetEntryMatcher.typeFacet(false) )) ); } @@ -624,7 +625,8 @@ public void ScopeBasedIndexingAndSearchTestSubcommunity22() throws Exception { FacetEntryMatcher.entityTypeFacet(false), FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.clarinItemsLanguageFacet(false) + FacetEntryMatcher.clarinItemsLanguageFacet(false), + FacetEntryMatcher.typeFacet(false) )) ); } @@ -677,7 +679,8 @@ public void ScopeBasedIndexingAndSearchTestCollection222() throws Exception { FacetEntryMatcher.entityTypeFacet(false), FacetEntryMatcher.clarinLicenseRightsFacet(false), FacetEntryMatcher.clarinItemsCommunityFacet(false), - FacetEntryMatcher.clarinItemsLanguageFacet(false) + FacetEntryMatcher.clarinItemsLanguageFacet(false), + FacetEntryMatcher.typeFacet(false) )) ); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataBitstreamRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataBitstreamRestRepositoryIT.java index 59e39285bea1..c966ecfa58e3 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataBitstreamRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/MetadataBitstreamRestRepositoryIT.java @@ -7,6 +7,7 @@ */ package org.dspace.app.rest; +import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -34,7 +35,6 @@ import org.dspace.content.service.clarin.ClarinLicenseResourceMappingService; import org.dspace.core.Constants; import org.dspace.services.ConfigurationService; -import org.dspace.util.FileTreeViewGenerator; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -115,9 +115,9 @@ public void findByHandle() throws Exception { .andExpect(jsonPath("$._embedded.metadatabitstreams[*].format") .value(Matchers.containsInAnyOrder(Matchers.containsString( bts.getFormat(context).getMIMEType())))) + // Convert the long into int because Marchers has a problem to compare long format .andExpect(jsonPath("$._embedded.metadatabitstreams[*].fileSize") - .value(Matchers.containsInAnyOrder(Matchers.containsString( - FileTreeViewGenerator.humanReadableFileSize(bts.getSizeBytes()))))) + .value(hasItem(is((int) bts.getSizeBytes())))) .andExpect(jsonPath("$._embedded.metadatabitstreams[*].canPreview") .value(Matchers.containsInAnyOrder(Matchers.is(canPreview)))) .andExpect(jsonPath("$._embedded.metadatabitstreams[*].fileInfo").exists()) @@ -150,8 +150,7 @@ public void previewingIsDisabledByCfg() throws Exception { .value(Matchers.containsInAnyOrder(Matchers.containsString( bts.getFormat(context).getMIMEType())))) .andExpect(jsonPath("$._embedded.metadatabitstreams[*].fileSize") - .value(Matchers.containsInAnyOrder(Matchers.containsString( - FileTreeViewGenerator.humanReadableFileSize(bts.getSizeBytes()))))) + .value(hasItem(is((int) bts.getSizeBytes())))) .andExpect(jsonPath("$._embedded.metadatabitstreams[*].canPreview") .value(Matchers.containsInAnyOrder(Matchers.is(false)))) .andExpect(jsonPath("$._embedded.metadatabitstreams[*].fileInfo").exists()) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java index 5544ecdb032b..2a07dc479807 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/StatisticsRestRepositoryIT.java @@ -53,6 +53,7 @@ import org.dspace.content.DSpaceObject; import org.dspace.content.Item; import org.dspace.content.Site; +import org.dspace.content.service.SiteService; import org.dspace.core.Constants; import org.dspace.eperson.EPerson; import org.dspace.services.ConfigurationService; @@ -76,6 +77,8 @@ public class StatisticsRestRepositoryIT extends AbstractControllerIntegrationTes ConfigurationService configurationService; @Autowired protected AuthorizeService authorizeService; + @Autowired + protected SiteService siteService; private Community communityNotVisited; private Community communityVisited; @@ -1532,6 +1535,22 @@ public void usageReportsSearch_Bitstream_Visited() throws Exception { ))); } + // Show usage reports for the Anonymous user - it could be configured by cfg property + // `site.usage-reports.enable.auth.anonymous` + @Test + public void usageReportsSearch_Site_For_Anonymous() throws Exception { + // This property is set to `true` before each test + configurationService.setProperty("usage-statistics.authorization.admin.usage", false); + + // Get the site object UUID + Site site = siteService.findSite(context); + // Allow accessing Site usage reports for anonymous + getClient() + .perform(get("/api/statistics/usagereports/search/object?uri=http://localhost:8080/server/api/core" + + "/sites/" + site.getID())) + .andExpect(status().isOk()); + } + // Create expected points from -6 months to now, with given number of views in current month private List getListOfVisitsPerMonthsPoints(int viewsLastMonth) { List expectedPoints = new ArrayList<>(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetEntryMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetEntryMatcher.java index 9176a42616f9..23d66754dcc6 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetEntryMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/FacetEntryMatcher.java @@ -124,7 +124,7 @@ public static Matcher matchFacet(boolean hasNext, String name, S public static Matcher clarinLicenseRightsFacet(boolean hasNext) { return allOf( hasJsonPath("$.name", is("rights")), - hasJsonPath("$.facetType", is("standard")), + hasJsonPath("$.facetType", is("text")), hasJsonPath("$.facetLimit", any(Integer.class)), hasJsonPath("$._links.self.href", containsString("api/discover/facets/rights")), hasJsonPath("$._links", matchNextLink(hasNext, "api/discover/facets/rights")) @@ -144,7 +144,7 @@ public static Matcher clarinItemsLanguageFacet(boolean hasNext) public static Matcher clarinItemsCommunityFacet(boolean hasNext) { return allOf( hasJsonPath("$.name", is("items_owning_community")), - hasJsonPath("$.facetType", is("standard")), + hasJsonPath("$.facetType", is("text")), hasJsonPath("$.facetLimit", any(Integer.class)), hasJsonPath("$._links.self.href", containsString("api/discover/facets/items_owning_community")), diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchFilterMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchFilterMatcher.java index 7700d5291249..b60f26940ff8 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchFilterMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/SearchFilterMatcher.java @@ -160,7 +160,7 @@ public static Matcher clarinLicenseRightsFilter() { return allOf( hasJsonPath("$.filter", is("rights")), hasJsonPath("$.hasFacets", is(true)), - hasJsonPath("$.type", is("standard")), + hasJsonPath("$.type", is("text")), hasJsonPath("$.openByDefault", is(false)), checkOperators() ); @@ -180,7 +180,7 @@ public static Matcher clarinItemsCommunityFilter() { return allOf( hasJsonPath("$.filter", is("items_owning_community")), hasJsonPath("$.hasFacets", is(true)), - hasJsonPath("$.type", is("standard")), + hasJsonPath("$.type", is("text")), hasJsonPath("$.openByDefault", is(false)), checkOperators() ); @@ -189,7 +189,7 @@ public static Matcher clarinItemsCommunityFilter() { public static Matcher clarinItemsTypeFilter() { return allOf( hasJsonPath("$.filter", is("itemtype")), - hasJsonPath("$.hasFacets", is(false)), + hasJsonPath("$.hasFacets", is(true)), hasJsonPath("$.type", is("text")), hasJsonPath("$.openByDefault", is(false)), checkOperators() diff --git a/dspace/config/clarin-dspace.cfg b/dspace/config/clarin-dspace.cfg index be485ad54184..8d8ae7898433 100644 --- a/dspace/config/clarin-dspace.cfg +++ b/dspace/config/clarin-dspace.cfg @@ -156,6 +156,9 @@ matomo.tracker.bitstream.site_id = 1 matomo.tracker.oai.site_id = 1 statistics.cache-server.uri = http://cache-server.none +#### Statistic usage reports #### +# site.usage-reports.enable.auth.anonymous = true + ##### Citacepro config ##### # citace.pro.url = https://www.citacepro.com/api/dspace/citace/oai @@ -252,3 +255,8 @@ s3.upload.by.parts.enabled = true ### The build version is stored in the specific file ### build.version.file.path = ${dspace.dir}/config/VERSION_D.txt + + +#### Item View #### +# Show handle and doi as identifiers - show only DOI if it exists instead of handle by default +item-page.show-handle-and-doi = false \ No newline at end of file diff --git a/dspace/config/dspace.cfg b/dspace/config/dspace.cfg index 60e46607c21f..4cf68c17f82f 100644 --- a/dspace/config/dspace.cfg +++ b/dspace/config/dspace.cfg @@ -931,6 +931,7 @@ registry.metadata.load = iiif-types.xml ### CLARIN ### # This property cannot be added in the `clarin-dspace.cfg` because then some Unit tests are failing.. registry.metadata.load = metashare-schema.xml +registry.metadata.load = edm.xml #---------------------------------------------------------------# #-----------------UI-Related CONFIGURATIONS---------------------# diff --git a/dspace/config/modules/authentication-shibboleth.cfg b/dspace/config/modules/authentication-shibboleth.cfg index 4034d7e2c326..7e176f71b718 100644 --- a/dspace/config/modules/authentication-shibboleth.cfg +++ b/dspace/config/modules/authentication-shibboleth.cfg @@ -90,8 +90,8 @@ authentication-shibboleth.lazysession.secure = true # Authentication headers for Mail, NetID, and Tomcat's Remote User. # Supply all parameters possible. -authentication-shibboleth.netid-header = SHIB-NETID -authentication-shibboleth.email-header = SHIB-MAIL +authentication-shibboleth.netid-header = eppn +authentication-shibboleth.email-header = mail authentication-shibboleth.email-use-tomcat-remote-user = false # Should we allow new users to be registered automatically? @@ -127,8 +127,8 @@ authentication-shibboleth.sword.compatibility = false # Metadata Headers # Shibboleth-based headers for the first and last name attirbutes -authentication-shibboleth.firstname-header = SHIB-GIVENNAME -authentication-shibboleth.lastname-header = SHIB-SURNAME +authentication-shibboleth.firstname-header = givenName +authentication-shibboleth.lastname-header = sn # Additional user attributes mapping, multiple attributes may be stored # for each user. The left side is the Shibboleth-based metadata Header diff --git a/dspace/config/modules/rest.cfg b/dspace/config/modules/rest.cfg index d17c6dc6bf2c..32dcc0fb1e67 100644 --- a/dspace/config/modules/rest.cfg +++ b/dspace/config/modules/rest.cfg @@ -70,6 +70,7 @@ rest.properties.exposed = themed.by.company.name rest.properties.exposed = identifier.doi.resolver rest.properties.exposed = spring.servlet.multipart.max-file-size rest.properties.exposed = authentication-shibboleth.show.idp-attributes +rest.properties.exposed = item-page.show-handle-and-doi # TUL rest.properties.exposed = dspace.ui.url diff --git a/dspace/config/registries/edm.xml b/dspace/config/registries/edm.xml new file mode 100644 index 000000000000..1c49505e9c20 --- /dev/null +++ b/dspace/config/registries/edm.xml @@ -0,0 +1,17 @@ + + + + edm + http://www.europeana.eu/schemas/edm/ + + + edm + type + + The value must be one of the types accepted by Europeana as it will support portal functionality: TEXT, VIDEO, SOUND, IMAGE, 3D. + There's a huge overlap with values we allow in metashare's mediaType; eventually this might get merged. + + + + + diff --git a/dspace/config/spring/api/discovery.xml b/dspace/config/spring/api/discovery.xml index c373051b848a..138c771dedb4 100644 --- a/dspace/config/spring/api/discovery.xml +++ b/dspace/config/spring/api/discovery.xml @@ -64,6 +64,7 @@ + @@ -171,6 +172,7 @@ + @@ -207,8 +209,168 @@ - - + + + + + + + + + + + + + (search.resourcetype:Item AND latestVersion:true) OR search.resourcetype:Collection OR search.resourcetype:Community + -withdrawn:true AND -discoverable:false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + dc.title + dc.contributor.author + dc.creator + dc.contributor.other + dc.subject + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -303,6 +465,7 @@ dc.title dc.contributor.author dc.creator + dc.contributor.other dc.subject @@ -355,8 +518,10 @@ - - + + + + @@ -440,6 +605,7 @@ dc.title dc.contributor.author dc.creator + dc.contributor.other dc.subject @@ -494,8 +660,10 @@ - - + + + + @@ -579,6 +747,7 @@ dc.title dc.contributor.author dc.creator + dc.contributor.other dc.subject @@ -636,8 +805,10 @@ - - + + + + @@ -719,6 +890,7 @@ dc.title dc.contributor.author dc.creator + dc.contributor.other dc.subject @@ -765,8 +937,10 @@ - - + + + + @@ -916,8 +1090,10 @@ - - + + + + @@ -991,8 +1167,10 @@ - - + + + + @@ -1066,8 +1244,10 @@ - - + + + + @@ -1150,8 +1330,10 @@ - - + + + + @@ -1220,8 +1402,10 @@ - - + + + + @@ -2308,6 +2492,7 @@ dc.contributor.author dc.creator + dc.contributor.other @@ -2325,7 +2510,7 @@ dc.rights.label - + @@ -2350,7 +2535,7 @@ - + @@ -2360,6 +2545,8 @@ dc.type + edm.type + metashare.ResourceInfo#ContentInfo.mediaType @@ -2995,6 +3182,17 @@ + + + + + + + + + + +