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.services;
20  
21  import jakarta.persistence.EntityManager;
22  import jakarta.persistence.EntityTransaction;
23  import org.apache.logging.log4j.LogManager;
24  import org.apache.logging.log4j.Logger;
25  import org.mycore.backend.jpa.MCREntityManagerProvider;
26  import org.mycore.common.MCRSession;
27  import org.mycore.common.MCRSessionMgr;
28  import org.mycore.common.MCRSystemUserInformation;
29  import org.mycore.datamodel.niofs.MCRPath;
30  import org.mycore.imagetiler.MCRImage;
31  import org.mycore.imagetiler.MCRTileEventHandler;
32  import org.mycore.imagetiler.MCRTiledPictureProps;
33  
34  import java.io.IOException;
35  import java.nio.file.Files;
36  import java.nio.file.Path;
37  import java.util.Date;
38  import java.util.concurrent.atomic.AtomicReference;
39  
40  /**
41   * A slave thread of {@link MCRImageTiler}
42   *
43   * This class can be extended. Any extending class should provide and implementation for {@link #getMCRImage()}.
44   * To get the extending class invoked, one need to define a MyCoRe property, which defaults to:
45   * <code>MCR.Module-iview2.MCRTilingActionImpl=org.mycore.iview2.services.MCRTilingAction</code>
46   * @author Thomas Scheffler (yagee)
47   *
48   */
49  public class MCRTilingAction implements Runnable {
50      private static final Logger LOGGER = LogManager.getLogger(MCRTilingAction.class);
51  
52      protected MCRTileJob tileJob = null;
53  
54      public MCRTilingAction(MCRTileJob image) {
55          this.tileJob = image;
56      }
57  
58      /**
59       * takes a {@link MCRTileJob} and tiles the referenced {@link MCRImage} instance.
60       *
61       * Also this updates tileJob properties of {@link MCRTileJob} in the database.
62       */
63      public void run() {
64          tileJob.setStart(new Date());
65          MCRImage image;
66          Path tileDir = MCRIView2Tools.getTileDir();
67          try {
68              image = getMCRImage();
69              image.setTileDir(tileDir);
70          } catch (IOException e) {
71              LOGGER.error("Error while retrieving image for job: {}", tileJob, e);
72              return;
73          }
74          MCRSessionMgr.unlock();
75          MCRSession mcrSession = MCRSessionMgr.getCurrentSession();
76          mcrSession.setUserInformation(MCRSystemUserInformation.getSystemUserInstance());
77          AtomicReference<EntityTransaction> imageReaderTransactionReference = new AtomicReference<>();
78          EntityTransaction mergeTransaction = null;
79  
80          try (EntityManager em = MCREntityManagerProvider.getCurrentEntityManager()) {
81              MCRTileEventHandler tileEventHandler = new MCRTileEventHandler() {
82  
83                  @Override
84                  public void preImageReaderCreated() {
85                      imageReaderTransactionReference.set(em.getTransaction());
86                      imageReaderTransactionReference.get().begin();
87                  }
88  
89                  @Override
90                  public void postImageReaderCreated() {
91                      em.clear(); //beside tileJob, no write access so far
92                      if (imageReaderTransactionReference.get().isActive()) {
93                          imageReaderTransactionReference.get().commit();
94                      }
95                  }
96  
97              };
98              try {
99                  MCRTiledPictureProps picProps = image.tile(tileEventHandler);
100                 tileJob.setFinished(new Date());
101                 tileJob.setStatus(MCRJobState.FINISHED);
102                 tileJob.setHeight(picProps.getHeight());
103                 tileJob.setWidth(picProps.getWidth());
104                 tileJob.setTiles(picProps.getTilesCount());
105                 tileJob.setZoomLevel(picProps.getZoomlevel());
106             } catch (IOException e) {
107                 LOGGER.error("IOException occured while tiling a queued picture", e);
108                 throw e;
109             }
110             mergeTransaction = em.getTransaction();
111             mergeTransaction.begin();
112             em.merge(tileJob);
113             mergeTransaction.commit();
114         } catch (Exception e) {
115             LOGGER.error("Error while getting next tiling job.", e);
116             EntityTransaction imageReaderTransaction = imageReaderTransactionReference.get();
117             if (imageReaderTransaction != null && imageReaderTransaction.isActive()) {
118                 imageReaderTransaction.rollback();
119             }
120             if (mergeTransaction != null && mergeTransaction.isActive()) {
121                 mergeTransaction.rollback();
122             }
123             try {
124                 Files.deleteIfExists(MCRImage.getTiledFile(tileDir, tileJob.getDerivate(), tileJob.getPath()));
125             } catch (IOException e1) {
126                 LOGGER.error("Could not delete tile file after error!", e);
127             }
128 
129         } finally {
130             MCRSessionMgr.releaseCurrentSession();
131             mcrSession.close();
132         }
133     }
134 
135     /**
136      * @return MCRImage instance based on the information provided by {@link #tileJob}
137      * @throws IOException thrown by {@link MCRImage#getInstance(Path, String, String)}
138      */
139     protected MCRImage getMCRImage() throws IOException {
140         MCRPath file = MCRPath.getPath(tileJob.getDerivate(), tileJob.getPath());
141         return MCRImage.getInstance(file, file.getOwner(), file.getOwnerRelativePath());
142     }
143 
144     @Override
145     public String toString() {
146         if (tileJob == null) {
147             return "unassigned tiling action";
148         }
149         return tileJob.toString();
150     }
151 
152 }