package com.xenoage.zong.webserver.actions; import static com.xenoage.zong.webserver.util.Database.stmt; import static com.xenoage.zong.webserver.util.Database.unixTime; import java.io.IOException; import java.sql.Blob; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.http.HttpServletResponse; import com.xenoage.utils.math.geom.Size2f; import com.xenoage.zong.webserver.Webserver; import com.xenoage.zong.webserver.model.ScaledPage; import com.xenoage.zong.webserver.model.requests.PageRequest; import com.xenoage.zong.webserver.model.requests.Request; /** * Responds with the tile image for the given document and page index. * * @author Andreas Wenger */ public class PageAction extends RetryAction { @Override public boolean performTry(Request request, Webserver server, HttpServletResponse response) throws SQLException, IOException { PageRequest pageRequest = getAs(PageRequest.class, request); Connection db = server.getDBConnection(); //get ID and number of pages of document PreparedStatement stmtID = stmt(db, "SELECT id, pages FROM docs WHERE public_id = ?", pageRequest.id); ResultSet resID = stmtID.executeQuery(); if (!resID.next()) { stmtID.close(); return false; } int docID = resID.getInt(1); int pages = resID.getInt(2); stmtID.close(); //unknown page? if (pageRequest.page < 0 || pageRequest.page >= pages) { throw new IOException("unknown page"); } //load size of first page //if it does not exist (yet), wait a little bit and try again PreparedStatement stmtFirstPageSize = stmt(db, "SELECT width, height FROM pageinfos WHERE doc_id = ? AND page = 0", docID); ResultSet resFirstPageSize = stmtFirstPageSize.executeQuery(); if (!resFirstPageSize.next()) { stmtFirstPageSize.close(); return false; } Size2f firstPageSize = new Size2f(resFirstPageSize.getFloat(1), resFirstPageSize.getFloat(2)); stmtFirstPageSize.close(); //unknown scaling? int scaling = pageRequest.scaling.convertTo10000(firstPageSize); boolean scalingExists = (ScaledPage.fromDB(db, docID, 0, scaling) != null); if (!scalingExists) { throw new IOException("unknown scaling"); } //deliver page image PreparedStatement stmtImage = stmt(db, "SELECT image FROM pages WHERE doc_id = ?" + " AND page = ? AND scaling = ?", docID, pageRequest.page, scaling); ResultSet resImage = stmtImage.executeQuery(); if (!resImage.next()) { stmtImage.close(); return false; } Blob blob = resImage.getBlob(1); byte[] imageData = blob.getBytes(1, (int) blob.length()); stmtImage.close(); response.setHeader("Content-Type", "image/png"); response.getOutputStream().write(imageData); //update access time PreparedStatement stmtTime = stmt(db, "UPDATE docs SET last_access = ? WHERE id = ?", unixTime(), docID); stmtTime.executeUpdate(); stmtTime.close(); return true; } }