ToolsEndpoint implements ManagedService { List<Tuple<Long, Long>> getSegmentsFromSmil(Smil smil) { List<Tuple<Long, Long>> segments = new ArrayList<>(); for (SmilMediaObject elem : smil.getBody().getMediaElements()) { if (elem instanceof SmilMediaContainer) { SmilMediaContainer mediaContainer = (SmilMediaContainer) elem; Tuple tuple = null; for (SmilMediaObject video : mediaContainer.getElements()) { if (video instanceof SmilMediaElement) { SmilMediaElement videoElem = (SmilMediaElement) video; try { if (tuple == null || (videoElem.getClipEndMS() - videoElem.getClipBeginMS()) > (Long) tuple.getB() - (Long) tuple.getA()) { tuple = Tuple.tuple(videoElem.getClipBeginMS(), videoElem.getClipEndMS()); } } catch (SmilException e) { logger.warn("Media element '{}' of SMIL catalog '{}' seems to be invalid: {}", videoElem, smil, e); } } } if (tuple != null) { segments.add(tuple); } } } return segments; }  @Override void updated(Dictionary<String, ?> properties); @GET @Path("{mediapackageid}.json") @RestQuery(name = "getAvailableTools", description = "Returns a list of tools which are currently available for the given media package.", returnDescription = "A JSON array with tools identifiers", pathParameters = { @RestParameter(name = "mediapackageid", description = "The id of the media package", isRequired = true, type = RestParameter.Type.STRING) }, responses = { @RestResponse(description = "Available tools evaluated", responseCode = HttpServletResponse.SC_OK) }) Response getAvailableTools(@PathParam("mediapackageid") final String mediaPackageId); @GET @Path("{mediapackageid}/editor.json") @Produces(MediaType.APPLICATION_JSON) @RestQuery(name = "getVideoEditor", description = "Returns all the information required to get the editor tool started", returnDescription = "JSON object", pathParameters = { @RestParameter(name = "mediapackageid", description = "The id of the media package", isRequired = true, type = RestParameter.Type.STRING) }, responses = { @RestResponse(description = "Media package found", responseCode = SC_OK), @RestResponse(description = "Media package not found", responseCode = SC_NOT_FOUND) }) Response getVideoEditor(@PathParam("mediapackageid") final String mediaPackageId); @POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.APPLICATION_JSON) @Path("{mediapackageid}/thumbnail.json") Response changeThumbnail(@PathParam("mediapackageid") final String mediaPackageId,
    @Context HttpServletRequest request); @POST @Path("{mediapackageid}/editor.json") @Consumes(MediaType.APPLICATION_JSON) @RestQuery(name = "editVideo", description = "Takes editing information from the client side and processes it", returnDescription = "", pathParameters = { @RestParameter(name = "mediapackageid", description = "The id of the media package", isRequired = true, type = RestParameter.Type.STRING) }, responses = { @RestResponse(description = "Editing information saved and processed", responseCode = HttpServletResponse.SC_OK), @RestResponse(description = "Media package not found", responseCode = HttpServletResponse.SC_NOT_FOUND), @RestResponse(description = "The editing information cannot be parsed", responseCode = HttpServletResponse.SC_BAD_REQUEST) }) Response editVideo(@PathParam("mediapackageid") final String mediaPackageId,
          @Context HttpServletRequest request);  }
@Test public void testGetSegmentsFromSmil() throws Exception { List<Tuple<Long, Long>> segments = endpoint.getSegmentsFromSmil(smil); assertEquals(4, segments.size()); assertTrue(segments.contains(Tuple.tuple(0L, 2449L))); assertTrue(segments.contains(Tuple.tuple(4922L, 11284L))); assertTrue(segments.contains(Tuple.tuple(14721L, 15963L))); assertTrue(segments.contains(Tuple.tuple(15963L, 20132L))); }