Skip to content

Commit

Permalink
Merge branch 'develop' of git@gitea.intranda.com:goobi-viewer/goobi-v…
Browse files Browse the repository at this point in the history
…iewer-core.git into develop
  • Loading branch information
Florian Alpers committed Feb 28, 2025
2 parents 5e1aec8 + ac65877 commit 423f552
Show file tree
Hide file tree
Showing 23 changed files with 525 additions and 339 deletions.
2 changes: 1 addition & 1 deletion goobi-viewer-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
<sonar.java.target>21</sonar.java.target>

<!-- Checkstyle -->
<checkstyle.max.violations>35</checkstyle.max.violations>
<checkstyle.max.violations>26</checkstyle.max.violations>
<skipCheckstyle>true</skipCheckstyle>

<!-- Manifest information -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ public String getBookmarkListAsRSS(
throws DAOException, IOException, RestApiException, ContentLibException {
BookmarkList list = getBookmarkList(id);
String query = list.generateSolrQueryForItems();
return RSSFeed.createRssFeed(language, maxHits, null, query, null, servletRequest, null, true);
return RSSFeed.createRssFeedString(language, maxHits, null, query, null, servletRequest, null, true);
}

@GET
Expand Down Expand Up @@ -409,6 +409,6 @@ public String getSharedBookmarkListAsRSS(
throws DAOException, RestApiException, ContentLibException {
BookmarkList list = getSharedBookmarkListByKey(key);
String query = list.generateSolrQueryForItems();
return RSSFeed.createRssFeed(language, maxHits, null, query, null, servletRequest, null, true);
return RSSFeed.createRssFeedString(language, maxHits, null, query, null, servletRequest, null, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public String getRssFeed(
@QueryParam("sortDescending") Boolean sortDescending)
throws ContentLibException {

return RSSFeed.createRssFeed(language, maxHits, subtheme, query, facets, servletRequest, sortField, sortDescending == null || sortDescending);
return RSSFeed.createRssFeedString(language, maxHits, subtheme, query, facets, servletRequest, sortField, sortDescending == null || sortDescending);
}

@GET
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ public List<ArchiveResource> getFilteredDatabases() {
} else {
try {
if (AccessConditionUtils
.checkAccessPermissionByIdentifierAndLogId(resource.getResourceId(), null, IPrivilegeHolder.PRIV_LIST,
.checkAccessPermissionByIdentifierAndLogId(resource.getResourceId(), null, IPrivilegeHolder.PRIV_ARCHIVE_DISPLAY_NODE,
BeanUtils.getRequest())
.isGranted()) {
ret.add(resource);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* This file is part of the Goobi viewer - a content presentation and management
* application for digitized objects.
*
* Visit these websites for more information.
* - http://www.intranda.com
* - http://digiverso.com
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package io.goobi.viewer.managedbeans;

import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.rometools.rome.feed.synd.SyndEntry;

import de.unigoettingen.sub.commons.contentlib.exceptions.ContentLibException;
import io.goobi.viewer.controller.DataManager;
import io.goobi.viewer.exceptions.DAOException;
import io.goobi.viewer.exceptions.IndexUnreachableException;
import io.goobi.viewer.exceptions.PresentationException;
import io.goobi.viewer.exceptions.ViewerConfigurationException;
import io.goobi.viewer.managedbeans.utils.BeanUtils;
import io.goobi.viewer.model.rss.Channel;
import io.goobi.viewer.model.rss.RSSFeed;
import io.goobi.viewer.model.search.SearchAggregationType;
import io.goobi.viewer.model.search.SearchFacets;
import io.goobi.viewer.model.search.SearchHelper;
import io.goobi.viewer.servlets.utils.ServletUtils;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;

@Named("rssBean")
@RequestScoped
public class RSSBean {

private static final Logger logger = LogManager.getLogger(RSSBean.class);

/**
*
* @param maxHits
* @param query
* @param sortField
* @param sortDescending
* @return List<SyndEntry>
*/
public List<SyndEntry> getRssFeed(Integer maxHits, String query, String sortField, Boolean sortDescending) {
try {
return RSSFeed.createRssFeed(null, maxHits, null, query, null, BeanUtils.getRequest(), sortField,
sortDescending == null || sortDescending).getEntries();

} catch (PresentationException | IndexUnreachableException | ViewerConfigurationException | DAOException e) {
logger.error(e.getMessage());
}

return Collections.emptyList();
}

/**
*
* @param maxHits
* @param query
* @param sortField
* @param sortDescending
* @return {@link Channel}
*/
public Channel getRssFeedChannel(Integer maxHits, String query, String sortField, Boolean sortDescending) {
try {
return RSSFeed.createRssResponse(null, maxHits, null, query, null, BeanUtils.getRequest(), sortField,
sortDescending == null || sortDescending);

} catch (ContentLibException e) {
logger.error(e.getMessage());
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
import java.util.Optional;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.persistence.annotations.PrivateOwned;

import io.goobi.viewer.model.translations.Translation;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
Expand All @@ -37,12 +41,6 @@
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.persistence.annotations.PrivateOwned;

import io.goobi.viewer.model.translations.IPolyglott;
import io.goobi.viewer.model.translations.Translation;

/**
* @author florian
*
Expand Down Expand Up @@ -75,6 +73,11 @@ public TermsOfUse() {

}

/**
*
* @param orig
* @should clone original correctly
*/
public TermsOfUse(TermsOfUse orig) {
this.active = orig.active;
this.id = orig.id;
Expand All @@ -99,8 +102,7 @@ public boolean isActive() {
}

public TermsOfUseTranslation getTitle(String language) {
TermsOfUseTranslation translation = getForLanguage(getTitles(), language).findAny().orElse(null);
return translation;
return getForLanguage(getTitles(), language).findAny().orElse(null);
}

public Optional<String> getTitleIfExists(String language) {
Expand All @@ -120,8 +122,7 @@ public TermsOfUseTranslation setTitle(String language, String value) {
}

public TermsOfUseTranslation getDescription(String language) {
TermsOfUseTranslation translation = getForLanguage(getDescriptions(), language).findAny().orElse(null);
return translation;
return getForLanguage(getDescriptions(), language).findAny().orElse(null);
}

public Optional<String> getDescriptionIfExists(String language) {
Expand All @@ -148,7 +149,14 @@ private Stream<TermsOfUseTranslation> getDescriptions() {
return this.translations.stream().filter(t -> DESCRIPTION_TAG.equals(t.getTag()));
}

private Stream<TermsOfUseTranslation> getForLanguage(Stream<TermsOfUseTranslation> translations, String language) {
/**
*
* @param translations
* @param language
* @return Stream<TermsOfUseTranslation>
* @should throw IllegalArgumentException if language blank
*/
static Stream<TermsOfUseTranslation> getForLanguage(Stream<TermsOfUseTranslation> translations, String language) {
if (StringUtils.isBlank(language)) {
throw new IllegalArgumentException("Must provide non-empty language parameter to filter translations for language");
}
Expand All @@ -160,7 +168,9 @@ public Long getId() {
}

/**
* Remove all empty translations from the translations list
* Remove all empty translations from the translations list.
*
* @should clear the list
*/
public void cleanTranslations() {
Iterator<TermsOfUseTranslation> i = this.translations.iterator();
Expand All @@ -172,4 +182,13 @@ public void cleanTranslations() {
}
}

/**
* For testing.
*
* @return the translations
*/
List<TermsOfUseTranslation> getTranslations() {
return translations;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public ArchiveEntry(Integer order, Integer hierarchy, SolrDocument doc) {
*
* @param orig
* @param parent
* @should clone entry correctly
*/
public ArchiveEntry(ArchiveEntry orig, ArchiveEntry parent) {
this.parentNode = parent;
Expand Down Expand Up @@ -432,6 +433,8 @@ public void setDisplaySearch(boolean displaySearch, boolean recursive) {
* Checks whether access to the given node is allowed due to set access conditions.
*
* @return true if access granted; false otherwise
* @should return true if access conditions empty
* @should check access correctly
*/
public boolean isAccessAllowed() {
if (getAccessConditions().isEmpty()) {
Expand All @@ -441,7 +444,7 @@ public boolean isAccessAllowed() {

try {
boolean ret = AccessConditionUtils
.checkAccessPermissionByIdentifierAndLogId(topstructPi, logId, IPrivilegeHolder.PRIV_LIST, BeanUtils.getRequest())
.checkAccessPermissionByIdentifierAndLogId(topstructPi, logId, IPrivilegeHolder.PRIV_ARCHIVE_DISPLAY_NODE, BeanUtils.getRequest())
.isGranted();
if (!ret) {
logger.trace("Access denied to {}", label);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import de.unigoettingen.sub.commons.contentlib.exceptions.ContentLibException;
import io.goobi.viewer.controller.DataManager;
import io.goobi.viewer.controller.StringConstants;
import io.goobi.viewer.controller.StringTools;
import io.goobi.viewer.exceptions.DAOException;
import io.goobi.viewer.exceptions.IndexUnreachableException;
import io.goobi.viewer.exceptions.PresentationException;
Expand Down Expand Up @@ -180,6 +181,7 @@ public static SyndFeed createRss(String rootPath, String query, List<String> fil
List<SyndEntry> entries = new ArrayList<>();

String sortOrder = sortDescending ? "desc" : "asc";
logger.trace("RSS query: {}", StringTools.cleanUserGeneratedData(query)); //NOSONAR Output is cleaned up prior to logging
SolrDocumentList docs = DataManager.getInstance()
.getSearchIndex()
.search(query, 0, maxItems,
Expand Down Expand Up @@ -732,33 +734,57 @@ public static Channel createRssResponse(final String language, final Integer max
* @return RSS feed as {@link String}
* @throws ContentLibException
*/
public static String createRssFeed(final String language, final Integer maxHits, String subtheme, final String query, String facets,
public static String createRssFeedString(final String language, final Integer maxHits, String subtheme, final String query, String facets,
HttpServletRequest servletRequest, String sortField, boolean sortDescending)
throws ContentLibException {
try {
String q = createQuery(query, null, subtheme, servletRequest, false);
if (StringUtils.isNotBlank(q)) {
q = SearchHelper.buildFinalQuery(q, false, servletRequest, SearchAggregationType.AGGREGATE_TO_TOPSTRUCT);
}

// Optional faceting
List<String> filterQueries = null;
if (StringUtils.isNotBlank(facets)) {
SearchFacets searchFacets = new SearchFacets();
searchFacets.setActiveFacetString(facets);
filterQueries = searchFacets.generateFacetFilterQueries(true);
}

SyndFeedOutput output = new SyndFeedOutput();
return output
.outputString(RSSFeed.createRss(ServletUtils.getServletPathWithHostAsUrlFromRequest(servletRequest), q, filterQueries,
language != null ? language : servletRequest.getLocale().getLanguage(),
maxHits != null ? maxHits : DataManager.getInstance().getConfiguration().getRssFeedItems(), sortField, sortDescending));
.outputString(createRssFeed(language, maxHits, subtheme, query, facets, servletRequest, sortField, sortDescending));

} catch (PresentationException | IndexUnreachableException | ViewerConfigurationException | DAOException | FeedException e) {
throw new ContentLibException(e.toString());
}
}

/**
*
* @param language
* @param maxHits
* @param subtheme
* @param query
* @param facets
* @param servletRequest
* @param sortField
* @param sortDescending
* @return {@link SyndFeed}
* @throws PresentationException
* @throws IndexUnreachableException
* @throws ViewerConfigurationException
* @throws DAOException
*/
public static SyndFeed createRssFeed(final String language, final Integer maxHits, String subtheme, final String query, String facets,
HttpServletRequest servletRequest, String sortField, boolean sortDescending)
throws PresentationException, IndexUnreachableException, ViewerConfigurationException, DAOException {
String q = createQuery(query, null, subtheme, servletRequest, false);
if (StringUtils.isNotBlank(q)) {
q = SearchHelper.buildFinalQuery(q, false, servletRequest, SearchAggregationType.AGGREGATE_TO_TOPSTRUCT);
}

// Optional faceting
List<String> filterQueries = null;
if (StringUtils.isNotBlank(facets)) {
SearchFacets searchFacets = new SearchFacets();
searchFacets.setActiveFacetString(facets);
filterQueries = searchFacets.generateFacetFilterQueries(true);
}

return RSSFeed.createRss(ServletUtils.getServletPathWithHostAsUrlFromRequest(servletRequest), q, filterQueries,
language != null ? language : servletRequest.getLocale().getLanguage(),
maxHits != null ? maxHits : DataManager.getInstance().getConfiguration().getRssFeedItems(), sortField, sortDescending);

}

/**
*
* @param query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected AbstractPrivilegeHolder() {
protected static final String[] PRIVS_RECORD =
{ PRIV_LIST, PRIV_VIEW_THUMBNAILS, PRIV_VIEW_IMAGES, PRIV_VIEW_VIDEO, PRIV_VIEW_AUDIO, PRIV_VIEW_FULLTEXT, PRIV_VIEW_METADATA,
PRIV_ZOOM_IMAGES, PRIV_DOWNLOAD_IMAGES, PRIV_DOWNLOAD_ORIGINAL_CONTENT, PRIV_DOWNLOAD_PAGE_PDF, PRIV_DOWNLOAD_PDF,
PRIV_DOWNLOAD_METADATA, PRIV_GENERATE_IIIF_MANIFEST, PRIV_VIEW_UGC, PRIV_DOWNLOAD_BORN_DIGITAL_FILES };
PRIV_DOWNLOAD_METADATA, PRIV_GENERATE_IIIF_MANIFEST, PRIV_VIEW_UGC, PRIV_DOWNLOAD_BORN_DIGITAL_FILES, PRIV_ARCHIVE_DISPLAY_NODE };

/** Constant array containing all constants for CMS privileges. */
protected static final String[] PRIVS_CMS =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ public interface IPrivilegeHolder {
public static final String PREFIX_TICKET = "TICKET_";
/** Constant <code>PREFIX_PRIV="PRIV_"</code> */
public static final String PREFIX_PRIV = "PRIV_";

/** Constant <code>PRIV_ARCHIVE_DISPLAY_NODE="PRIV_ARCHIVE_DISPLAY_NODE"</code> */
public static final String PRIV_ARCHIVE_DISPLAY_NODE = "ARCHIVE_DISPLAY_NODE";
/** Constant <code>PRIV_LIST="LIST"</code> */
public static final String PRIV_LIST = "LIST";
/** Constant <code>PRIV_VIEW_IMAGES="VIEW_IMAGES"</code> */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ public static boolean isImageOrPdfDownloadAllowed(String mimeTypeName) {
return mimeType.isImageOrPdfDownloadAllowed();
}

/**
*
* @param mimeType
* @return Part of mimeType after the slash; entire value if no slash
* @should return empty string if mimeType blank
* @should return empty string if mimeType contains no slash
* @should return second part
*/
public static String getSpecificMimeType(String mimeType) {
if (StringUtils.isBlank(mimeType)) {
return "";
Expand All @@ -151,8 +159,7 @@ public static String getSpecificMimeType(String mimeType) {
String useName = mimeType;
if (useName.contains("/")) {
return useName.substring(useName.indexOf("/") + 1);
} else {
return "";
}
return "";
}
}
Loading

0 comments on commit 423f552

Please sign in to comment.