package LinGUIne.extensions;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.Collection;
import java.util.LinkedList;
import java.util.NavigableSet;
import java.util.TreeMap;
import java.util.TreeSet;
import LinGUIne.model.AnnotationSet;
import LinGUIne.model.AnnotationSetContents;
import LinGUIne.model.IProjectData;
import LinGUIne.model.TextData;
import LinGUIne.model.TextDataContents;
import LinGUIne.model.annotations.IAnnotation;
import LinGUIne.model.annotations.Tag;
import LinGUIne.model.annotations.TextAnnotation;
/**
* Exporter to create an XML file from TextAnnotations in an AnnotationSet.
* Tags are XML tags surrounding the annotated text. Works with nested
* Annotations.
*
* @author Kyle Mullins
*/
public class XMLAnnotationExporter implements IAnnotationExporter {
@Override
public String getFileType() {
return "Extensible Markup Language (XML)";
}
@Override
public String getFileMask() {
return "*.xml";
}
@Override
public Collection<Class<? extends IProjectData>> getSupportedSourceDataTypes() {
LinkedList<Class<? extends IProjectData>> supportedTypes =
new LinkedList<Class<? extends IProjectData>>();
supportedTypes.add(TextData.class);
return supportedTypes;
}
@Override
public void exportAnnotation(IProjectData sourceData,
AnnotationSet annotations, File destFile) throws IOException {
if(sourceData instanceof TextData){
TextData textSource = (TextData)sourceData;
TextDataContents textContents = (TextDataContents)textSource.
getContents();
AnnotationSetContents annotationContents = annotations.getContents();
TreeMap<Integer, String> annotationTags = new TreeMap<Integer,
String>();
//Build up the sets of all Tags that will appear at each index
for(Tag tag: annotationContents.getTags()){
for(IAnnotation annotation: annotationContents.
getAnnotations(tag)){
if(annotation instanceof TextAnnotation){
TextAnnotation textAnn = (TextAnnotation)annotation;
String startTags = "";
String endTags = "";
if(annotationTags.containsKey(textAnn.getStartIndex())){
startTags = annotationTags.get(textAnn.getStartIndex());
}
if(annotationTags.containsKey(textAnn.getEndIndex())){
endTags = annotationTags.get(textAnn.getEndIndex());
}
startTags += "<" + tag.getName() + ">";
endTags = "</" + tag.getName() + ">" + endTags;
annotationTags.put(textAnn.getStartIndex(), startTags);
annotationTags.put(textAnn.getEndIndex(), endTags);
}
}
}
String xmlContent = textContents.getText();
NavigableSet<Integer> annotationIndices = new TreeSet<Integer>(
annotationTags.keySet()).descendingSet();
//Iterate through indices in reverse, inserting the Tag Strings that
//we built above into the original text
for(Integer annotationIndex: annotationIndices){
String textHead = xmlContent.substring(0, annotationIndex);
String textTail = xmlContent.substring(annotationIndex);
xmlContent = textHead + annotationTags.get(annotationIndex) +
textTail;
}
try(BufferedWriter writer = Files.newBufferedWriter(
destFile.toPath(), Charset.defaultCharset())){
writer.write(xmlContent);
}
catch(IOException ioe){
//Catch and rethrow the exception so the twr can close the stream
throw ioe;
}
}
else{
throw new IllegalArgumentException("Parameter sourceResult must be"
+ " of type TextData");
}
}
}