diff --git a/pom.xml b/pom.xml index 39428683..2ebe1945 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,7 @@ de.digitalcollections iiif-server-hymir - 5.1.9-SNAPSHOT + 6.0.0-SNAPSHOT jar https://github.com/dbmdz/iiif-server-hymir @@ -189,14 +189,6 @@ 7.3 runtime - - nz.net.ultraq.thymeleaf - thymeleaf-layout-dialect - - - org.apache.commons - commons-lang3 - org.assertj assertj-core @@ -240,95 +232,10 @@ - - org.springframework.boot - spring-boot-starter-thymeleaf - org.springframework.boot spring-boot-starter-web - - org.thymeleaf.extras - thymeleaf-extras-conditionalcomments - 2.1.2.RELEASE - - - org.webjars - html5shiv - 3.7.3-1 - - - org.webjars - mirador - 2.7.0 - - - org.webjars.bower - ie10-viewport-bug-workaround - 1.0.3 - - - org.webjars.npm - bootstrap - 4.6.0 - - - org.webjars - jquery - - - - - org.webjars.npm - dbmdz__mirador-canvaslink - 1.2.4 - - - org.webjars.npm - dbmdz__mirador-downloadmenu - 1.0.6 - - - org.webjars.npm - dbmdz__mirador-imagecropper - 2.4.6 - - - org.webjars.npm - dbmdz__mirador-keyboardnavigation - 1.1.0 - - - org.webjars.npm - dbmdz__mirador-physicalruler - 1.3.4 - - - org.webjars.npm - dbmdz__mirador-sharebuttons - 1.0.2 - - - org.webjars.npm - dbmdz__mirador-viewfromurl - 1.2.0 - - - org.webjars.npm - jquery - 3.6.4 - - - org.webjars.npm - openseadragon - 2.4.2 - - - org.webjars.npm - respond.js - 1.4.2 - diff --git a/src/main/java/de/digitalcollections/iiif/hymir/config/CustomResponseHeaders.java b/src/main/java/de/digitalcollections/iiif/hymir/config/CustomResponseHeaders.java index 71ab914b..0a687f5c 100644 --- a/src/main/java/de/digitalcollections/iiif/hymir/config/CustomResponseHeaders.java +++ b/src/main/java/de/digitalcollections/iiif/hymir/config/CustomResponseHeaders.java @@ -16,23 +16,13 @@ public class CustomResponseHeaders { private final List imageTile; private final List imageInfo; - private final List presentationManifest; - private final List presentationAnnotationList; - private final List presentationCollection; // custom.iiif.headers - public CustomResponseHeaders( - List all, - ImageResponseHeaders image, - PresentationResponseHeaders presentation) { + public CustomResponseHeaders(List all, ImageResponseHeaders image) { all = Objects.requireNonNullElseGet(all, Collections::emptyList); image = Objects.requireNonNullElseGet(image, ImageResponseHeaders::empty); - presentation = Objects.requireNonNullElseGet(presentation, PresentationResponseHeaders::empty); this.imageTile = concatenate(all, image.image); this.imageInfo = concatenate(all, image.info); - this.presentationManifest = concatenate(all, presentation.manifest); - this.presentationAnnotationList = concatenate(all, presentation.annotationList); - this.presentationCollection = concatenate(all, presentation.collection); } private List concatenate( @@ -50,18 +40,6 @@ public List forImageInfo() { return unmodifiableList(imageInfo); } - public List forPresentationManifest() { - return unmodifiableList(presentationManifest); - } - - public List forPresentationCollection() { - return unmodifiableList(presentationCollection); - } - - public List forPresentationAnnotationList() { - return unmodifiableList(presentationAnnotationList); - } - protected static class ImageResponseHeaders { private final List image; @@ -85,39 +63,6 @@ public static ImageResponseHeaders empty() { } } - @ConstructorBinding - protected static class PresentationResponseHeaders { - - private final List manifest; - private final List collection; - private final List annotationList; - - public PresentationResponseHeaders( - List manifest, - List collection, - List annotationList) { - this.manifest = Objects.requireNonNullElseGet(manifest, Collections::emptyList); - this.collection = Objects.requireNonNullElseGet(collection, Collections::emptyList); - this.annotationList = Objects.requireNonNullElseGet(annotationList, Collections::emptyList); - } - - public List getManifest() { - return unmodifiableList(manifest); - } - - public List getCollection() { - return unmodifiableList(collection); - } - - public List getAnnotationList() { - return unmodifiableList(annotationList); - } - - public static PresentationResponseHeaders empty() { - return new PresentationResponseHeaders(emptyList(), emptyList(), emptyList()); - } - } - public static class ResponseHeader { private final String name; diff --git a/src/main/java/de/digitalcollections/iiif/hymir/config/SpringConfigBackendPresentation.java b/src/main/java/de/digitalcollections/iiif/hymir/config/SpringConfigBackendPresentation.java deleted file mode 100644 index f2390b44..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/config/SpringConfigBackendPresentation.java +++ /dev/null @@ -1,10 +0,0 @@ -package de.digitalcollections.iiif.hymir.config; - -import de.digitalcollections.commons.file.config.SpringConfigCommonsFile; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** Backend configuration. */ -@Configuration -@Import(SpringConfigCommonsFile.class) -public class SpringConfigBackendPresentation {} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/config/SpringConfigWeb.java b/src/main/java/de/digitalcollections/iiif/hymir/config/SpringConfigWeb.java index d7d309e5..3733050c 100644 --- a/src/main/java/de/digitalcollections/iiif/hymir/config/SpringConfigWeb.java +++ b/src/main/java/de/digitalcollections/iiif/hymir/config/SpringConfigWeb.java @@ -1,31 +1,13 @@ package de.digitalcollections.iiif.hymir.config; -import de.digitalcollections.commons.springmvc.interceptors.CurrentUrlAsModelAttributeHandlerInterceptor; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.LocaleResolver; -import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; -import org.springframework.web.servlet.i18n.SessionLocaleResolver; import org.springframework.web.util.UrlPathHelper; @Configuration public class SpringConfigWeb implements WebMvcConfigurer { - @Override - public void addInterceptors(InterceptorRegistry registry) { - LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor(); - localeChangeInterceptor.setParamName("language"); - registry.addInterceptor(localeChangeInterceptor); - - CurrentUrlAsModelAttributeHandlerInterceptor currentUrlAsModelAttributeHandlerInterceptor = - new CurrentUrlAsModelAttributeHandlerInterceptor(); - currentUrlAsModelAttributeHandlerInterceptor.deleteParams("language"); - registry.addInterceptor(currentUrlAsModelAttributeHandlerInterceptor); - } - @Override public void configurePathMatch(PathMatchConfigurer configurer) { // Needed for escaped slashes in identifiers @@ -33,9 +15,4 @@ public void configurePathMatch(PathMatchConfigurer configurer) { urlPathHelper.setUrlDecode(false); configurer.setUrlPathHelper(urlPathHelper); } - - @Bean - public LocaleResolver localeResolver() { - return new SessionLocaleResolver(); - } } diff --git a/src/main/java/de/digitalcollections/iiif/hymir/config/WebjarProperties.java b/src/main/java/de/digitalcollections/iiif/hymir/config/WebjarProperties.java deleted file mode 100644 index 4146c037..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/config/WebjarProperties.java +++ /dev/null @@ -1,24 +0,0 @@ -package de.digitalcollections.iiif.hymir.config; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.util.HashMap; -import java.util.Map; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** Model for the webjar versions in application-webjars.yml. */ -@ConfigurationProperties(prefix = "webjars") -public class WebjarProperties { - - private final Map versions; - - public WebjarProperties(Map versions) { - this.versions = new HashMap<>(versions); - } - - @SuppressFBWarnings( - value = {"EI_EXPOSE_REP", "EI_EXPOSE_REP2"}, - justification = "Value is only used by the Spring framework") - public Map getVersions() { - return versions; - } -} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/frontend/ExtendedViewController.java b/src/main/java/de/digitalcollections/iiif/hymir/frontend/ExtendedViewController.java deleted file mode 100644 index c07d7c1e..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/frontend/ExtendedViewController.java +++ /dev/null @@ -1,104 +0,0 @@ -package de.digitalcollections.iiif.hymir.frontend; - -import de.digitalcollections.commons.server.HttpLoggingUtilities; -import de.digitalcollections.iiif.hymir.model.exception.InvalidDataException; -import de.digitalcollections.iiif.hymir.model.exception.ResolvingException; -import de.digitalcollections.iiif.hymir.presentation.business.api.PresentationService; -import de.digitalcollections.iiif.hymir.presentation.frontend.IIIFPresentationApiController; -import de.digitalcollections.model.exception.ResourceNotFoundException; -import java.net.URI; -import javax.servlet.http.HttpServletRequest; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.MDC; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; - -/** - * Controller for serving viewer page. - * - *

Provides direct access to viewer for external call. Can be overwritten with custom behaviour. - */ -@Deprecated(forRemoval = true) // Will be gone with the next major version -@Controller -public class ExtendedViewController { - - private static final Logger log = LoggerFactory.getLogger(ExtendedViewController.class); - - @Autowired private PresentationService presentationService; - - @RequestMapping(value = "/presentation/{identifier}/view.html", method = RequestMethod.GET) - public String viewExtendedPresentationGet(@PathVariable String identifier, Model model) { - model.addAttribute( - "presentationUri", - "/presentation/" + IIIFPresentationApiController.VERSION + "/" + identifier); - return "mirador/view"; - } - - /** - * Direct link for viewing a specified canvas (page) used for - * citation.https://api.digitale-sammlungen.de/iiif/presentation/v2/bsb00107186/canvas/1 - * - * @param version api version - * @param objectIdentifier object identifier - * @param canvasName name of canvas - * @param model mvc model - * @param request request - * @return canvas specific view - * @throws ResolvingException if identifier of manifest can not be resolved - * @throws ResourceNotFoundException if manifest not found - * @throws InvalidDataException if manifest can't be read - */ - @RequestMapping( - value = "/presentation/{version}/{objectIdentifier}/canvas/{canvasName}/view", - method = RequestMethod.GET) - public String viewCanvasGet( - @PathVariable String version, - @PathVariable String objectIdentifier, - @PathVariable String canvasName, - Model model, - HttpServletRequest request) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - HttpLoggingUtilities.addRequestClientInfoToMDC(request); - MDC.put("manifestId", objectIdentifier); - MDC.put("canvasName", canvasName); - - String url = getOriginalUri(request).toString(); - String canvasId = url.substring(0, url.indexOf("/view")); - String manifestId = url.substring(0, url.indexOf("/canvas")) + "/manifest"; - - try { - presentationService.getCanvas(objectIdentifier, canvasId); - log.info("Serving Canvas for {}", canvasId); - - model.addAttribute("manifestId", manifestId); - model.addAttribute("canvasId", canvasId); - - } catch (ResolvingException e) { - log.info("Did not find canvas for {}", canvasId); - throw e; - } catch (InvalidDataException e) { - log.error("Bad data for {}", objectIdentifier); - throw e; - } finally { - MDC.clear(); - } - - return "mirador/view_canvas"; - } - - private URI getOriginalUri(HttpServletRequest request) { - String requestUrl = request.getRequestURL().toString(); - String incomingScheme = URI.create(requestUrl).getScheme(); - String originalScheme = request.getHeader("X-Forwarded-Proto"); - if (originalScheme != null && !incomingScheme.equals(originalScheme)) { - return URI.create(requestUrl.replaceFirst("^" + incomingScheme, originalScheme)); - } else { - return URI.create(requestUrl); - } - } -} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/frontend/GlobalControllerAdvice.java b/src/main/java/de/digitalcollections/iiif/hymir/frontend/GlobalControllerAdvice.java deleted file mode 100644 index d861cb34..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/frontend/GlobalControllerAdvice.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.digitalcollections.iiif.hymir.frontend; - -import de.digitalcollections.iiif.hymir.config.WebjarProperties; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import java.util.Map; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ModelAttribute; - -@ControllerAdvice -public class GlobalControllerAdvice { - - private final Map webjarVersions; - - public GlobalControllerAdvice(WebjarProperties webjarProperties) { - this.webjarVersions = webjarProperties.getVersions(); - } - - @SuppressFBWarnings( - value = "EI_EXPOSE_REP", - justification = "Value is only used by the Spring framework") - /** Adds the webjar versions read from yaml files as global model attribute. */ - @ModelAttribute("webjarVersions") - public Map getWebjarVersions() { - return webjarVersions; - } -} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/frontend/ViewController.java b/src/main/java/de/digitalcollections/iiif/hymir/frontend/ViewController.java deleted file mode 100644 index 8861c965..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/frontend/ViewController.java +++ /dev/null @@ -1,66 +0,0 @@ -package de.digitalcollections.iiif.hymir.frontend; - -import de.digitalcollections.iiif.hymir.image.frontend.IIIFImageApiController; -import de.digitalcollections.iiif.hymir.presentation.frontend.IIIFPresentationApiController; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; - -/** Controller for serving different view pages. */ -@Deprecated(forRemoval = true) // Will be gone with the next major version -@Controller -public class ViewController { - - @RequestMapping( - value = {"", "/"}, - method = RequestMethod.GET) - public String viewHomepage(Model model) { - model.addAttribute("menu", "home"); - return "index"; - } - - @RequestMapping(value = "/image/{identifier}/view.html", method = RequestMethod.GET) - public String viewImageGet(@PathVariable String identifier, Model model) { - model.addAttribute( - "infoUrl", "/image/" + IIIFImageApiController.VERSION + "/" + identifier + "/info.json"); - return "openseadragon/view"; - } - - @RequestMapping(value = "/image/view", method = RequestMethod.POST) - public String viewImagePost(@RequestParam String identifier) { - return "redirect:/image/" + identifier + "/view.html"; - } - - @RequestMapping(value = "/presentation/view", method = RequestMethod.POST) - public String viewPresentationPost(@RequestParam String identifier, Model model) { - return "redirect:/presentation/view/" + identifier; - } - - @RequestMapping(value = "/presentation/view/{identifier}", method = RequestMethod.GET) - public String viewPresentationGet(@PathVariable String identifier, Model model) { - model.addAttribute( - "presentationUri", - "/presentation/" + IIIFPresentationApiController.VERSION + "/" + identifier); - return "mirador/view"; - } - - @RequestMapping(value = "/presentation/manifest", method = RequestMethod.GET) - public String viewPresentationManifest(@RequestParam String identifier) { - return "redirect:/presentation/" - + IIIFPresentationApiController.VERSION - + "/" - + identifier - + "/manifest"; - } - - @RequestMapping(value = "/presentation/collection", method = RequestMethod.GET) - public String viewPresentationCollection(@RequestParam String name) { - return "redirect:/presentation/" - + IIIFPresentationApiController.VERSION - + "/collection/" - + name; - } -} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/presentation/backend/PresentationRepositoryImpl.java b/src/main/java/de/digitalcollections/iiif/hymir/presentation/backend/PresentationRepositoryImpl.java deleted file mode 100644 index 4cb71406..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/presentation/backend/PresentationRepositoryImpl.java +++ /dev/null @@ -1,155 +0,0 @@ -package de.digitalcollections.iiif.hymir.presentation.backend; - -import de.digitalcollections.commons.file.backend.FileSystemResourceIOException; -import de.digitalcollections.commons.file.business.api.FileResourceService; -import de.digitalcollections.iiif.hymir.model.exception.InvalidDataException; -import de.digitalcollections.iiif.hymir.model.exception.ResolvingException; -import de.digitalcollections.iiif.hymir.presentation.backend.api.PresentationRepository; -import de.digitalcollections.iiif.model.jackson.IiifObjectMapper; -import de.digitalcollections.iiif.model.sharedcanvas.AnnotationList; -import de.digitalcollections.iiif.model.sharedcanvas.Collection; -import de.digitalcollections.iiif.model.sharedcanvas.Manifest; -import de.digitalcollections.model.exception.ResourceIOException; -import de.digitalcollections.model.exception.ResourceNotFoundException; -import de.digitalcollections.model.file.MimeType; -import de.digitalcollections.model.identifiable.resource.FileResource; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.time.ZoneOffset; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Repository; - -/** - * Default implementation trying to get manifest.json from an resolved URI as String and returning - * Manifest instance. - */ -@Repository -@Deprecated(forRemoval = true) // Will be gone with the next major version -public class PresentationRepositoryImpl implements PresentationRepository { - - private static final String COLLECTION_PREFIX = "collection-"; - - private static final Logger log = LoggerFactory.getLogger(PresentationRepositoryImpl.class); - - @Autowired private IiifObjectMapper objectMapper; - - @Autowired private FileResourceService fileResourceService; - - @Override - public AnnotationList getAnnotationList(String identifier, String name, String canvasId) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - String annotationListName = name + "-" + identifier + "_" + canvasId; - FileResource resource; - try { - resource = fileResourceService.find(annotationListName, MimeType.MIME_APPLICATION_JSON); - } catch (FileSystemResourceIOException e) { - // We have to throw a RTE since we don't want to break with the API, but still - // have a different error handling path than Resolving/InvalidData. - throw new RuntimeException(e); - } catch (ResourceIOException ex) { - log.error("Error getting annotation list for name {}", annotationListName, ex); - throw new ResolvingException("No annotation list for name " + annotationListName); - } - try { - return objectMapper.readValue(getResourceJson(resource), AnnotationList.class); - } catch (FileSystemResourceIOException e) { - // See comment above - throw new RuntimeException(e); - } catch (IOException ex) { - log.error("Could not retrieve annotation list {}", annotationListName, ex); - throw new InvalidDataException( - "Annotation list " + annotationListName + " can not be parsed", ex); - } - } - - @Override - public Collection getCollection(String name) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - // to get a regex resolvable pattern we add a static prefix for collections - String collectionName = COLLECTION_PREFIX + name; - FileResource resource; - try { - resource = fileResourceService.find(collectionName, MimeType.MIME_APPLICATION_JSON); - } catch (FileSystemResourceIOException e) { - // We have to throw a RTE since we don't want to break with the API, but still - // have a different error handling path than Resolving/InvalidData. - throw new RuntimeException(e); - } catch (ResourceIOException ex) { - log.error("Error getting manifest for collection {}", name, ex); - throw new ResolvingException("No collection for name " + name); - } - try { - return objectMapper.readValue(getResourceJson(resource), Collection.class); - } catch (FileSystemResourceIOException e) { - // We have to throw a RTE since we don't want to break with the API, but still - // have a different error handling path than Resolving/InvalidData. - throw new RuntimeException(e); - } catch (IOException ex) { - log.info("Could not retrieve collection {}", collectionName, ex); - throw new InvalidDataException( - "Collection for name " + collectionName + " can not be parsed", ex); - } - } - - @Override - public Manifest getManifest(String identifier) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - FileResource resource; - try { - resource = fileResourceService.find(identifier, MimeType.MIME_APPLICATION_JSON); - } catch (FileSystemResourceIOException e) { - // We have to throw a RTE since we don't want to break with the API, but still - // have a different error handling path than Resolving/InvalidData. - throw new RuntimeException(e); - } catch (ResourceIOException ex) { - log.error("Error getting manifest for identifier {}", identifier, ex); - throw new ResolvingException("No manifest for identifier " + identifier); - } - try { - return objectMapper.readValue(getResourceJson(resource), Manifest.class); - } catch (FileSystemResourceIOException e) { - // We have to throw a RTE since we don't want to break with the API, but still - // have a different error handling path than Resolving/InvalidData. - throw new RuntimeException(e); - } catch (IOException ex) { - log.error("Manifest {} can not be parsed", identifier, ex); - throw new InvalidDataException("Manifest " + identifier + " can not be parsed", ex); - } - } - - @Override - public Instant getManifestModificationDate(String identifier) - throws ResolvingException, ResourceNotFoundException { - return getResourceModificationDate(identifier); - } - - @Override - public Instant getCollectionModificationDate(String identifier) - throws ResolvingException, ResourceNotFoundException { - return getResourceModificationDate(identifier); - } - - private Instant getResourceModificationDate(String identifier) - throws ResolvingException, ResourceNotFoundException { - try { - FileResource resource = fileResourceService.find(identifier, MimeType.MIME_APPLICATION_JSON); - return resource.getLastModified().toInstant(ZoneOffset.UTC); - } catch (FileSystemResourceIOException e) { - // We have to throw a RTE since we don't want to break with the API, but still - // have a different error handling path than Resolving/InvalidData. - throw new RuntimeException(e); - } catch (ResourceIOException ex) { - log.error( - "Error getting resource for identifier '{}', message '{}'", identifier, ex.getMessage()); - throw new ResolvingException("No manifest for identifier " + identifier); - } - } - - protected String getResourceJson(FileResource resource) - throws ResourceIOException, ResourceNotFoundException { - return fileResourceService.getAsString(resource, StandardCharsets.UTF_8); - } -} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/presentation/backend/api/PresentationRepository.java b/src/main/java/de/digitalcollections/iiif/hymir/presentation/backend/api/PresentationRepository.java deleted file mode 100644 index 6e9ec551..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/presentation/backend/api/PresentationRepository.java +++ /dev/null @@ -1,56 +0,0 @@ -package de.digitalcollections.iiif.hymir.presentation.backend.api; - -import de.digitalcollections.iiif.hymir.model.exception.InvalidDataException; -import de.digitalcollections.iiif.hymir.model.exception.ResolvingException; -import de.digitalcollections.iiif.model.sharedcanvas.AnnotationList; -import de.digitalcollections.iiif.model.sharedcanvas.Collection; -import de.digitalcollections.iiif.model.sharedcanvas.Manifest; -import de.digitalcollections.model.exception.ResourceNotFoundException; -import java.time.Instant; - -/** Interface to be implemented by project/user of this library. */ -@Deprecated(forRemoval = true) // Will be gone with the next major version -public interface PresentationRepository { - - /** - * @param identifier unique identifier of the corresponding manifest - * @param name unique name of annotation list - * @param canvasId name of the corresponding canvas - * @return AnnotationList specified by name - * @throws ResolvingException if no annotation list found - * @throws ResourceNotFoundException if annotation list with given name can not be found - * @throws InvalidDataException if data is corrupted - */ - AnnotationList getAnnotationList(String identifier, String name, String canvasId) - throws ResolvingException, ResourceNotFoundException, InvalidDataException; - - /** - * @param name unique name of collection - * @return Collection specified by name - * @throws ResolvingException in case Collection does not exist or can not be delivered - * @throws ResourceNotFoundException if Collection with given name can not be found - * @throws InvalidDataException if collection contains invalid data - */ - Collection getCollection(String name) - throws ResolvingException, ResourceNotFoundException, InvalidDataException; - - /** - * @param identifier unique id for IIIF resource - * @return Manifest specifying presentation for IIIF resource - * @throws ResolvingException in case Manifest does not exist or can not be delivered - * @throws ResourceNotFoundException if Manifest with given identifier can not be found - * @throws InvalidDataException if manifest contains invalid data - */ - Manifest getManifest(String identifier) - throws ResolvingException, ResourceNotFoundException, InvalidDataException; - - default Instant getManifestModificationDate(String identifier) - throws ResolvingException, ResourceNotFoundException { - return null; - } - - default Instant getCollectionModificationDate(String identifier) - throws ResolvingException, ResourceNotFoundException { - return null; - } -} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/presentation/business/PresentationServiceImpl.java b/src/main/java/de/digitalcollections/iiif/hymir/presentation/business/PresentationServiceImpl.java deleted file mode 100644 index 481a6c48..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/presentation/business/PresentationServiceImpl.java +++ /dev/null @@ -1,73 +0,0 @@ -package de.digitalcollections.iiif.hymir.presentation.business; - -import de.digitalcollections.iiif.hymir.model.exception.InvalidDataException; -import de.digitalcollections.iiif.hymir.model.exception.ResolvingException; -import de.digitalcollections.iiif.hymir.presentation.backend.api.PresentationRepository; -import de.digitalcollections.iiif.hymir.presentation.business.api.PresentationSecurityService; -import de.digitalcollections.iiif.hymir.presentation.business.api.PresentationService; -import de.digitalcollections.iiif.model.sharedcanvas.AnnotationList; -import de.digitalcollections.iiif.model.sharedcanvas.Collection; -import de.digitalcollections.iiif.model.sharedcanvas.Manifest; -import de.digitalcollections.model.exception.ResourceNotFoundException; -import java.time.Instant; -import javax.servlet.http.HttpServletRequest; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -@Deprecated(forRemoval = true) // Will be gone with the next major version -public class PresentationServiceImpl implements PresentationService { - - private final PresentationRepository presentationRepository; - - private final PresentationSecurityService presentationSecurityService; - - // FIXME: Yes, this is incredibly nasty and violates "separation of concerns", but it's the - // only way to implement ACL based on user-supplied data without refactoring a significant - // part of the API and breaking implementers left and right. - // This should be done properly with the next major release that introduces API breakage - // anyway - @Autowired private HttpServletRequest currentRequest; - - @Autowired - public PresentationServiceImpl( - PresentationRepository presentationRepository, - @Autowired(required = false) PresentationSecurityService presentationSecurityService) { - this.presentationRepository = presentationRepository; - this.presentationSecurityService = presentationSecurityService; - } - - @Override - public AnnotationList getAnnotationList(String identifier, String name, String canvasId) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - return presentationRepository.getAnnotationList(identifier, name, canvasId); - } - - @Override - public Collection getCollection(String name) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - return presentationRepository.getCollection(name); - } - - @Override - public Manifest getManifest(String identifier) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - if (presentationSecurityService != null - && !presentationSecurityService.isAccessAllowed(identifier, currentRequest)) { - throw new ResolvingException(); // TODO maybe throw an explicit 'access disallowed' exception - } - return presentationRepository.getManifest(identifier); - } - - @Override - public Instant getManifestModificationDate(String identifier) - throws ResolvingException, ResourceNotFoundException { - return presentationRepository.getManifestModificationDate(identifier); - } - - @Override - public Instant getCollectionModificationDate(String identifier) - throws ResolvingException, ResourceNotFoundException { - return presentationRepository.getCollectionModificationDate(identifier); - } -} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/presentation/business/api/PresentationSecurityService.java b/src/main/java/de/digitalcollections/iiif/hymir/presentation/business/api/PresentationSecurityService.java deleted file mode 100644 index 1d88ff42..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/presentation/business/api/PresentationSecurityService.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.digitalcollections.iiif.hymir.presentation.business.api; - -import javax.servlet.http.HttpServletRequest; - -/** Service responsible for deciding if object (identified by identifier) is accessible. */ -public interface PresentationSecurityService { - @Deprecated(forRemoval = true) // Will be gone with the next major version - boolean isAccessAllowed(String identifier); - - default boolean isAccessAllowed(String identifier, HttpServletRequest req) { - return this.isAccessAllowed(identifier); - } -} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/presentation/business/api/PresentationService.java b/src/main/java/de/digitalcollections/iiif/hymir/presentation/business/api/PresentationService.java deleted file mode 100644 index f7a59ea6..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/presentation/business/api/PresentationService.java +++ /dev/null @@ -1,114 +0,0 @@ -package de.digitalcollections.iiif.hymir.presentation.business.api; - -import de.digitalcollections.iiif.hymir.model.exception.InvalidDataException; -import de.digitalcollections.iiif.hymir.model.exception.ResolvingException; -import de.digitalcollections.iiif.model.sharedcanvas.AnnotationList; -import de.digitalcollections.iiif.model.sharedcanvas.Canvas; -import de.digitalcollections.iiif.model.sharedcanvas.Collection; -import de.digitalcollections.iiif.model.sharedcanvas.Manifest; -import de.digitalcollections.iiif.model.sharedcanvas.Range; -import de.digitalcollections.iiif.model.sharedcanvas.Resource; -import de.digitalcollections.iiif.model.sharedcanvas.Sequence; -import de.digitalcollections.model.exception.ResourceNotFoundException; -import java.net.URI; -import java.time.Instant; - -/** Service for IIIF Presentation API functionality. */ -@Deprecated(forRemoval = true) // Will be gone with the next major version -public interface PresentationService { - - /** - * @param identifier unique identifier of the corresponding manifest - * @param name unique name of annotation list - * @param canvasId name of the corresponding canvas - * @return AnnotationList specified by name - * @throws ResolvingException if no annotation list found - * @throws ResourceNotFoundException if annotation list with given name can not be found - * @throws InvalidDataException if data is corrupted - */ - AnnotationList getAnnotationList(String identifier, String name, String canvasId) - throws ResolvingException, ResourceNotFoundException, InvalidDataException; - - /** - * @param name unique name of collection - * @return Collection specified by name - * @throws ResolvingException if no collection found or access disallowed - * @throws ResourceNotFoundException if collection with given name can not be found - * @throws InvalidDataException if data is corrupted - */ - Collection getCollection(String name) - throws ResolvingException, ResourceNotFoundException, InvalidDataException; - - /** - * @param identifier unique id for IIIF resource - * @return Manifest specifying presentation for IIIF resource - * @throws ResolvingException if no manifest found or access disallowed - * @throws ResourceNotFoundException if Manifest with given identifier can not be found - * @throws InvalidDataException if data is corrupted - */ - Manifest getManifest(String identifier) - throws ResolvingException, ResourceNotFoundException, InvalidDataException; - - default Instant getManifestModificationDate(String identifier) - throws ResolvingException, ResourceNotFoundException { - return Instant.now(); - } - - default Instant getCollectionModificationDate(String identifier) - throws ResolvingException, ResourceNotFoundException { - return Instant.now(); - } - - default Canvas getCanvas(String manifestId, String canvasUri) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - return getCanvas(manifestId, URI.create(canvasUri)); - } - - default Canvas getCanvas(String manifestId, URI canvasUri) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - Manifest manifest = getManifest(manifestId); - return manifest.getSequences().stream() - .flatMap(seq -> seq.getCanvases().stream()) - .filter(canv -> canv.getIdentifier().equals(canvasUri)) - .map(canv -> this.copyAttributionInfo(manifest, canv)) - .findFirst() - .orElseThrow(ResolvingException::new); - } - - default Range getRange(String manifestId, String rangeUri) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - return getRange(manifestId, URI.create(rangeUri)); - } - - default Range getRange(String manifestId, URI rangeUri) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - Manifest manifest = getManifest(manifestId); - return manifest.getRanges().stream() - .filter(r -> r.getIdentifier().equals(rangeUri)) - .map(r -> this.copyAttributionInfo(manifest, r)) - .findFirst() - .orElseThrow(ResolvingException::new); - } - - default Sequence getSequence(String manifestId, String sequenceUri) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - return getSequence(manifestId, URI.create(sequenceUri)); - } - - default Sequence getSequence(String manifestId, URI sequenceUri) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - Manifest manifest = getManifest(manifestId); - return manifest.getSequences().stream() - .filter(s -> s.getIdentifier().equals(sequenceUri)) - .map(s -> this.copyAttributionInfo(manifest, s)) - .findFirst() - .orElseThrow(ResolvingException::new); - } - - default T copyAttributionInfo(Manifest manifest, T res) { - res.setLogos(manifest.getLogos()); - res.setAttribution(manifest.getAttribution()); - res.setLicenses(manifest.getLicenses()); - return res; - } -} diff --git a/src/main/java/de/digitalcollections/iiif/hymir/presentation/frontend/IIIFPresentationApiController.java b/src/main/java/de/digitalcollections/iiif/hymir/presentation/frontend/IIIFPresentationApiController.java deleted file mode 100644 index c4e62880..00000000 --- a/src/main/java/de/digitalcollections/iiif/hymir/presentation/frontend/IIIFPresentationApiController.java +++ /dev/null @@ -1,239 +0,0 @@ -package de.digitalcollections.iiif.hymir.presentation.frontend; - -import de.digitalcollections.iiif.hymir.config.CustomResponseHeaders; -import de.digitalcollections.iiif.hymir.model.exception.InvalidDataException; -import de.digitalcollections.iiif.hymir.model.exception.ResolvingException; -import de.digitalcollections.iiif.hymir.presentation.business.api.PresentationService; -import de.digitalcollections.iiif.hymir.util.UrlRules; -import de.digitalcollections.iiif.model.sharedcanvas.AnnotationList; -import de.digitalcollections.iiif.model.sharedcanvas.Canvas; -import de.digitalcollections.iiif.model.sharedcanvas.Collection; -import de.digitalcollections.iiif.model.sharedcanvas.Manifest; -import de.digitalcollections.iiif.model.sharedcanvas.Range; -import de.digitalcollections.iiif.model.sharedcanvas.Sequence; -import de.digitalcollections.model.exception.ResourceNotFoundException; -import java.net.URI; -import java.time.Instant; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.context.request.WebRequest; - -@Controller -@RequestMapping("${custom.iiif.presentation.urlPrefix:/presentation/v2}") -@Deprecated(forRemoval = true) // Will be gone with the next major version -public class IIIFPresentationApiController { - - public static final String VERSION = "v2"; - - @Autowired protected CustomResponseHeaders customResponseHeaders; - - @Autowired private PresentationService presentationService; - - // We set the header ourselves, since using @CrossOrigin doesn't expose "*", but always sets the - // requesting domain - // @CrossOrigin(allowedHeaders = {"*"}, origins = {"*"}) - @RequestMapping( - value = {"{identifier}/manifest", "{identifier}"}, - method = RequestMethod.GET, - produces = "application/json") - @ResponseBody - public Manifest getManifest( - @PathVariable String identifier, WebRequest request, HttpServletResponse resp) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - if (UrlRules.isInsecure(identifier)) { - resp.setStatus(400); - return null; - } - // Return 304 if the manifest has seen no modifications since the requested time - long modified = presentationService.getManifestModificationDate(identifier).toEpochMilli(); - if (request.checkNotModified(modified)) { - return null; - } - Manifest manifest = presentationService.getManifest(identifier); - resp.setDateHeader("Last-Modified", modified); - resp.addHeader("Access-Control-Allow-Origin", "*"); - - customResponseHeaders - .forPresentationManifest() - .forEach( - customResponseHeader -> { - resp.setHeader(customResponseHeader.getName(), customResponseHeader.getValue()); - }); - return manifest; - } - - @RequestMapping( - value = {"{identifier}/manifest", "{identifier}"}, - method = RequestMethod.HEAD) - public void checkManifest(@PathVariable String identifier, HttpServletResponse resp) - throws ResolvingException, ResourceNotFoundException { - if (UrlRules.isInsecure(identifier)) { - resp.setStatus(400); - return; - } - Instant modDate = presentationService.getManifestModificationDate(identifier); - resp.setDateHeader("Last-Modified", modDate.toEpochMilli()); - resp.addHeader("Access-Control-Allow-Origin", "*"); - - customResponseHeaders - .forPresentationManifest() - .forEach( - customResponseHeader -> { - resp.setHeader(customResponseHeader.getName(), customResponseHeader.getValue()); - }); - resp.setStatus(HttpServletResponse.SC_OK); - } - - @RequestMapping( - value = {"{manifestId}/canvas/{canvasId}"}, - method = RequestMethod.GET) - @ResponseBody - public Canvas getCanvas( - @PathVariable String manifestId, - @PathVariable String canvasId, - HttpServletRequest req, - HttpServletResponse resp) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - if (UrlRules.anyIsInsecure(manifestId, canvasId)) { - resp.setStatus(400); - return null; - } - resp.addHeader("Access-Control-Allow-Origin", "*"); - - customResponseHeaders - .forPresentationManifest() - .forEach( - customResponseHeader -> { - resp.setHeader(customResponseHeader.getName(), customResponseHeader.getValue()); - }); - return presentationService.getCanvas(manifestId, getOriginalUri(req)); - } - - @RequestMapping( - value = {"{manifestId}/range/{rangeId}"}, - method = RequestMethod.GET) - @ResponseBody - public Range getRange( - @PathVariable String manifestId, - @PathVariable String rangeId, - HttpServletRequest req, - HttpServletResponse resp) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - if (UrlRules.anyIsInsecure(manifestId, rangeId)) { - resp.setStatus(400); - return null; - } - resp.addHeader("Access-Control-Allow-Origin", "*"); - - customResponseHeaders - .forPresentationManifest() - .forEach( - customResponseHeader -> { - resp.setHeader(customResponseHeader.getName(), customResponseHeader.getValue()); - }); - return presentationService.getRange(manifestId, getOriginalUri(req)); - } - - @RequestMapping( - value = {"{manifestId}/sequence/{sequenceId}"}, - method = RequestMethod.GET) - @ResponseBody - public Sequence getSequence( - @PathVariable String manifestId, - @PathVariable String sequenceId, - HttpServletRequest req, - HttpServletResponse resp) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - if (UrlRules.anyIsInsecure(manifestId, sequenceId)) { - resp.setStatus(400); - return null; - } - resp.addHeader("Access-Control-Allow-Origin", "*"); - - customResponseHeaders - .forPresentationManifest() - .forEach( - customResponseHeader -> { - resp.setHeader(customResponseHeader.getName(), customResponseHeader.getValue()); - }); - return presentationService.getSequence(manifestId, getOriginalUri(req)); - } - - @RequestMapping( - value = {"collection/{identifier}"}, - method = {RequestMethod.GET, RequestMethod.HEAD}, - produces = "application/json") - @ResponseBody - public Collection getCollection( - @PathVariable String identifier, WebRequest request, HttpServletResponse resp) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - if (UrlRules.isInsecure(identifier)) { - resp.setStatus(400); - return null; - } - long modified = presentationService.getCollectionModificationDate(identifier).toEpochMilli(); - resp.addHeader("Access-Control-Allow-Origin", "*"); - - customResponseHeaders - .forPresentationCollection() - .forEach( - customResponseHeader -> { - resp.setHeader(customResponseHeader.getName(), customResponseHeader.getValue()); - }); - if (request.checkNotModified(modified)) { - return null; - } - Collection collection = presentationService.getCollection(identifier); - return collection; - } - - @GetMapping( - value = {"{identifier}/list/{name}/{canvasId}"}, - produces = "application/json") - @ResponseBody - public AnnotationList getAnnotationList( - @PathVariable String identifier, - @PathVariable String name, - @PathVariable String canvasId, - HttpServletResponse resp) - throws ResolvingException, ResourceNotFoundException, InvalidDataException { - if (UrlRules.anyIsInsecure(identifier, name, canvasId)) { - resp.setStatus(400); - return null; - } - resp.addHeader("Access-Control-Allow-Origin", "*"); - - customResponseHeaders - .forPresentationAnnotationList() - .forEach( - customResponseHeader -> { - resp.setHeader(customResponseHeader.getName(), customResponseHeader.getValue()); - }); - - return presentationService.getAnnotationList(identifier, name, canvasId); - } - - /** - * Return the URL as it was originally received from a possible frontend proxy. - * - * @param request Incoming request - * @return URL as it was received at the frontend proxy - */ - private URI getOriginalUri(HttpServletRequest request) { - String requestUrl = request.getRequestURL().toString(); - String incomingScheme = URI.create(requestUrl).getScheme(); - String originalScheme = request.getHeader("X-Forwarded-Proto"); - if (originalScheme != null && !incomingScheme.equals(originalScheme)) { - return URI.create(requestUrl.replaceFirst("^" + incomingScheme, originalScheme)); - } else { - return URI.create(requestUrl); - } - } -} diff --git a/src/main/resources/application-webjars.yml b/src/main/resources/application-webjars.yml deleted file mode 100644 index 923661dc..00000000 --- a/src/main/resources/application-webjars.yml +++ /dev/null @@ -1,16 +0,0 @@ -webjars: - versions: - bootstrap: '@version.webjar-bootstrap@' - html5shiv: '@version.webjar-html5shiv@' - ie10-viewport-bug-workaround: '@version.webjar-ie10-viewport-bug-workaround@' - jquery: '@version.webjar-jquery@' - mirador: '@version.webjar-mirador@' - mirador-canvaslink: '@version.webjar-mirador-canvaslink@' - mirador-downloadmenu: '@version.webjar-mirador-downloadmenu@' - mirador-imagecropper: '@version.webjar-mirador-imagecropper@' - mirador-keyboardnavigation: '@version.webjar-mirador-keyboardnavigation@' - mirador-physicalruler: '@version.webjar-mirador-physicalruler@' - mirador-sharebuttons: '@version.webjar-mirador-sharebuttons@' - mirador-viewfromurl: '@version.webjar-mirador-viewfromurl@' - openseadragon: '@version.webjar-openseadragon@' - respond: '@version.webjar-respond@' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1b417a8e..3c943d18 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -43,23 +43,11 @@ resourceRepository: - 'file:/var/local/iiif/images/$1/original/image_$1_$2.tif' - 'file:/var/local/iiif/images/$1/300/image_$1_$2.jpg' - 'file:/var/local/iiif/images/$1/150/image_$1_$2.jpg' - # An manifest pattern resolving example: - - pattern: ^(\d{8})$ - substitutions: - - 'file:/var/local/iiif/presentation/manifests/manifest_$1.json' # For the official IIIF Image API Validator - pattern: 67352ccc-d1b0-11e1-89ae-279075081939 substitutions: - 'classpath:validation.jp2' - 'classpath:validation.png' - # Collection manifests ('collection-' pattern-prefix is statically added to requested collection name to disambigued from other patterns) - - pattern: ^collection-(.*)$ - substitutions: - - 'file:/var/local/iiif/presentation/collections/$1.json' - # Annotation list of transcriptions - - pattern: ^transcription-(.*)$ - substitutions: - - 'file:/var/local/iiif/presentation/annotations/$1.json' server: error: @@ -82,14 +70,10 @@ spring: fallback-to-system-locale: false profiles: active: local - include: webjars security: user: name: admin password: secret - thymeleaf: - cache: false - mode: HTML --- @@ -103,5 +87,3 @@ spring: config: activate: on-profile: PROD - thymeleaf: - cache: true diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 69c8108d..e69de29b 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -1,18 +0,0 @@ -error.404.button_text=Take Me Home -error.404.page_title=Page not found -error.DEFAULT_MESSAGE=An error occured. -error.exception=Exception -error.message=Error message -error.page_title=Ooops! -error.reason=Error reason -error.stacktrace=Stacktrace -error.status_code=Status code -error.timestamp=Time error occured -error.url-path=Called url path -intro_text=Use below forms to view resources provided by this server. -resource=Resource -view=view -view_collection=View IIIF collection as JSON -view_image=View image with OpenSeadragon -view_manifest=View IIIF manifest as JSON -view_object=View object with Mirador \ No newline at end of file diff --git a/src/main/resources/messages_de.properties b/src/main/resources/messages_de.properties index 4b030733..e69de29b 100644 --- a/src/main/resources/messages_de.properties +++ b/src/main/resources/messages_de.properties @@ -1,18 +0,0 @@ -error.404.button_text=Zur Homepage -error.404.page_title=Seite nicht gefunden -error.DEFAULT_MESSAGE=Es ist ein Fehler aufgetreten. -error.exception=Exception -error.message=Fehlernachricht -error.page_title=Uuups! -error.reason=Fehlerursache -error.stacktrace=Stacktrace -error.status_code=Statuscode -error.timestamp=Fehler-Zeitpunkt -error.url-path=Aufgerufener URL-Pfad -intro_text=Benutzen Sie die Formulare, um die Ressourcen, die dieser Server zur Verf\u00fcgung stellt, anzuzeigen. -resource=Ressource -view=anzeigen -view_collection=IIIF-Collection als JSON anzeigen -view_image=Bild mit OpenSeadragon anzeigen -view_manifest=IIIF-Manifest als JSON anzeigen -view_object=Objekt mit Mirador anzeigen \ No newline at end of file diff --git a/src/main/resources/static/css/theme.css b/src/main/resources/static/css/theme.css deleted file mode 100644 index 9c4518b6..00000000 --- a/src/main/resources/static/css/theme.css +++ /dev/null @@ -1,66 +0,0 @@ -body { - padding-top: 65px; -} - -.navbar { - border-bottom: solid 1px #e5e5e5; - min-height: 45px; -} - -.navbar-brand.logo img { - height: 30px; -} - -#mirador-viewer { - background: #333; - height: calc(100vh - 115px); - position: relative; - width: 100%; -} - -#mirador-viewer .window-manifest-title { - height: 1.25em; -} - -#mirador-viewer .mirador-osd-annotation-controls * { - box-sizing: content-box; -} - -#mirador-viewer .metadata-listing .metadata-item { - padding-top: 5px; -} - -#mirador-viewer .metadata-listing .metadata-label, -#mirador-viewer .metadata-listing .metadata-value { - display: inline; -} - -#mirador-viewer .metadata-listing .metadata-label { - font-weight: bold; - margin-right: 10px; -} - -#mirador-viewer .metadata-listing img { - display: block; -} - -#mirador-viewer .mirador-osd-next, -#mirador-viewer .mirador-osd-previous, -#mirador-viewer .mirador-osd-toggle-bottom-panel { - color: white; -} - -#openseadragon-viewer { - border: solid 1px #e5e5e5; - height: calc(100vh - 205px); -} - -.error-page p { - text-align: left; -} - -footer { - border-top: solid 1px #AAA; - bottom: 0; - position: fixed; -} \ No newline at end of file diff --git a/src/main/resources/static/images/favicon.ico b/src/main/resources/static/images/favicon.ico deleted file mode 100644 index 5d022b18..00000000 Binary files a/src/main/resources/static/images/favicon.ico and /dev/null differ diff --git a/src/main/resources/static/images/hymir-logo.png b/src/main/resources/static/images/hymir-logo.png deleted file mode 100644 index 952698e5..00000000 Binary files a/src/main/resources/static/images/hymir-logo.png and /dev/null differ diff --git a/src/main/resources/templates/base.html b/src/main/resources/templates/base.html deleted file mode 100644 index 9c261fe6..00000000 --- a/src/main/resources/templates/base.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - Hymir IIIF Server - - - - - - - - - - - - - - - -

- -
-
-
- -
-
-
- - - - - - - - - - - - - - diff --git a/src/main/resources/templates/error.html b/src/main/resources/templates/error.html deleted file mode 100644 index 21571700..00000000 --- a/src/main/resources/templates/error.html +++ /dev/null @@ -1,35 +0,0 @@ - - - -
- -
-

Ooops!

- -

- : The status code -

-

- : The error reason -

-

- : The exception message -

-

- : The URL path when the exception was raised -

-

- : The time that the errors were extracted -

-

- : The class name of the root exception (if configured) -

-

- : The exception stack trace -

-
-
- - \ No newline at end of file diff --git a/src/main/resources/templates/error/404.html b/src/main/resources/templates/error/404.html deleted file mode 100644 index 9fc1cc24..00000000 --- a/src/main/resources/templates/error/404.html +++ /dev/null @@ -1,20 +0,0 @@ - - - -
-
-
Ooops!
-
-
Page not found
-

- - Take Me Home - -

-
-
-
- - \ No newline at end of file diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html deleted file mode 100644 index 815e1fdd..00000000 --- a/src/main/resources/templates/index.html +++ /dev/null @@ -1,83 +0,0 @@ - - - -
- - -
-

Hymir IIIF Server

-

...

-
- -
-
-
-
IIIF Image API 2.1
-
- - - - -
-
-

...

-
- /image/ /view.html -
- -
-
-
-
-
- -
-
-
IIIF Presentation API 2.1
-
- - - - - - - - - - -
-
-

...

-
- /presentation/ /view.html -
- -
-
-
-

...

-
- /presentation/v2/ /manifest -
- -
-
-
-

View collection as JSON

-
- /presentation/v2/collection/ -
- -
-
-
-
-
-
- - -
- - diff --git a/src/main/resources/templates/mirador/view.html b/src/main/resources/templates/mirador/view.html deleted file mode 100644 index 6b9c0c55..00000000 --- a/src/main/resources/templates/mirador/view.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
- - - - - - - - - - - - - - diff --git a/src/main/resources/templates/mirador/view_canvas.html b/src/main/resources/templates/mirador/view_canvas.html deleted file mode 100644 index 6a9067de..00000000 --- a/src/main/resources/templates/mirador/view_canvas.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - -
-
-
-
-
-
-
- - - - - - - - - - - - - - diff --git a/src/main/resources/templates/openseadragon/view.html b/src/main/resources/templates/openseadragon/view.html deleted file mode 100644 index 1a1098c1..00000000 --- a/src/main/resources/templates/openseadragon/view.html +++ /dev/null @@ -1,33 +0,0 @@ - - - -
-
-
-
- ... "..." in OpenSeadragon osd version -
-
-
-
-
- - - -
-
- - diff --git a/src/test/java/de/digitalcollections/iiif/hymir/config/CustomResponseHeadersTest.java b/src/test/java/de/digitalcollections/iiif/hymir/config/CustomResponseHeadersTest.java index 2696a735..83e1a684 100644 --- a/src/test/java/de/digitalcollections/iiif/hymir/config/CustomResponseHeadersTest.java +++ b/src/test/java/de/digitalcollections/iiif/hymir/config/CustomResponseHeadersTest.java @@ -31,8 +31,5 @@ public void testCustomResponseHeadersConfiguration() { ResponseHeader header1 = headersImageInfo.get(1); assertThat(header1.getName()).isEqualTo("header1"); assertThat(header1.getValue()).isEqualTo("value1"); - - assertThat(headers.forPresentationManifest().size()).isEqualTo(3); - assertThat(headers.forPresentationCollection().size()).isEqualTo(1); } } diff --git a/src/test/java/de/digitalcollections/iiif/hymir/presentation/frontend/IIIFPresentationApiControllerTest.java b/src/test/java/de/digitalcollections/iiif/hymir/presentation/frontend/IIIFPresentationApiControllerTest.java deleted file mode 100644 index feacbcbc..00000000 --- a/src/test/java/de/digitalcollections/iiif/hymir/presentation/frontend/IIIFPresentationApiControllerTest.java +++ /dev/null @@ -1,62 +0,0 @@ -package de.digitalcollections.iiif.hymir.presentation.frontend; - -import static org.assertj.core.api.Assertions.assertThat; - -import de.digitalcollections.iiif.hymir.Application; -import de.digitalcollections.iiif.hymir.TestConfiguration; -import de.digitalcollections.iiif.hymir.presentation.business.PresentationServiceImpl; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -@ExtendWith(SpringExtension.class) -@SpringBootTest( - properties = {"spring.profiles.active=TEST", "spring.config.name=application-test"}, - classes = {Application.class, TestConfiguration.class}, - webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class IIIFPresentationApiControllerTest { - - @LocalServerPort private int randomServerPort; - - @Autowired protected IIIFPresentationApiController iiifController; - - @Autowired protected PresentationServiceImpl presentationService; - - @Autowired private TestRestTemplate restTemplate; - - @BeforeAll - public static void beforeAll() { - System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true"); - TestConfiguration.setDefaults(); - } - - @Test - public void testInvalidDataInManifest() { - ResponseEntity response = - restTemplate.getForEntity( - "/presentation/" - + IIIFPresentationApiController.VERSION - + "/manifest-invalid-data/manifest", - String.class); - assertThat(response.getStatusCode()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR); - } - - @Test - public void testManifest() { - ResponseEntity response = - restTemplate.getForEntity( - "/presentation/" - + IIIFPresentationApiController.VERSION - + "/manifest-valid-data/manifest", - String.class); - assertThat(response.getHeaders().get("mani1")).containsExactly("mani-value1"); - assertThat(response.getHeaders().get("mani2")).containsExactly("mani-value2"); - } -} diff --git a/src/test/resources/application-test.yml b/src/test/resources/application-test.yml index bf05820b..65a3109d 100644 --- a/src/test/resources/application-test.yml +++ b/src/test/resources/application-test.yml @@ -11,13 +11,6 @@ custom: info: - name: 'header1' value: 'value1' - presentation: - manifest: - - name: 'mani1' - value: 'mani-value1' - - name: 'mani2' - value: 'mani-value2' - collection: null image: maxWidth: 65500 maxHeight: 65500 @@ -70,10 +63,6 @@ resourceRepository: substitutions: ['classpath\:mockdata/mock-square-width.jpg'] - pattern: square-height substitutions: ['classpath\:mockdata/mock-square-height.jpg'] - - pattern: manifest-invalid-data - substitutions: ['classpath\:mockdata/manifest-invalid-data.json'] - - pattern: manifest-valid-data - substitutions: ['classpath\:mockdata/manifest.json'] server: error: @@ -93,6 +82,4 @@ spring: name: admin password: secret roles: ACTUATOR - thymeleaf: - cache: false - mode: HTML +