From 1bad56eafe1608ca81aa7f8000e56a5309165f89 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Wed, 30 Jun 2021 20:05:50 +0200 Subject: [PATCH] More cleanup and JavaDoc. --- .../java/org/librecms/assets/BinaryAsset.java | 18 -------- .../assets/BinaryAssetBlobDataProvider.java | 39 ++-------------- .../assets/BinaryAssetDataProvider.java | 41 ++++++++++++++--- .../assets/BinaryAssetDataService.java | 45 ++++++++++++++++-- .../assets/FileAssetEditStep.java | 46 +------------------ 5 files changed, 82 insertions(+), 107 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 0be95e6e1..03b77204d 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/BinaryAsset.java +++ b/ccm-cms/src/main/java/org/librecms/assets/BinaryAsset.java @@ -87,7 +87,6 @@ public class BinaryAsset extends Asset implements Serializable { @Lob @Basic(fetch = FetchType.LAZY) // @NotAudited -// private byte[] data; private Blob data; @Column(name = "DATA_SIZE") @@ -124,23 +123,6 @@ public class BinaryAsset extends Asset implements Serializable { this.mimeType = mimeType; } -// public byte[] getData() { -// if (data == null) { -// return new byte[]{}; -// } else { -// return Arrays.copyOf(data, data.length); -// } -// } -// -// public void setData(final byte[] data) { -// if (data == null) { -// this.data = new byte[]{}; -// size = this.data.length; -// } else { -// this.data = Arrays.copyOf(data, data.length); -// size = data.length; -// } -// } public Blob getData() { return data; } 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 1d0650fb1..189d41546 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetBlobDataProvider.java +++ b/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetBlobDataProvider.java @@ -41,11 +41,13 @@ import javax.activation.MimeTypeParseException; import javax.annotation.Resource; import javax.enterprise.context.Dependent; import javax.inject.Inject; -import javax.persistence.EntityManager; import javax.sql.DataSource; import javax.transaction.Transactional; /** + * An implementation of {@link BinaryAssetDataProvider} using the + * {@link BinaryAsset#data} field and the {@link BlobProxy} from Hibernate for + * storing and retrieving binary data. * * @author Jens Pelzetter */ @@ -62,9 +64,6 @@ public class BinaryAssetBlobDataProvider implements BinaryAssetDataProvider { @Inject private AssetRepository assetRepo; - @Inject - private EntityManager entityManager; - @Override public void copyDataToOutputStream( final BinaryAsset asset, final OutputStream outputStream @@ -99,8 +98,7 @@ public class BinaryAssetBlobDataProvider implements BinaryAssetDataProvider { final BinaryAsset asset, final InputStream inputStream, final String fileName, - final String mimeType, - final long fileSizeParam + final String mimeType ) { Objects.requireNonNull(asset, "Can't save data to null."); Objects.requireNonNull(inputStream, "Can't read data from null"); @@ -144,35 +142,6 @@ public class BinaryAssetBlobDataProvider implements BinaryAssetDataProvider { assetRepo.save(asset); } - @Transactional(Transactional.TxType.REQUIRES_NEW) - 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); - } - } - private class UploadInputStream extends InputStream { private final Path tmpFilePath; diff --git a/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetDataProvider.java b/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetDataProvider.java index 991837e67..39ac036ac 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetDataProvider.java +++ b/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetDataProvider.java @@ -22,21 +22,50 @@ import java.io.InputStream; import java.io.OutputStream; /** + * Interface for providers of the data of a {@link BinaryAsset}. The + * implementations are used by the {@link BinaryAssetDataService}. + * + * Implementations MUST NOT copy all binary data to the working memory. Instead + * a streaming approch MUST be used to avoid out-of-memory problems with large + * files. * * @author Jens Pelzetter */ public interface BinaryAssetDataProvider { - + + /** + * Copy the data of the {@link BinaryAsset} to the provided + * {@link OutputStream}. + * + * @param asset The asset providing the data. + * @param outputStream The output stream to use. + */ void copyDataToOutputStream( BinaryAsset asset, OutputStream outputStream ); - + + /** + * Saves binary data for the provided {@link BinaryAsset}. Implementations + * must store the provided binary data and set the following fields: + * + * + * The {@code size} has the be determined by the implementation of this + * method. + * + * @param asset The asset that will hold the data. + * @param stream The {@link InputStream} providing the data. + * @param fileName The file name of the data. + * @param contentType The content type of the data. + */ void saveData( - BinaryAsset asset, + BinaryAsset asset, InputStream stream, String fileName, - String contentType, - long fileSize + String contentType ); - + } diff --git a/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetDataService.java b/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetDataService.java index 79b4ea501..a4548d37c 100644 --- a/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetDataService.java +++ b/ccm-cms/src/main/java/org/librecms/assets/BinaryAssetDataService.java @@ -31,19 +31,41 @@ import javax.enterprise.inject.Instance; import javax.inject.Inject; /** + * A service class for working with the binary data of a {@link BinaryAsset}. + * + * This class acts as a frontend to the implementations of + * {@link BinaryAssetDataProvider}. The implementation to use is configured by + * {@link BinaryAssetConfig#binaryAssetDataProvider}. * * @author Jens Pelzetter */ @RequestScoped public class BinaryAssetDataService { + /** + * Used to retrrieve the {@link BinaryAssetConfig}. + */ @Inject private ConfigurationManager confManager; + /** + * The available implementations of {@link BinaryAssetDataProvider}. + */ @Inject @Any private Instance dataProvider; + /** + * Copy the data of the {@link BinaryAsset} to the provided + * {@link OutputStream}. + * + * @param asset The asset providing the data. + * @param outputStream The output stream to use. + * + * @see + * BinaryAssetDataProvider#copyDataToOutputStream(org.librecms.assets.BinaryAsset, + * java.io.OutputStream) + */ public void copyDataToOutputStream( final BinaryAsset asset, final OutputStream outputStream @@ -53,19 +75,36 @@ public class BinaryAssetDataService { getDataProvider().copyDataToOutputStream(asset, outputStream); } + /** + * + * Saves binary data for the provided {@link BinaryAsset}. + * + * @param asset The asset that will hold the data. + * @param stream The {@link InputStream} providing the data. + * @param fileName The file name of the data. + * @param contentType The content type of the data. + * + * @see BinaryAssetDataProvider#saveData(org.librecms.assets.BinaryAsset, + * java.io.InputStream, java.lang.String, java.lang.String) + */ public void saveData( final BinaryAsset asset, final InputStream stream, final String fileName, - final String mimeType, - final long fileSize + final String mimeType ) { Objects.requireNonNull(asset, "Can't save data to null."); final BinaryAssetDataProvider dataProvider = getDataProvider(); - dataProvider.saveData(asset, stream, fileName, mimeType, fileSize); + dataProvider.saveData(asset, stream, fileName, mimeType); } + /** + * Helper method for obtaining the implementation of + * {@link BinaryAssetDataProvider} to use. + * + * @return The implementation of {@link BinaryAssetDataProvider} to use. + */ @SuppressWarnings("unchecked") private BinaryAssetDataProvider getDataProvider() { final BinaryAssetConfig config = confManager.findConfiguration( 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 b85fe77bc..fa80ec05b 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 @@ -348,7 +348,6 @@ public class FileAssetEditStep extends AbstractMvcAssetEditStep { String fileName = ""; String contentType = ""; - long fileSize = 0; for (final InputPart inputPart : inputParts) { try { final MultivaluedMap headers = inputPart @@ -361,51 +360,8 @@ public class FileAssetEditStep extends AbstractMvcAssetEditStep { fileAsset, inputPart.getBody(InputStream.class, null), fileName, - contentType, - fileSize + contentType ); -// -// 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 -// ); -// 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