@Override
    public synchronized void parse(InputStream stream, ContentHandler handler, Metadata metadata,
                                   ParseContext context)
            throws IOException, SAXException, TikaException {
        if (!recogniser.isAvailable()) {
            LOG.warn("{} is not available for service", recogniser.getClass());
            return;
        }
        metadata.set(MD_REC_IMPL_KEY, recogniser.getClass().getName());
        long start = System.currentTimeMillis();
        List<? extends RecognisedObject> objects =
                recogniser.recognise(stream, handler, metadata, context);

        LOG.debug("Found {} objects", objects != null ? objects.size() : 0);
        LOG.info("Time taken {}ms", System.currentTimeMillis() - start);

        if (objects != null && !objects.isEmpty()) {
            int count;
            List<RecognisedObject> acceptedObjects = new ArrayList<>();
            List<String> xhtmlIds = new ArrayList<>();
            String xhtmlStartVal = null;
            count = 0;
            objects.sort((o1, o2) -> Double.compare(o2.getConfidence(), o1.getConfidence()));
            // first process all the MD objects
            for (RecognisedObject object : objects) {
                if (object instanceof CaptionObject) {
                    if (xhtmlStartVal == null) {
                        xhtmlStartVal = "captions";
                    }
                    String labelAndConfidence =
                            String.format(Locale.ENGLISH, "%s (%.5f)", object.getLabel(),
                                    object.getConfidence());
                    metadata.add(MD_KEY_IMG_CAP, labelAndConfidence);
                    xhtmlIds.add(String.valueOf(count++));
                } else {
                    if (xhtmlStartVal == null) {
                        xhtmlStartVal = "objects";
                    }
                    String labelAndConfidence =
                            String.format(Locale.ENGLISH, "%s (%.5f)", object.getLabel(),
                                    object.getConfidence());
                    metadata.add(MD_KEY_OBJ_REC, labelAndConfidence);
                    xhtmlIds.add(object.getId());
                }
                LOG.info("Add {}", object);
                acceptedObjects.add(object);
            }
            XHTMLContentHandler xhtml = new XHTMLContentHandler(handler, metadata);
            xhtml.startDocument();
            xhtml.startElement("ol", "id", xhtmlStartVal);
            count = 0;
            for (RecognisedObject object : acceptedObjects) {
                //writing to handler
                xhtml.startElement("li", "id", xhtmlIds.get(count++));
                String text = String.format(Locale.ENGLISH, " %s [%s](confidence = %f)",
                        object.getLabel(), object.getLabelLang(), object.getConfidence());
                xhtml.characters(text);
                xhtml.endElement("li");
            }
            xhtml.endElement("ol");
            xhtml.endDocument();
        } else {
            LOG.warn("NO objects");
            metadata.add("no.objects", Boolean.TRUE.toString());
        }
    }
@Test
    public void jpegTFObjRecTest() throws IOException, TikaException, SAXException {
        TensorflowImageRecParser p = new TensorflowImageRecParser();
        assumeTrue(p.isAvailable());
        try (InputStream stream = loader.getResourceAsStream(CONFIG_FILE_OBJ_REC)) {
            assert stream != null;
            Tika tika = new Tika(new TikaConfig(stream));
            Metadata metadata = new Metadata();
            try (InputStream imageStream = loader.getResourceAsStream(CAT_IMAGE_JPEG)) {
                Reader reader = tika.parse(imageStream, metadata);
                List<String> lines = IOUtils.readLines(reader);
                String text = StringUtils.join(lines, " ");
                String[] expectedObjects = {"Egyptian cat", "tabby, tabby cat"};
                String metaValues = StringUtils
                        .join(metadata.getValues(ObjectRecognitionParser.MD_KEY_OBJ_REC), " ");
                for (String expectedObject : expectedObjects) {
                    String message = "'" + expectedObject + "' must have been detected";
                    assertTrue(text.contains(expectedObject), message);
                    assertTrue(metaValues.contains(expectedObject), message);
                }
            }
        }
    }