From f022a9540de6fa5b71462a8ee7959a522ab2fc16 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Tue, 29 Jun 2021 20:39:57 +0200 Subject: [PATCH] Moved logic for saving asset data to separate class. --- .../java/org/librecms/assets/BinaryAsset.java | 2 +- .../assets/BinaryAssetBlobDataProvider.java | 139 +++++++++++++++--- .../assets/FileAssetEditStep.java | 103 ++++++------- .../assets/FileAssetEditStepDownload.java | 9 -- 4 files changed, 164 insertions(+), 89 deletions(-) diff --git a/ccm-cms/src/main/java/org/librecms/assets/BinaryAsset.java b/ccm-cms/src/main/java/org/librecms/assets/BinaryAsset.java index 1c318f58b..677160d31 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/BinaryAsset.java +++ b/ccm-cms/src/main/java/org/librecms/assets/BinaryAsset.java @@ -21,7 +21,6 @@ package org.librecms.assets; import org.librecms.contentsection.Asset; import java.io.Serializable; -import java.util.Arrays; import java.util.Objects; import javax.activation.MimeType; @@ -48,6 +47,7 @@ import java.sql.SQLException; import javax.persistence.Basic; import javax.persistence.Convert; import javax.persistence.FetchType; +import javax.transaction.Transactional; import static org.librecms.CmsConstants.*; diff --git a/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetBlobDataProvider.java b/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetBlobDataProvider.java index 851ee9390..e9a73aeb5 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetBlobDataProvider.java +++ b/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetBlobDataProvider.java @@ -18,11 +18,17 @@ */ package org.librecms.assets; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.hibernate.engine.jdbc.BlobProxy; import org.libreccm.core.UnexpectedErrorException; +import org.librecms.contentsection.AssetRepository; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.sql.Blob; import java.sql.Connection; import java.sql.PreparedStatement; @@ -30,9 +36,12 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Objects; +import javax.activation.MimeType; +import javax.activation.MimeTypeParseException; import javax.annotation.Resource; -import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.Dependent; +import javax.inject.Inject; +import javax.persistence.EntityManager; import javax.sql.DataSource; import javax.transaction.Transactional; @@ -43,15 +52,24 @@ import javax.transaction.Transactional; @Dependent public class BinaryAssetBlobDataProvider implements BinaryAssetDataProvider { + private static final Logger LOGGER = LogManager.getLogger( + BinaryAssetBlobDataProvider.class + ); + @Resource(lookup = "java:/comp/env/jdbc/libreccm/db") private DataSource dataSource; + @Inject + private AssetRepository assetRepo; + + @Inject + private EntityManager entityManager; + @Override public void copyDataToOutputStream( final BinaryAsset asset, final OutputStream outputStream ) { - Objects.requireNonNull(asset, "Can't retrieve data from null."); - try ( Connection connection = dataSource.getConnection()) { + try ( Connection connection = dataSource.getConnection()) { connection.setAutoCommit(false); final PreparedStatement stmt = connection .prepareStatement( @@ -62,43 +80,116 @@ public class BinaryAssetBlobDataProvider implements BinaryAssetDataProvider { try ( ResultSet resultSet = stmt.executeQuery()) { resultSet.next(); final Blob blob = resultSet.getBlob("asset_data"); - blob.getBinaryStream().transferTo(outputStream); -// try ( InputStream inputStream = blob.getBinaryStream()) { -// byte[] buffer = new byte[8192]; -// int length; -// while ((length = inputStream.read(buffer)) != -1) { -// outputStream.write(buffer, 0, length); -// } -// } +// blob.getBinaryStream().transferTo(outputStream); + try ( InputStream inputStream = blob.getBinaryStream()) { + byte[] buffer = new byte[8192]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, length); + } + } } } catch (SQLException | IOException ex) { throw new UnexpectedErrorException(ex); } } + @Transactional(Transactional.TxType.REQUIRED) @Override public void saveData( final BinaryAsset asset, - final InputStream stream, + final InputStream inputStream, final String fileName, final String mimeType, - final long fileSize + final long fileSizeParam ) { Objects.requireNonNull(asset, "Can't save data to null."); - try ( Connection connection = dataSource.getConnection()) { - final PreparedStatement stmt = connection - .prepareStatement( - "UPDATE ccm_cms.binary_assets SET asset_data = ?, filename = ?, mime_type = ?, data_size = ? WHERE object_id = ?" + Objects.requireNonNull(inputStream, "Can't read data from null"); + Objects.requireNonNull(fileName); + Objects.requireNonNull(mimeType); + + try { + final Path tmpFilePath = Files.createTempFile("upload", fileName); + int fileSize = 0; + try ( OutputStream outputStream = Files.newOutputStream(tmpFilePath)) { + int length; + byte[] buffer = new byte[8192]; + while ((length = inputStream.read(buffer)) != -1) { + outputStream.write(buffer); + fileSize += length; + } + outputStream.flush(); + } + + final Blob data = BlobProxy.generateProxy( + Files.newInputStream(tmpFilePath), -1 + ); + asset.setFileName(fileName); + asset.setData(data); + asset.setSize(fileSize); + try { + asset.setMimeType(new MimeType(mimeType)); + } catch (MimeTypeParseException ex) { + LOGGER.error( + "Failed to upload file for FileAsset {}:", + asset.getUuid() ); - stmt.setBlob(1, stream); - stmt.setString(2, fileName); - stmt.setString(3, mimeType); - stmt.setLong(4, fileSize); - stmt.setLong(5, asset.getObjectId()); + LOGGER.error(ex); - stmt.execute(); + throw new UnexpectedErrorException(ex); + } + } catch (IOException ex) { + throw new UnexpectedErrorException(ex); + } - } catch (SQLException ex) { + assetRepo.save(asset); + entityManager.flush(); + + updateAudTable(asset.getObjectId()); + +// try ( Connection connection = dataSource.getConnection()) { +// final PreparedStatement stmt = connection +// .prepareStatement( +// "UPDATE ccm_cms.binary_assets SET asset_data = ?, filename = ?, mime_type = ?, data_size = ? WHERE object_id = ?" +// ); +// stmt.setBlob(1, stream); +// stmt.setString(2, fileName); +// stmt.setString(3, mimeType); +// stmt.setLong(4, fileSize); +// stmt.setLong(5, asset.getObjectId()); +// +// stmt.execute(); +// +// } catch (SQLException ex) { +// throw new UnexpectedErrorException(ex); +// } + } + + @Transactional(Transactional.TxType.REQUIRED) + private void updateAudTable(final long assetId) { + try (Connection connection = dataSource.getConnection()) { + final PreparedStatement findRevStmt = connection + .prepareStatement( + "SELECT rev FROM ccm_cms.binary_assets_aud WHERE object_id = ? ORDER BY rev DESC LIMIT 1" + ); + findRevStmt.setLong(1, assetId); + + final long rev; + try(ResultSet resultSet = findRevStmt.executeQuery()) { + resultSet.next(); + rev = resultSet.getLong("rev"); + } + + final PreparedStatement updateDataStmt = connection + .prepareStatement( + "UPDATE ccm_cms.binary_assets_aud SET asset_data = (SELECT asset_data FROM ccm_cms.binary_assets WHERE object_id = ?) WHERE object_id = ? AND rev = ?" + ); + updateDataStmt.setLong(1, assetId); + updateDataStmt.setLong(2, assetId); + updateDataStmt.setLong(3, rev); + + updateDataStmt.execute(); + } catch(SQLException ex) { throw new UnexpectedErrorException(ex); } } diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStep.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStep.java index 7a4bab691..b85fe77bc 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStep.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStep.java @@ -32,8 +32,6 @@ import org.librecms.contentsection.AssetRepository; import org.librecms.ui.contentsections.AssetPermissionsChecker; import org.librecms.ui.contentsections.ContentSectionNotFoundException; -import java.io.BufferedInputStream; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -355,65 +353,60 @@ public class FileAssetEditStep extends AbstractMvcAssetEditStep { try { final MultivaluedMap headers = inputPart .getHeaders(); + fileName = getFileName(headers); contentType = getContentType(headers); -// fileSize = getFileSize(headers); - final java.nio.file.Path tmpFilePath = Files - .createTempFile( - "upload", fileName - ); - try ( InputStream inputStream = inputPart.getBody( - InputStream.class, null - )) { - try ( OutputStream outputStream = Files.newOutputStream( - tmpFilePath - )) { - int length; - byte[] buffer = new byte[8192]; - while ((length = inputStream.read(buffer)) != -1) { - outputStream.write(buffer); - fileSize += length; - } - outputStream.flush(); - } - } - - final Blob data = BlobProxy.generateProxy( - Files.newInputStream(tmpFilePath), -1 + dataService.saveData( + fileAsset, + inputPart.getBody(InputStream.class, null), + fileName, + contentType, + fileSize ); - fileAsset.setFileName(fileName); - fileAsset.setData(data); - - fileAsset.setSize(fileSize); -// fileAsset.setSize(fileAsset.getData().length); - try { - fileAsset.setMimeType(new MimeType(contentType)); - } catch (MimeTypeParseException ex) { - LOGGER.error( - "Failed to upload file for FileAsset {}:", - assetPath - ); - LOGGER.error(ex); - - models.put("uploadFailed", true); - return buildRedirectPathForStep(); - } - - assetRepo.save(fileAsset); -// } -// try ( InputStream inputStream = inputPart.getBody( -// InputStream.class, null)) { -// dataService.saveData( -// fileAsset, -// inputStream, -// fileName, -// contentType, -// fileSize +// +// final java.nio.file.Path tmpFilePath = Files +// .createTempFile( +// "upload", fileName // ); +// try ( InputStream inputStream = inputPart.getBody( +// InputStream.class, null +// )) { +// try ( OutputStream outputStream = Files.newOutputStream( +// tmpFilePath +// )) { +// int length; +// byte[] buffer = new byte[8192]; +// while ((length = inputStream.read(buffer)) != -1) { +// outputStream.write(buffer); +// fileSize += length; +// } +// outputStream.flush(); +// } // } - - } catch (IOException ex) { +// +// final Blob data = BlobProxy.generateProxy( +// Files.newInputStream(tmpFilePath), -1 +// ); +// fileAsset.setFileName(fileName); +// fileAsset.setData(data); +// +// fileAsset.setSize(fileSize); +// try { +// fileAsset.setMimeType(new MimeType(contentType)); +// } catch (MimeTypeParseException ex) { +// LOGGER.error( +// "Failed to upload file for FileAsset {}:", +// assetPath +// ); +// LOGGER.error(ex); +// +// models.put("uploadFailed", true); +// return buildRedirectPathForStep(); +// } +// +// assetRepo.save(fileAsset); + } catch (IOException | UnexpectedErrorException ex) { LOGGER.error( "Failed to upload file for FileAsset {}:", assetPath ); diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStepDownload.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStepDownload.java index 1945908bc..ee4e99d51 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStepDownload.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/assets/FileAssetEditStepDownload.java @@ -24,20 +24,13 @@ import org.librecms.assets.FileAsset; import org.librecms.contentsection.Asset; import org.librecms.contentsection.AssetRepository; import org.librecms.contentsection.ContentSection; -import org.librecms.ui.contentsections.ContentSectionNotFoundException; import org.librecms.ui.contentsections.ContentSectionsUi; -import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.OutputStreamWriter; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; -import javax.mail.internet.ContentDisposition; import javax.transaction.Transactional; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -67,14 +60,12 @@ public class FileAssetEditStepDownload { @GET @Path("/") @AuthorizationRequired - @Transactional(Transactional.TxType.REQUIRED) public Response downloadFile( @PathParam(MvcAssetEditSteps.SECTION_IDENTIFIER_PATH_PARAM) final String sectionIdentifier, @PathParam(MvcAssetEditSteps.ASSET_PATH_PATH_PARAM_NAME) final String assetPath ) { - final ContentSection contentSection = sectionsUi .findContentSection(sectionIdentifier) .orElseThrow(