use of org.haiku.haikudepotserver.dataobjects.PkgIconImage in project haikudepotserver by haiku.
the class PkgIconServiceImpl method storePkgIconImage.
@Override
public PkgIcon storePkgIconImage(InputStream input, MediaType mediaType, Integer expectedSize, ObjectContext context, PkgSupplement pkgSupplement) throws IOException, BadPkgIconException {
Preconditions.checkArgument(null != context, "the context is not supplied");
Preconditions.checkArgument(null != input, "the input must be provided");
Preconditions.checkArgument(null != mediaType, "the mediaType must be provided");
Preconditions.checkArgument(null != pkgSupplement, "the pkgSupplement must be provided");
byte[] imageData = ByteStreams.toByteArray(new BoundedInputStream(input, ICON_SIZE_LIMIT));
Optional<PkgIcon> pkgIconOptional;
Integer size = null;
switch(mediaType.getCode()) {
case MediaType.MEDIATYPE_PNG:
ImageHelper.Size pngSize = imageHelper.derivePngSize(imageData);
if (null == pngSize) {
LOGGER.warn("attempt to set the bitmap (png) package icon for package {}, but the size was invalid;" + "it is not a valid png image", pkgSupplement.getBasePkgName());
throw new BadPkgIconException("invalid png");
}
if (!pngSize.areSides(16) && !pngSize.areSides(32) && !pngSize.areSides(64)) {
LOGGER.warn("attempt to set the bitmap (png) package icon for package {}, but the size was invalid; " + "it must be either 32x32 or 16x16 px, but was {}", pkgSupplement.getBasePkgName(), pngSize.toString());
throw new BadPkgIconException("non-square sizing or unexpected sizing");
}
if (null != expectedSize && !pngSize.areSides(expectedSize)) {
LOGGER.warn("attempt to set the bitmap (png) package icon for package {}, but the size did not " + " match the expected size", pkgSupplement.getBasePkgName());
throw new BadPkgIconException("size of image was not as expected");
}
try {
imageData = pngOptimizationService.optimize(imageData);
} catch (IOException ioe) {
throw new RuntimeException("the png optimization process has failed; ", ioe);
}
size = pngSize.width;
pkgIconOptional = pkgSupplement.getPkgIcon(mediaType, pngSize.width);
break;
case MediaType.MEDIATYPE_HAIKUVECTORICONFILE:
if (!imageHelper.looksLikeHaikuVectorIconFormat(imageData)) {
LOGGER.warn("attempt to set the vector (hvif) package icon for package {}, but the data does not " + "look like hvif", pkgSupplement.getBasePkgName());
throw new BadPkgIconException();
}
pkgIconOptional = pkgSupplement.getPkgIcon(mediaType, null);
break;
default:
throw new IllegalStateException("unhandled media type; " + mediaType.getCode());
}
PkgIconImage pkgIconImage;
if (pkgIconOptional.isPresent()) {
pkgIconImage = pkgIconOptional.get().getPkgIconImage();
} else {
PkgIcon pkgIcon = context.newObject(PkgIcon.class);
pkgSupplement.addToManyTarget(PkgSupplement.PKG_ICONS.getName(), pkgIcon, true);
pkgIcon.setMediaType(mediaType);
pkgIcon.setSize(size);
pkgIconImage = context.newObject(PkgIconImage.class);
pkgIcon.addToManyTarget(PkgIcon.PKG_ICON_IMAGES.getName(), pkgIconImage, true);
pkgIconOptional = Optional.of(pkgIcon);
}
if (pkgIconImage.getData() == null || !Arrays.equals(pkgIconImage.getData(), imageData)) {
pkgIconImage.setData(imageData);
pkgSupplement.setModifyTimestamp();
pkgSupplement.setIconModifyTimestamp(new java.sql.Timestamp(Clock.systemUTC().millis()));
renderedPkgIconRepository.evict(context, pkgSupplement);
if (null != size) {
LOGGER.info("the icon {}px for package [{}] has been updated", size, pkgSupplement.getBasePkgName());
} else {
LOGGER.info("the icon for package [{}] has been updated", pkgSupplement.getBasePkgName());
}
} else {
LOGGER.info("no change to package icon for [{}] ", pkgSupplement.getBasePkgName());
}
return pkgIconOptional.orElseThrow(IllegalStateException::new);
}
Aggregations