Improvements for handling binary assets

pull/10/head
Jens Pelzetter 2021-06-24 21:12:01 +02:00
parent de65988459
commit 65425ee88f
5 changed files with 86 additions and 34 deletions

View File

@ -38,7 +38,9 @@ import org.hibernate.envers.Audited;
import org.libreccm.jpa.utils.MimeTypeConverter; import org.libreccm.jpa.utils.MimeTypeConverter;
import org.libreccm.l10n.LocalizedString; import org.libreccm.l10n.LocalizedString;
import javax.persistence.Basic;
import javax.persistence.Convert; import javax.persistence.Convert;
import javax.persistence.FetchType;
import static org.librecms.CmsConstants.*; import static org.librecms.CmsConstants.*;
@ -76,6 +78,7 @@ public class BinaryAsset extends Asset implements Serializable {
@Column(name = "ASSET_DATA") @Column(name = "ASSET_DATA")
@Lob @Lob
@Basic(fetch = FetchType.LAZY)
private byte[] data; private byte[] data;
@Column(name = "DATA_SIZE") @Column(name = "DATA_SIZE")

View File

@ -34,6 +34,7 @@ import javax.annotation.Resource;
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.Dependent; import javax.enterprise.context.Dependent;
import javax.sql.DataSource; import javax.sql.DataSource;
import javax.transaction.Transactional;
/** /**
* *
@ -58,33 +59,45 @@ public class BinaryAssetBlobDataProvider implements BinaryAssetDataProvider {
); );
stmt.setLong(1, asset.getObjectId()); stmt.setLong(1, asset.getObjectId());
try (ResultSet resultSet = stmt.executeQuery()) { try ( ResultSet resultSet = stmt.executeQuery()) {
resultSet.next(); resultSet.next();
final Blob blob = resultSet.getBlob("asset_data"); final Blob blob = resultSet.getBlob("asset_data");
try(InputStream inputStream = blob.getBinaryStream()) { blob.getBinaryStream().transferTo(outputStream);
byte[] buffer = new byte[8192]; // try ( InputStream inputStream = blob.getBinaryStream()) {
int length; // byte[] buffer = new byte[8192];
while((length = inputStream.read(buffer)) != -1) { // int length;
outputStream.write(buffer, 0, length); // while ((length = inputStream.read(buffer)) != -1) {
// outputStream.write(buffer, 0, length);
// }
// }
} }
} } catch (SQLException | IOException ex) {
}
} catch (SQLException |IOException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }
} }
@Override @Override
public void saveData(final BinaryAsset asset, final InputStream stream) { public void saveData(
final BinaryAsset asset,
final InputStream stream,
final String fileName,
final String mimeType,
final long fileSize
) {
Objects.requireNonNull(asset, "Can't save data to null."); Objects.requireNonNull(asset, "Can't save data to null.");
try ( Connection connection = dataSource.getConnection()) { try ( Connection connection = dataSource.getConnection()) {
final PreparedStatement stmt = connection final PreparedStatement stmt = connection
.prepareStatement( .prepareStatement(
"UPDATE ccm_cms.binary_assets SET asset_data = ? WHERE object_id = ?" "UPDATE ccm_cms.binary_assets SET asset_data = ?, filename = ?, mime_type = ?, data_size = ? WHERE object_id = ?"
); );
stmt.setBlob(1, stream); stmt.setBlob(1, stream);
stmt.setLong(2, asset.getObjectId()); stmt.setString(2, fileName);
// connection.commit(); stmt.setString(3, mimeType);
stmt.setLong(4, fileSize);
stmt.setLong(5, asset.getObjectId());
stmt.execute();
} catch (SQLException ex) { } catch (SQLException ex) {
throw new UnexpectedErrorException(ex); throw new UnexpectedErrorException(ex);
} }

View File

@ -31,6 +31,12 @@ public interface BinaryAssetDataProvider {
BinaryAsset asset, OutputStream outputStream BinaryAsset asset, OutputStream outputStream
); );
void saveData(BinaryAsset asset, InputStream stream); void saveData(
BinaryAsset asset,
InputStream stream,
String fileName,
String contentType,
long fileSize
);
} }

View File

@ -45,18 +45,25 @@ public class BinaryAssetDataService {
private Instance<BinaryAssetDataProvider> dataProvider; private Instance<BinaryAssetDataProvider> dataProvider;
public void copyDataToOutputStream( public void copyDataToOutputStream(
final BinaryAsset asset, final OutputStream outputStream final BinaryAsset asset,
final OutputStream outputStream
) { ) {
Objects.requireNonNull(asset, "Can't retrieve data from null."); Objects.requireNonNull(asset, "Can't retrieve data from null.");
Objects.requireNonNull(outputStream, "Can't copy data to null."); Objects.requireNonNull(outputStream, "Can't copy data to null.");
getDataProvider().copyDataToOutputStream(asset, outputStream); getDataProvider().copyDataToOutputStream(asset, outputStream);
} }
public void saveData(final BinaryAsset asset, final InputStream stream) { public void saveData(
final BinaryAsset asset,
final InputStream stream,
final String fileName,
final String mimeType,
final long fileSize
) {
Objects.requireNonNull(asset, "Can't save data to null."); Objects.requireNonNull(asset, "Can't save data to null.");
final BinaryAssetDataProvider dataProvider = getDataProvider(); final BinaryAssetDataProvider dataProvider = getDataProvider();
dataProvider.saveData(asset, stream); dataProvider.saveData(asset, stream, fileName, mimeType, fileSize);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

View File

@ -22,6 +22,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.jboss.resteasy.plugins.providers.multipart.InputPart; import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.AuthorizationRequired;
import org.librecms.assets.BinaryAssetDataService; import org.librecms.assets.BinaryAssetDataService;
@ -345,33 +346,41 @@ public class FileAssetEditStep extends AbstractMvcAssetEditStep {
String fileName = ""; String fileName = "";
String contentType = ""; String contentType = "";
long fileSize = 0;
for (final InputPart inputPart : inputParts) { for (final InputPart inputPart : inputParts) {
try { try {
final MultivaluedMap<String, String> headers = inputPart final MultivaluedMap<String, String> headers = inputPart
.getHeaders(); .getHeaders();
fileName = getFileName(headers); fileName = getFileName(headers);
contentType = getContentType(headers); contentType = getContentType(headers);
fileSize = getFileSize(headers);
fileAsset.setFileName(fileName); // fileAsset.setFileName(fileName);
fileAsset.setSize(fileAsset.getData().length); // //fileAsset.setSize(fileAsset.getData().length);
try { // try {
fileAsset.setMimeType(new MimeType(contentType)); // fileAsset.setMimeType(new MimeType(contentType));
} catch (MimeTypeParseException ex) { // } catch (MimeTypeParseException ex) {
LOGGER.error( // LOGGER.error(
"Failed to upload file for FileAsset {}:", assetPath // "Failed to upload file for FileAsset {}:", assetPath
); // );
LOGGER.error(ex); // LOGGER.error(ex);
//
models.put("uploadFailed", true); // models.put("uploadFailed", true);
return buildRedirectPathForStep(); // return buildRedirectPathForStep();
} // }
//
assetRepo.save(fileAsset); // assetRepo.save(fileAsset);
try ( InputStream inputStream = inputPart.getBody( try ( InputStream inputStream = inputPart.getBody(
InputStream.class, null)) { InputStream.class, null)) {
dataService.saveData(fileAsset, inputStream); dataService.saveData(
fileAsset,
inputStream,
fileName,
contentType,
fileSize
);
} }
} catch (IOException ex) { } catch (IOException ex) {
LOGGER.error( LOGGER.error(
"Failed to upload file for FileAsset {}:", assetPath "Failed to upload file for FileAsset {}:", assetPath
@ -414,4 +423,18 @@ public class FileAssetEditStep extends AbstractMvcAssetEditStep {
return headers.getFirst("Content-Type"); return headers.getFirst("Content-Type");
} }
private long getFileSize(final MultivaluedMap<String, String> headers) {
if (headers.containsKey("Content-Length")) {
try {
return Long.parseLong(
headers.getFirst("Content-Length")
);
} catch (NumberFormatException ex) {
throw new UnexpectedErrorException(ex);
}
} else {
return 0;
}
}
} }