001package org.nasdanika.ai.drawio; 002 003import java.io.IOException; 004import java.util.List; 005 006import javax.xml.parsers.ParserConfigurationException; 007 008import org.apache.commons.imaging.common.GenericImageMetadata.GenericImageMetadataItem; 009import org.apache.commons.imaging.common.ImageMetadata; 010import org.apache.commons.imaging.common.ImageMetadata.ImageMetadataItem; 011import org.nasdanika.ai.ImageMetadataNarrator; 012import org.nasdanika.ai.Narrator; 013import org.nasdanika.drawio.Document; 014import org.slf4j.Logger; 015import org.slf4j.LoggerFactory; 016import org.xml.sax.SAXException; 017 018import reactor.core.publisher.Mono; 019 020public abstract class DocumentImageMetadataNarrator<S> extends ImageMetadataNarrator<S> { 021 022 private static Logger LOGGER = LoggerFactory.getLogger(DocumentImageMetadataNarrator.class); 023 024 protected Narrator<Document> documentNarrator; 025 026 /** 027 * @param documentNarrator Narrates document if it is found in the image metadata. 028 */ 029 protected DocumentImageMetadataNarrator(Narrator<Document> documentNarrator) { 030 this.documentNarrator = documentNarrator; 031 } 032 033 // TODO - document narrator 034 035 @Override 036 public Mono<String> generateAsync(S input) { 037 return narrateMetadataAsync(getImageMetadata(input)); 038 } 039 040 @Override 041 public String generate(S input) { 042 return narrateMetadata(getImageMetadata(input)); 043 } 044 045 protected abstract ImageMetadata getImageMetadata(S source); 046 047 protected String narrateMetadata(ImageMetadata metadata) { 048 if (metadata != null) { 049 List<? extends ImageMetadataItem> items = metadata.getItems(); 050 if (items != null) { 051 for (ImageMetadataItem item: items) { 052 if (item instanceof GenericImageMetadataItem) { 053 GenericImageMetadataItem gItem = (GenericImageMetadataItem) item; 054 if ("mxfile".equals(gItem.getKeyword())) { 055 try { 056 Document document = Document.load(gItem.getText(), null); 057 return documentNarrator.generate(document); 058 } catch (ParserConfigurationException | SAXException | IOException e) { 059 LOGGER.error("Could not narrate document from metadata: " + e, e); 060 } 061 } 062 } 063 } 064 } 065 } 066 return super.narrateMetadata(metadata); 067 } 068 069 protected Mono<String> narrateMetadataAsync(ImageMetadata metadata) { 070 return Mono.just(narrateMetadata(metadata)); 071 } 072 073}