use of org.haiku.haikudepotserver.dataobjects.PkgIcon in project haikudepotserver by haiku.
the class PkgIconController method handleHeadOrGetPkgIcon.
private void handleHeadOrGetPkgIcon(RequestMethod requestMethod, HttpServletResponse response, Integer size, String format, String pkgName, Boolean fallback) throws IOException {
if (null == format) {
throw new MissingOrBadFormat();
}
if (Strings.isNullOrEmpty(pkgName) || !Pkg.PATTERN_NAME.matcher(pkgName).matches()) {
throw new MissingPkgName();
}
ObjectContext context = serverRuntime.newContext();
// cached
Optional<Pkg> pkg = Pkg.tryGetByName(context, pkgName);
if (!pkg.isPresent()) {
LOGGER.debug("request for icon for package '{}', but no such package was able to be found", pkgName);
throw new PkgNotFound();
}
PkgSupplement pkgSupplement = pkg.get().getPkgSupplement();
switch(format) {
case org.haiku.haikudepotserver.dataobjects.MediaType.EXTENSION_HAIKUVECTORICONFILE:
Optional<PkgIcon> hvifPkgIcon = pkg.get().getPkgSupplement().getPkgIcon(org.haiku.haikudepotserver.dataobjects.MediaType.getByExtension(context, format).get(), null);
if (hvifPkgIcon.isPresent()) {
byte[] data = hvifPkgIcon.get().getPkgIconImage().getData();
response.setContentType(org.haiku.haikudepotserver.dataobjects.MediaType.MEDIATYPE_HAIKUVECTORICONFILE);
outputToResponse(response, pkgSupplement, data, requestMethod == RequestMethod.GET);
} else {
throw new PkgIconNotFound();
}
break;
case org.haiku.haikudepotserver.dataobjects.MediaType.EXTENSION_PNG:
if (null == size) {
throw new IllegalArgumentException("the size must be provided when requesting a PNG");
}
size = normalizeSize(size);
Optional<byte[]> pngImageData = renderedPkgIconRepository.render(size, context, pkg.get().getPkgSupplement());
if (!pngImageData.isPresent()) {
if ((null == fallback) || !fallback) {
throw new PkgIconNotFound();
}
handleGenericHeadOrGet(requestMethod, response, size, true);
} else {
byte[] data = pngImageData.get();
response.setContentType(MediaType.PNG.toString());
outputToResponse(response, pkgSupplement, data, requestMethod == RequestMethod.GET);
}
break;
default:
throw new IllegalStateException("unexpected format; " + format);
}
}
use of org.haiku.haikudepotserver.dataobjects.PkgIcon in project haikudepotserver by haiku.
the class PkgApiIT method testConfigurePkgIcon_ok_bitmap.
/**
* <p>This test will configure the icons for the package.</p>
*/
@Test
public void testConfigurePkgIcon_ok_bitmap() throws Exception {
setAuthenticatedUserToRoot();
integrationTestSupportService.createStandardTestData();
byte[] sample16 = getResourceData("sample-16x16.png");
byte[] sample32 = getResourceData("sample-32x32.png");
byte[] sample64 = getResourceData("sample-64x64.png");
ConfigurePkgIconRequest request = new ConfigurePkgIconRequest();
request.pkgName = "pkg1";
request.pkgIcons = ImmutableList.of(new ConfigurePkgIconRequest.PkgIcon(MediaType.PNG.toString(), 16, Base64.getEncoder().encodeToString(sample16)), new ConfigurePkgIconRequest.PkgIcon(MediaType.PNG.toString(), 32, Base64.getEncoder().encodeToString(sample32)), new ConfigurePkgIconRequest.PkgIcon(MediaType.PNG.toString(), 64, Base64.getEncoder().encodeToString(sample64)));
// ------------------------------------
pkgApi.configurePkgIcon(request);
// ------------------------------------
{
ObjectContext objectContext = serverRuntime.newContext();
Pkg pkgAfter = Pkg.getByName(objectContext, "pkg1");
PkgSupplement pkgSupplementAfter = pkgAfter.getPkgSupplement();
org.haiku.haikudepotserver.dataobjects.MediaType mediaTypePng = org.haiku.haikudepotserver.dataobjects.MediaType.getByCode(objectContext, MediaType.PNG.toString());
Assertions.assertThat(pkgSupplementAfter.getPkgIcons().size()).isEqualTo(3);
Optional<PkgIcon> pkgIcon16Optional = pkgSupplementAfter.getPkgIcon(mediaTypePng, 16);
Assertions.assertThat(pkgIcon16Optional.get().getPkgIconImage().getData()).isEqualTo(sample16);
Optional<PkgIcon> pkgIcon32Optional = pkgSupplementAfter.getPkgIcon(mediaTypePng, 32);
Assertions.assertThat(pkgIcon32Optional.get().getPkgIconImage().getData()).isEqualTo(sample32);
Optional<PkgIcon> pkgIcon64Optional = pkgSupplementAfter.getPkgIcon(mediaTypePng, 64);
Assertions.assertThat(pkgIcon64Optional.get().getPkgIconImage().getData()).isEqualTo(sample64);
}
}
use of org.haiku.haikudepotserver.dataobjects.PkgIcon in project haikudepotserver by haiku.
the class PkgImportServiceImplIT method testImport_payloadData.
/**
* <P>During the import process, it is possible that the system is able to check the length of the
* package. This test will check that this mechanism is working.</P>
*/
@Test
public void testImport_payloadData() throws Exception {
File repositoryDirectory = null;
int expectedPayloadLength;
try {
// create the repository
integrationTestSupportService.createStandardTestData();
Pkg inputPackage = createPkg("3");
// setup a test repository
{
ObjectContext context = serverRuntime.newContext();
RepositorySource repositorySource = RepositorySource.tryGetByCode(context, "testreposrc_xyz").get();
repositoryDirectory = new File(repositorySource.tryGetPackagesBaseURL(ExposureType.INTERNAL_FACING).get().getPath());
if (!repositoryDirectory.mkdirs()) {
throw new IllegalStateException("unable to create the on-disk repository");
}
File fileF = new File(repositoryDirectory, "testpkg-1.3.3~4-5-x86_64.hpkg");
byte[] payload = Resources.toByteArray(Resources.getResource(RESOURCE_TEST));
Files.write(payload, fileF);
expectedPayloadLength = payload.length;
}
// now load the next package version in
{
ObjectContext context = serverRuntime.newContext();
RepositorySource repositorySource = RepositorySource.tryGetByCode(context, "testreposrc_xyz").get();
// ---------------------------------
pkgImportService.importFrom(context, repositorySource.getObjectId(), inputPackage, // <--- NOTE
true);
// ---------------------------------
context.commitChanges();
}
// check the length on that package is there and is correct and that the
// package icon is loaded in.
{
ObjectContext context = serverRuntime.newContext();
org.haiku.haikudepotserver.dataobjects.Pkg pkg = org.haiku.haikudepotserver.dataobjects.Pkg.getByName(context, "testpkg");
org.haiku.haikudepotserver.dataobjects.PkgVersion pkgVersion = pkgService.getLatestPkgVersionForPkg(context, pkg, Repository.tryGetByCode(context, "testrepo").get(), Collections.singletonList(Architecture.tryGetByCode(context, "x86_64").get())).get();
Assertions.assertThat(pkgVersion.getPayloadLength()).isEqualTo(expectedPayloadLength);
List<PkgIcon> pkgIcons = pkg.getPkgSupplement().getPkgIcons();
Assertions.assertThat(pkgIcons).hasSize(1);
PkgIcon pkgIcon = Iterables.getOnlyElement(pkgIcons);
byte[] actualIconData = pkgIcon.getPkgIconImage().getData();
Assertions.assertThat(actualIconData).hasSize(544);
}
} finally {
if (null != repositoryDirectory) {
FileHelper.delete(repositoryDirectory);
}
}
}
use of org.haiku.haikudepotserver.dataobjects.PkgIcon 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);
}
use of org.haiku.haikudepotserver.dataobjects.PkgIcon in project haikudepotserver by haiku.
the class PkgApiIT method testConfigurePkgIcon_ok_hvif.
/**
* <p>This test will configure the icons for the package.</p>
*/
@Test
public void testConfigurePkgIcon_ok_hvif() throws Exception {
setAuthenticatedUserToRoot();
integrationTestSupportService.createStandardTestData();
byte[] sampleHvif = getResourceData("sample.hvif");
ConfigurePkgIconRequest request = new ConfigurePkgIconRequest();
request.pkgName = "pkg1";
request.pkgIcons = Collections.singletonList(new ConfigurePkgIconRequest.PkgIcon(org.haiku.haikudepotserver.dataobjects.MediaType.MEDIATYPE_HAIKUVECTORICONFILE, null, Base64.getEncoder().encodeToString(sampleHvif)));
// ------------------------------------
pkgApi.configurePkgIcon(request);
// ------------------------------------
{
ObjectContext objectContext = serverRuntime.newContext();
PkgSupplement pkgSupplementAfter = Pkg.getByName(objectContext, "pkg1").getPkgSupplement();
org.haiku.haikudepotserver.dataobjects.MediaType mediaTypeHvif = org.haiku.haikudepotserver.dataobjects.MediaType.getByCode(objectContext, org.haiku.haikudepotserver.dataobjects.MediaType.MEDIATYPE_HAIKUVECTORICONFILE);
Assertions.assertThat(pkgSupplementAfter.getPkgIcons().size()).isEqualTo(1);
Optional<PkgIcon> pkgIconHvifOptional = pkgSupplementAfter.getPkgIcon(mediaTypeHvif, null);
Assertions.assertThat(pkgIconHvifOptional.get().getPkgIconImage().getData()).isEqualTo(sampleHvif);
}
}
Aggregations