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}