source: gs3-extensions/iiif-servlet/trunk/src/src/main/java/edu/illinois/library/cantaloupe/resource/iiif/v2/GSInformationResource.java@ 32886

Last change on this file since 32886 was 32886, checked in by davidb, 5 years ago

Copy refactoring

File size: 9.0 KB
Line 
1package edu.illinois.library.cantaloupe.resource.iiif.v2;
2
3import java.io.IOException;
4import java.nio.file.Files;
5import java.nio.file.NoSuchFileException;
6import java.nio.file.Path;
7import java.util.List;
8
9import edu.illinois.library.cantaloupe.RestletApplication;
10import edu.illinois.library.cantaloupe.cache.CacheFacade;
11import edu.illinois.library.cantaloupe.config.Configuration;
12import edu.illinois.library.cantaloupe.config.Key;
13import edu.illinois.library.cantaloupe.image.Format;
14import edu.illinois.library.cantaloupe.image.Identifier;
15import edu.illinois.library.cantaloupe.image.Info;
16import edu.illinois.library.cantaloupe.processor.Processor;
17import edu.illinois.library.cantaloupe.processor.ProcessorFactory;
18import edu.illinois.library.cantaloupe.source.Source;
19import edu.illinois.library.cantaloupe.source.SourceFactory;
20import edu.illinois.library.cantaloupe.resource.JSONRepresentation;
21import edu.illinois.library.cantaloupe.processor.ProcessorConnector;
22import org.restlet.data.MediaType;
23import org.restlet.data.Preference;
24import org.restlet.data.Reference;
25import org.restlet.representation.EmptyRepresentation;
26import org.restlet.representation.Representation;
27import org.restlet.resource.Get;
28
29//import org.greenstone.gsdl3.IIIFServerBridge; // ****
30
31/**
32 * Handles IIIF Image API 2.x information requests.
33 *
34 * @see <a href="http://iiif.io/api/image/2.1/#information-request">Information
35 * Requests</a>
36 */
37public class GSInformationResource extends InformationResource {
38
39 /**
40 * Redirects {@literal /:identifier} to {@literal /:identifier/info.json},
41 * respecting the Servlet context root and
42 * {@link #PUBLIC_IDENTIFIER_HEADER} header.
43 */
44 public static class RedirectingResource extends IIIF2Resource {
45 @Get
46 public Representation doGet() {
47 final Reference newRef = new Reference(
48 getPublicRootReference() +
49 RestletApplication.IIIF_2_PATH + "/" +
50 getPublicIdentifier() +
51 "/info.json");
52 redirectSeeOther(newRef);
53 return new EmptyRepresentation();
54 }
55 }
56
57 /**
58 * Responds to information requests.
59 *
60 * @return {@link ImageInfo} instance serialized as JSON.
61 */
62 @Get
63 public Representation doGet() throws Exception {
64 final Configuration config = Configuration.getInstance();
65 final Identifier identifier = getIdentifier();
66 final CacheFacade cacheFacade = new CacheFacade();
67
68 // If we don't need to resolve first, and are using a cache, and the
69 // cache contains an info matching the request, skip all the setup and
70 // just return the cached info.
71 if (!isResolvingFirst()) {
72 try {
73 Info info = cacheFacade.getInfo(identifier);
74 if (info != null) {
75 // The source format will be null or UNKNOWN if the info was
76 // serialized in version < 3.4.
77 final Format format = info.getSourceFormat();
78 if (format != null && !Format.UNKNOWN.equals(format)) {
79 final Processor processor = new ProcessorFactory().
80 newProcessor(format);
81 commitCustomResponseHeaders();
82 return newRepresentation(info, processor);
83 }
84 }
85 } catch (IOException e) {
86 // Don't rethrow -- it's still possible to service the request.
87 getLogger().severe(e.getMessage());
88 }
89 }
90
91 final Identifier identifier_image = IdentifierToGSAssocfile.createIdentifierImage(identifier);
92 final Source source = new SourceFactory().newSource(identifier_image, getDelegateProxy());
93 /*
94 String identifier_str = identifier.toString();
95 String[] strs = identifier_str.split(":", 3);
96 if(strs == null || strs.length < 3) {
97 System.err.println("identifier is not in the form site:coll:id" + identifier_str);
98 return null;
99 }
100 String site_name = strs[0];
101 String coll_name = strs[1];
102 String doc_id = strs[2];
103
104 // Move into Constructor, ,and keep hashmap ???
105 IIIFServerBridge gs_iiif_bridge = new IIIFServerBridge();
106 gs_iiif_bridge.init(site_name);
107 String collect_image_filename = gs_iiif_bridge.doGetDocumentMessage(coll_name + ":" + doc_id);
108 String site_image_filename = site_name + "/collect/" + coll_name + "/index/assoc/" + collect_image_filename;
109
110 //System.err.println("**** gs_message = " + XMLConverter.getPrettyString(gs_message_elem));
111 System.err.println("**** Greenstone site image filename = " + site_image_filename);
112
113 final Identifier identifier_image = new Identifier(site_image_filename);
114
115 //final Source source = new SourceFactory().newSource(identifier, getDelegateProxy());
116 final Source source = new SourceFactory().newSource(identifier_image, getDelegateProxy());
117
118 System.err.println("***** identifier_image = " + identifier_image);
119 System.err.println("***** source path = " + ((edu.illinois.library.cantaloupe.source.FileSource)source).getPath());
120 */
121
122 // If we are resolving first, or if the source image is not present in
123 // the source cache (if enabled), check access to it in preparation for
124 // retrieval.
125 final Path sourceImage = cacheFacade.getSourceCacheFile(identifier);
126 if (sourceImage == null || isResolvingFirst()) {
127 try {
128 source.checkAccess();
129 } catch (NoSuchFileException e) { // this needs to be rethrown!
130 if (config.getBoolean(Key.CACHE_SERVER_PURGE_MISSING, false)) {
131 // If the image was not found, purge it from the cache.
132 cacheFacade.purgeAsync(identifier);
133 }
134 throw e;
135 }
136 }
137
138 // Get the format of the source image.
139 // If we are not resolving first, and there is a hit in the source
140 // cache, read the format from the source-cached-file, as we will
141 // expect source cache access to be more efficient.
142 // Otherwise, read it from the source.
143 Format format = Format.UNKNOWN;
144 if (!isResolvingFirst() && sourceImage != null) {
145 List<edu.illinois.library.cantaloupe.image.MediaType> mediaTypes =
146 edu.illinois.library.cantaloupe.image.MediaType.detectMediaTypes(sourceImage);
147 if (!mediaTypes.isEmpty()) {
148 format = mediaTypes.get(0).toFormat();
149 }
150 } else {
151 format = source.getFormat();
152 }
153
154 // Obtain an instance of the processor assigned to that format.
155 try (Processor processor = new ProcessorFactory().newProcessor(format)) {
156 // Connect it to the source.
157 tempFileFuture = new ProcessorConnector().connect(
158 source, processor, identifier, format);
159
160 final Info info = getOrReadInfo(identifier, processor);
161
162 commitCustomResponseHeaders();
163
164 return newRepresentation(info, processor);
165 }
166 }
167
168 /**
169 * @return Full image URI corresponding to the given identifier, respecting
170 * the {@literal X-Forwarded-*} and
171 * {@link #PUBLIC_IDENTIFIER_HEADER} reverse proxy headers.
172 */
173 private String getImageURI() {
174 return getPublicRootReference() + RestletApplication.IIIF_2_PATH + "/" +
175 getPublicIdentifier();
176 }
177
178 private MediaType getNegotiatedMediaType() {
179 MediaType mediaType;
180 // If the client has requested JSON-LD, set the content type to
181 // that; otherwise set it to JSON.
182 List<Preference<MediaType>> preferences = getRequest().getClientInfo().
183 getAcceptedMediaTypes();
184 if (preferences.get(0) != null && preferences.get(0).toString().
185 startsWith("application/ld+json")) {
186 mediaType = new MediaType("application/ld+json");
187 } else {
188 mediaType = new MediaType("application/json");
189 }
190 return mediaType;
191 }
192
193 private Representation newRepresentation(Info info,
194 Processor processor) {
195 final ImageInfoFactory factory = new ImageInfoFactory(
196 processor.getSupportedFeatures(),
197 processor.getSupportedIIIF2Qualities(),
198 processor.getAvailableOutputFormats());
199 factory.setDelegateProxy(getDelegateProxy());
200
201 final ImageInfo<String, Object> imageInfo = factory.newImageInfo(
202 getImageURI(), info, getPageIndex());
203 final MediaType mediaType = getNegotiatedMediaType();
204
205 return new JSONRepresentation(imageInfo, mediaType, () -> {
206 if (tempFileFuture != null) {
207 Path tempFile = tempFileFuture.get();
208 if (tempFile != null) {
209 Files.deleteIfExists(tempFile);
210 }
211 }
212 return null;
213 });
214 }
215
216 private boolean isResolvingFirst() {
217 return Configuration.getInstance().
218 getBoolean(Key.CACHE_SERVER_RESOLVE_FIRST, true);
219 }
220
221}
Note: See TracBrowser for help on using the repository browser.