View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.iview2.frontend.resources;
20  
21  import java.awt.image.BufferedImage;
22  import java.io.BufferedOutputStream;
23  import java.io.IOException;
24  import java.io.OutputStream;
25  import java.nio.file.FileVisitResult;
26  import java.nio.file.Files;
27  import java.nio.file.SimpleFileVisitor;
28  import java.nio.file.attribute.BasicFileAttributes;
29  import java.util.Objects;
30  import java.util.zip.Deflater;
31  
32  import javax.imageio.ImageIO;
33  
34  import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
35  import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
36  import org.jdom2.JDOMException;
37  import org.mycore.access.MCRAccessManager;
38  import org.mycore.common.MCRSessionMgr;
39  import org.mycore.common.MCRTransactionHelper;
40  import org.mycore.datamodel.metadata.MCRObjectID;
41  import org.mycore.datamodel.niofs.MCRPath;
42  import org.mycore.imagetiler.MCRImage;
43  import org.mycore.imagetiler.MCRTiledPictureProps;
44  import org.mycore.iview2.services.MCRIView2Tools;
45  
46  import jakarta.ws.rs.GET;
47  import jakarta.ws.rs.Path;
48  import jakarta.ws.rs.PathParam;
49  import jakarta.ws.rs.Produces;
50  import jakarta.ws.rs.QueryParam;
51  import jakarta.ws.rs.WebApplicationException;
52  import jakarta.ws.rs.core.Response;
53  import jakarta.ws.rs.core.StreamingOutput;
54  import jakarta.ws.rs.core.Response.Status;
55  
56  @Path("/iview/zip")
57  public class MCRIViewZipResource {
58  
59      /**
60       * Zips a derivate and its containing iview images as jpg's. All other files are ignored.
61       * 
62       * @param derivateID the derivate to zip
63       * @param zoom if undefined the base resolution is assumed
64       * @return zip file
65       */
66      @GET
67      @Produces("application/zip")
68      @Path("{derivateID}")
69      public Response zip(@PathParam("derivateID") String derivateID, @QueryParam("zoom") Integer zoom) throws Exception {
70          if (!MCRAccessManager.checkDerivateContentPermission(MCRObjectID.getInstance(derivateID),
71              MCRAccessManager.PERMISSION_READ)) {
72              throw new WebApplicationException(Status.UNAUTHORIZED);
73          }
74          MCRPath derivateRoot = MCRPath.getPath(derivateID, "/");
75          if (!Files.exists(derivateRoot)) {
76              throw new WebApplicationException(Status.NOT_FOUND);
77          }
78          ZipStreamingOutput stream = new ZipStreamingOutput(derivateRoot, zoom);
79          return Response.ok(stream).header("Content-Disposition", "attachnment; filename=\"" + derivateID + ".zip\"")
80              .build();
81      }
82  
83      public static class ZipStreamingOutput implements StreamingOutput {
84  
85          protected MCRPath derivateRoot;
86  
87          protected Integer zoom;
88  
89          public ZipStreamingOutput(MCRPath derivateRoot, Integer zoom) {
90              this.derivateRoot = derivateRoot;
91              this.zoom = zoom;
92          }
93  
94          @Override
95          public void write(OutputStream out) throws IOException, WebApplicationException {
96              MCRSessionMgr.getCurrentSession();
97              MCRTransactionHelper.beginTransaction();
98              try {
99                  final ZipArchiveOutputStream zipStream = new ZipArchiveOutputStream(new BufferedOutputStream(out));
100                 zipStream.setLevel(Deflater.BEST_SPEED);
101                 SimpleFileVisitor<java.nio.file.Path> zipper = new SimpleFileVisitor<>() {
102                     @Override
103                     public FileVisitResult visitFile(java.nio.file.Path file, BasicFileAttributes attrs)
104                         throws IOException {
105                         Objects.requireNonNull(file);
106                         Objects.requireNonNull(attrs);
107                         MCRPath mcrPath = MCRPath.toMCRPath(file);
108                         if (MCRIView2Tools.isFileSupported(file)) {
109                             java.nio.file.Path iviewFile = MCRImage.getTiledFile(MCRIView2Tools.getTileDir(),
110                                 mcrPath.getOwner(), mcrPath.getOwnerRelativePath());
111                             if (!Files.exists(iviewFile)) {
112                                 return super.visitFile(iviewFile, attrs);
113                             }
114                             try {
115                                 MCRTiledPictureProps imageProps = MCRTiledPictureProps.getInstanceFromFile(iviewFile);
116                                 Integer zoomLevel = (zoom == null || zoom > imageProps.getZoomlevel()) ? imageProps
117                                     .getZoomlevel() : zoom;
118                                 BufferedImage image = MCRIView2Tools.getZoomLevel(iviewFile, zoomLevel);
119                                 ZipArchiveEntry entry = new ZipArchiveEntry(file.getFileName() + ".jpg");
120                                 zipStream.putArchiveEntry(entry);
121                                 ImageIO.write(image, "jpg", zipStream);
122                             } catch (JDOMException e) {
123                                 throw new WebApplicationException(e);
124                             }
125                             zipStream.closeArchiveEntry();
126                         }
127                         return FileVisitResult.CONTINUE;
128                     }
129                 };
130                 Files.walkFileTree(derivateRoot, zipper);
131                 zipStream.close();
132             } catch (Exception exc) {
133                 throw new WebApplicationException(exc);
134             } finally {
135                 MCRSessionMgr.getCurrentSession();
136                 MCRTransactionHelper.commitTransaction();
137             }
138         }
139     }
140 
141 }