ThemesEndpoint { @PUT @Path("{themeId}") @RestQuery(name = "updateTheme", description = "Updates a theme", returnDescription = "Return the updated theme", pathParameters = { @RestParameter(name = "themeId", description = "The theme identifier", isRequired = true, type = Type.INTEGER) }, restParameters = { @RestParameter(name = "default", description = "Whether the theme is default", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "name", description = "The theme name", isRequired = false, type = Type.STRING), @RestParameter(name = "description", description = "The theme description", isRequired = false, type = Type.TEXT), @RestParameter(name = "bumperActive", description = "Whether the theme bumper is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "trailerActive", description = "Whether the theme trailer is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "titleSlideActive", description = "Whether the theme title slide is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "licenseSlideActive", description = "Whether the theme license slide is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "watermarkActive", description = "Whether the theme watermark is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "bumperFile", description = "The theme bumper file", isRequired = false, type = Type.STRING), @RestParameter(name = "trailerFile", description = "The theme trailer file", isRequired = false, type = Type.STRING), @RestParameter(name = "watermarkFile", description = "The theme watermark file", isRequired = false, type = Type.STRING), @RestParameter(name = "titleSlideBackground", description = "The theme title slide background file", isRequired = false, type = Type.STRING), @RestParameter(name = "licenseSlideBackground", description = "The theme license slide background file", isRequired = false, type = Type.STRING), @RestParameter(name = "titleSlideMetadata", description = "The theme title slide metadata", isRequired = false, type = Type.STRING), @RestParameter(name = "licenseSlideDescription", description = "The theme license slide description", isRequired = false, type = Type.STRING), @RestParameter(name = "watermarkPosition", description = "The theme watermark position", isRequired = false, type = Type.STRING), }, responses = { @RestResponse(responseCode = SC_OK, description = "Theme updated"), @RestResponse(responseCode = SC_NOT_FOUND, description = "If the theme has not been found."), }) public Response updateTheme(@PathParam("themeId") long themeId, @FormParam("default") Boolean isDefault, @FormParam("name") String name, @FormParam("description") String description, @FormParam("bumperActive") Boolean bumperActive, @FormParam("trailerActive") Boolean trailerActive, @FormParam("titleSlideActive") Boolean titleSlideActive, @FormParam("licenseSlideActive") Boolean licenseSlideActive, @FormParam("watermarkActive") Boolean watermarkActive, @FormParam("bumperFile") String bumperFile, @FormParam("trailerFile") String trailerFile, @FormParam("watermarkFile") String watermarkFile, @FormParam("titleSlideBackground") String titleSlideBackground, @FormParam("licenseSlideBackground") String licenseSlideBackground, @FormParam("titleSlideMetadata") String titleSlideMetadata, @FormParam("licenseSlideDescription") String licenseSlideDescription, @FormParam("watermarkPosition") String watermarkPosition) throws NotFoundException { try { Theme origTheme = themesServiceDatabase.getTheme(themeId); if (isDefault == null) isDefault = origTheme.isDefault(); if (StringUtils.isBlank(name)) name = origTheme.getName(); if (StringUtils.isEmpty(description)) description = origTheme.getDescription(); if (bumperActive == null) bumperActive = origTheme.isBumperActive(); if (StringUtils.isEmpty(bumperFile)) bumperFile = origTheme.getBumperFile(); if (trailerActive == null) trailerActive = origTheme.isTrailerActive(); if (StringUtils.isEmpty(trailerFile)) trailerFile = origTheme.getTrailerFile(); if (titleSlideActive == null) titleSlideActive = origTheme.isTitleSlideActive(); if (StringUtils.isEmpty(titleSlideMetadata)) titleSlideMetadata = origTheme.getTitleSlideMetadata(); if (StringUtils.isEmpty(titleSlideBackground)) titleSlideBackground = origTheme.getTitleSlideBackground(); if (licenseSlideActive == null) licenseSlideActive = origTheme.isLicenseSlideActive(); if (StringUtils.isEmpty(licenseSlideBackground)) licenseSlideBackground = origTheme.getLicenseSlideBackground(); if (StringUtils.isEmpty(licenseSlideDescription)) licenseSlideDescription = origTheme.getLicenseSlideDescription(); if (watermarkActive == null) watermarkActive = origTheme.isWatermarkActive(); if (StringUtils.isEmpty(watermarkFile)) watermarkFile = origTheme.getWatermarkFile(); if (StringUtils.isEmpty(watermarkPosition)) watermarkPosition = origTheme.getWatermarkPosition(); Theme theme = new Theme(origTheme.getId(), origTheme.getCreationDate(), isDefault, origTheme.getCreator(), name, StringUtils.trimToNull(description), BooleanUtils.toBoolean(bumperActive), StringUtils.trimToNull(bumperFile), BooleanUtils.toBoolean(trailerActive), StringUtils.trimToNull(trailerFile), BooleanUtils.toBoolean(titleSlideActive), StringUtils.trimToNull(titleSlideMetadata), StringUtils.trimToNull(titleSlideBackground), BooleanUtils.toBoolean(licenseSlideActive), StringUtils.trimToNull(licenseSlideBackground), StringUtils.trimToNull(licenseSlideDescription), BooleanUtils.toBoolean(watermarkActive), StringUtils.trimToNull(watermarkFile), StringUtils.trimToNull(watermarkPosition)); try { updateReferencedFiles(origTheme, theme); } catch (IOException e) { logger.warn("Error while persisting file: {}", e.getMessage()); return R.serverError(); } catch (NotFoundException e) { logger.warn("A file that is referenced in theme '{}' was not found: {}", theme, e.getMessage()); return R.badRequest("Referenced non-existing file"); } Theme updatedTheme = themesServiceDatabase.updateTheme(theme); return RestUtils.okJson(themeToJSON(updatedTheme)); } catch (ThemesServiceDatabaseException e) { logger.error("Unable to update theme {}", themeId, e); return RestUtil.R.serverError(); } }  void setThemesServiceDatabase(ThemesServiceDatabase themesServiceDatabase); void setSecurityService(SecurityService securityService); void setIndex(AdminUISearchIndex index); void setSeriesService(SeriesService seriesService); void setStaticFileService(StaticFileService staticFileService); void setStaticFileRestService(StaticFileRestService staticFileRestService); void activate(BundleContext bundleContext); @GET @Produces({ MediaType.APPLICATION_JSON }) @Path("themes.json") @RestQuery(name = "getThemes", description = "Return all of the known themes on the system", restParameters = { @RestParameter(name = "filter", isRequired = false, description = "The filter used for the query. They should be formated like that: 'filter1:value1,filter2:value2'", type = STRING), @RestParameter(defaultValue = "0", description = "The maximum number of items to return per page.", isRequired = false, name = "limit", type = RestParameter.Type.INTEGER), @RestParameter(defaultValue = "0", description = "The page number.", isRequired = false, name = "offset", type = RestParameter.Type.INTEGER), @RestParameter(name = "sort", isRequired = false, description = "The sort order. May include any of the following: NAME, CREATOR. Add '_DESC' to reverse the sort order (e.g. CREATOR_DESC).", type = STRING) }, responses = { @RestResponse(description = "A JSON representation of the themes", responseCode = HttpServletResponse.SC_OK) }, returnDescription = "") Response getThemes(@QueryParam("filter") String filter, @QueryParam("limit") int limit,
          @QueryParam("offset") int offset, @QueryParam("sort") String sort); @GET @Path("{themeId}.json") @Produces(MediaType.APPLICATION_JSON) @RestQuery(name = "getTheme", description = "Returns the theme by the given id as JSON", returnDescription = "The theme as JSON", pathParameters = { @RestParameter(name = "themeId", description = "The theme id", isRequired = true, type = RestParameter.Type.INTEGER) }, responses = { @RestResponse(description = "Returns the theme as JSON", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "No theme with this identifier was found.", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response getThemeResponse(@PathParam("themeId") long id); @GET @Path("{themeId}/usage.json") @Produces(MediaType.APPLICATION_JSON) @RestQuery(name = "getThemeUsage", description = "Returns the theme usage by the given id as JSON", returnDescription = "The theme usage as JSON", pathParameters = { @RestParameter(name = "themeId", description = "The theme id", isRequired = true, type = RestParameter.Type.INTEGER) }, responses = { @RestResponse(description = "Returns the theme usage as JSON", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "Theme with the given id does not exist", responseCode = HttpServletResponse.SC_NOT_FOUND) }) Response getThemeUsage(@PathParam("themeId") long themeId); @POST @Path("") @RestQuery(name = "createTheme", description = "Add a theme", returnDescription = "Return the created theme", restParameters = { @RestParameter(name = "default", description = "Whether the theme is default", isRequired = true, type = Type.BOOLEAN), @RestParameter(name = "name", description = "The theme name", isRequired = true, type = Type.STRING), @RestParameter(name = "description", description = "The theme description", isRequired = false, type = Type.TEXT), @RestParameter(name = "bumperActive", description = "Whether the theme bumper is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "trailerActive", description = "Whether the theme trailer is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "titleSlideActive", description = "Whether the theme title slide is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "licenseSlideActive", description = "Whether the theme license slide is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "watermarkActive", description = "Whether the theme watermark is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "bumperFile", description = "The theme bumper file", isRequired = false, type = Type.STRING), @RestParameter(name = "trailerFile", description = "The theme trailer file", isRequired = false, type = Type.STRING), @RestParameter(name = "watermarkFile", description = "The theme watermark file", isRequired = false, type = Type.STRING), @RestParameter(name = "titleSlideBackground", description = "The theme title slide background file", isRequired = false, type = Type.STRING), @RestParameter(name = "licenseSlideBackground", description = "The theme license slide background file", isRequired = false, type = Type.STRING), @RestParameter(name = "titleSlideMetadata", description = "The theme title slide metadata", isRequired = false, type = Type.STRING), @RestParameter(name = "licenseSlideDescription", description = "The theme license slide description", isRequired = false, type = Type.STRING), @RestParameter(name = "watermarkPosition", description = "The theme watermark position", isRequired = false, type = Type.STRING), }, responses = { @RestResponse(responseCode = SC_OK, description = "Theme created"), @RestResponse(responseCode = SC_BAD_REQUEST, description = "The theme references a non-existing file") }) Response createTheme(@FormParam("default") boolean isDefault, @FormParam("name") String name,
          @FormParam("description") String description, @FormParam("bumperActive") Boolean bumperActive,
          @FormParam("trailerActive") Boolean trailerActive, @FormParam("titleSlideActive") Boolean titleSlideActive,
          @FormParam("licenseSlideActive") Boolean licenseSlideActive,
          @FormParam("watermarkActive") Boolean watermarkActive, @FormParam("bumperFile") String bumperFile,
          @FormParam("trailerFile") String trailerFile, @FormParam("watermarkFile") String watermarkFile,
          @FormParam("titleSlideBackground") String titleSlideBackground,
          @FormParam("licenseSlideBackground") String licenseSlideBackground,
          @FormParam("titleSlideMetadata") String titleSlideMetadata,
          @FormParam("licenseSlideDescription") String licenseSlideDescription,
          @FormParam("watermarkPosition") String watermarkPosition); @PUT @Path("{themeId}") @RestQuery(name = "updateTheme", description = "Updates a theme", returnDescription = "Return the updated theme", pathParameters = { @RestParameter(name = "themeId", description = "The theme identifier", isRequired = true, type = Type.INTEGER) }, restParameters = { @RestParameter(name = "default", description = "Whether the theme is default", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "name", description = "The theme name", isRequired = false, type = Type.STRING), @RestParameter(name = "description", description = "The theme description", isRequired = false, type = Type.TEXT), @RestParameter(name = "bumperActive", description = "Whether the theme bumper is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "trailerActive", description = "Whether the theme trailer is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "titleSlideActive", description = "Whether the theme title slide is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "licenseSlideActive", description = "Whether the theme license slide is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "watermarkActive", description = "Whether the theme watermark is active", isRequired = false, type = Type.BOOLEAN), @RestParameter(name = "bumperFile", description = "The theme bumper file", isRequired = false, type = Type.STRING), @RestParameter(name = "trailerFile", description = "The theme trailer file", isRequired = false, type = Type.STRING), @RestParameter(name = "watermarkFile", description = "The theme watermark file", isRequired = false, type = Type.STRING), @RestParameter(name = "titleSlideBackground", description = "The theme title slide background file", isRequired = false, type = Type.STRING), @RestParameter(name = "licenseSlideBackground", description = "The theme license slide background file", isRequired = false, type = Type.STRING), @RestParameter(name = "titleSlideMetadata", description = "The theme title slide metadata", isRequired = false, type = Type.STRING), @RestParameter(name = "licenseSlideDescription", description = "The theme license slide description", isRequired = false, type = Type.STRING), @RestParameter(name = "watermarkPosition", description = "The theme watermark position", isRequired = false, type = Type.STRING), }, responses = { @RestResponse(responseCode = SC_OK, description = "Theme updated"), @RestResponse(responseCode = SC_NOT_FOUND, description = "If the theme has not been found."), }) Response updateTheme(@PathParam("themeId") long themeId, @FormParam("default") Boolean isDefault,
          @FormParam("name") String name, @FormParam("description") String description,
          @FormParam("bumperActive") Boolean bumperActive, @FormParam("trailerActive") Boolean trailerActive,
          @FormParam("titleSlideActive") Boolean titleSlideActive,
          @FormParam("licenseSlideActive") Boolean licenseSlideActive,
          @FormParam("watermarkActive") Boolean watermarkActive, @FormParam("bumperFile") String bumperFile,
          @FormParam("trailerFile") String trailerFile, @FormParam("watermarkFile") String watermarkFile,
          @FormParam("titleSlideBackground") String titleSlideBackground,
          @FormParam("licenseSlideBackground") String licenseSlideBackground,
          @FormParam("titleSlideMetadata") String titleSlideMetadata,
          @FormParam("licenseSlideDescription") String licenseSlideDescription,
          @FormParam("watermarkPosition") String watermarkPosition); @DELETE @Path("{themeId}") @RestQuery(name = "deleteTheme", description = "Deletes a theme", returnDescription = "The method doesn't return any content", pathParameters = { @RestParameter(name = "themeId", isRequired = true, description = "The theme identifier", type = RestParameter.Type.INTEGER) }, responses = { @RestResponse(responseCode = SC_NOT_FOUND, description = "If the theme has not been found."), @RestResponse(responseCode = SC_NO_CONTENT, description = "The method does not return any content"), @RestResponse(responseCode = SC_UNAUTHORIZED, description = "If the current user is not authorized to perform this action") }) Response deleteTheme(@PathParam("themeId") long themeId);  }
@Test public void testUpdateTheme() throws ParseException, IOException { String themesString = IOUtils.toString(getClass().getResource("/theme-update.json"), "UTF-8"); String result = given().pathParam("themeId", 1).formParam("default", true).formParam("name", "new-name") .formParam("description", "new-description").formParam("bumperActive", true) .formParam("bumperFile", "new-bumper-file").formParam("trailerActive", true) .formParam("trailerFile", "new-trailer-file").formParam("titleSlideActive", true) .formParam("titleSlideBackground", "new-title-background") .formParam("titleSlideMetadata", "new-title-metadata").formParam("licenseSlideActive", true) .formParam("licenseSlideBackground", "new-license-background") .formParam("licenseSlideDescription", "new-license-description").formParam("watermarkActive", true) .formParam("watermarkPosition", "new-watermark-position").formParam("watermarkFile", "new-watermark-file") .expect().statusCode(HttpStatus.SC_OK).when().put(rt.host("/{themeId}")).asString(); JSONObject theme = ((JSONObject) parser.parse(result)); assertTrue(StringUtils.trimToNull(theme.get("creationDate").toString()) != null); theme.remove("creationDate"); logger.info("Expected" + themesString); logger.info("Result: " + theme.toJSONString()); assertThat(themesString, SameJSONAs.sameJSONAs(theme.toJSONString()).allowingAnyArrayOrdering()); }