/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
package org.apache.uima.caseditor.core.model.dotcorpus; | |
import java.awt.Color; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import javax.xml.parsers.DocumentBuilder; | |
import javax.xml.parsers.DocumentBuilderFactory; | |
import javax.xml.parsers.ParserConfigurationException; | |
import org.apache.uima.caseditor.CasEditorPlugin; | |
import org.apache.uima.caseditor.editor.AnnotationStyle; | |
import org.apache.uima.util.XMLSerializer; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.core.runtime.IStatus; | |
import org.eclipse.core.runtime.Status; | |
import org.w3c.dom.Element; | |
import org.w3c.dom.Node; | |
import org.w3c.dom.NodeList; | |
import org.xml.sax.ContentHandler; | |
import org.xml.sax.SAXException; | |
import org.xml.sax.helpers.AttributesImpl; | |
/** | |
* This class is responsible to read and write {@link DotCorpus} objects from or to a byte stream. | |
*/ | |
public class DotCorpusSerializer { | |
/** The Constant CONFIG_ELEMENT. */ | |
private static final String CONFIG_ELEMENT = "config"; | |
/** The Constant CORPUS_ELEMENT. */ | |
private static final String CORPUS_ELEMENT = "corpus"; | |
/** The Constant CORPUS_FOLDER_ATTRIBUTE. */ | |
private static final String CORPUS_FOLDER_ATTRIBUTE = "folder"; | |
/** The Constant STYLE_ELEMENT. */ | |
private static final String STYLE_ELEMENT = "style"; | |
/** The Constant STYLE_TYPE_ATTRIBUTE. */ | |
private static final String STYLE_TYPE_ATTRIBUTE = "type"; | |
/** The Constant STYLE_STYLE_ATTRIBUTE. */ | |
private static final String STYLE_STYLE_ATTRIBUTE = "style"; | |
/** The Constant STYLE_COLOR_ATTRIBUTE. */ | |
private static final String STYLE_COLOR_ATTRIBUTE = "color"; | |
/** The Constant STYLE_LAYER_ATTRIBUTE. */ | |
private static final String STYLE_LAYER_ATTRIBUTE = "layer"; | |
/** The Constant STYLE_CONFIG_ATTRIBUTE. */ | |
private static final String STYLE_CONFIG_ATTRIBUTE = "config"; | |
/** The Constant TYPESYSTEM_ELEMENT. */ | |
private static final String TYPESYSTEM_ELEMENT = "typesystem"; | |
/** The Constant TYPESYTEM_FILE_ATTRIBUTE. */ | |
private static final String TYPESYTEM_FILE_ATTRIBUTE = "file"; | |
/** The Constant CAS_PROCESSOR_ELEMENT. */ | |
private static final String CAS_PROCESSOR_ELEMENT = "processor"; | |
/** The Constant CAS_PROCESSOR_FOLDER_ATTRIBUTE. */ | |
private static final String CAS_PROCESSOR_FOLDER_ATTRIBUTE = "folder"; | |
/** The Constant EDITOR_ELEMENT. */ | |
private static final String EDITOR_ELEMENT = "editor"; | |
/** The Constant EDITOR_LINE_LENGTH_ATTRIBUTE. */ | |
private static final String EDITOR_LINE_LENGTH_ATTRIBUTE = "line-length-hint"; | |
/** The Constant SHOWN_ELEMENT. */ | |
private static final String SHOWN_ELEMENT = "shown"; | |
/** The Constant SHOWN_TYPE_ATTRIBUTE. */ | |
private static final String SHOWN_TYPE_ATTRIBUTE = "type"; | |
/** The Constant SHOWN_IS_VISISBLE_ATTRIBUTE. */ | |
private static final String SHOWN_IS_VISISBLE_ATTRIBUTE = "visible"; | |
/** | |
* Creates a {@link DotCorpus} object from a given {@link InputStream}. | |
* | |
* @param dotCorpusStream the dot corpus stream | |
* @return the {@link DotCorpus} instance. | |
* @throws CoreException - | |
*/ | |
public static DotCorpus parseDotCorpus(InputStream dotCorpusStream) throws CoreException { | |
DocumentBuilderFactory documentBuilderFacoty = DocumentBuilderFactory.newInstance(); | |
DocumentBuilder documentBuilder; | |
try { | |
documentBuilder = documentBuilderFacoty.newDocumentBuilder(); | |
} catch (ParserConfigurationException e) { | |
String message = "This should never happen:" + (e.getMessage() != null ? e.getMessage() : ""); | |
IStatus s = new Status(IStatus.ERROR, CasEditorPlugin.ID, IStatus.OK, message, e); | |
throw new CoreException(s); | |
} | |
org.w3c.dom.Document dotCorpusDOM; | |
try { | |
dotCorpusDOM = documentBuilder.parse(dotCorpusStream); | |
} catch (SAXException e) { | |
String message = e.getMessage() != null ? e.getMessage() : ""; | |
IStatus s = new Status(IStatus.ERROR, CasEditorPlugin.ID, IStatus.OK, message, e); | |
throw new CoreException(s); | |
} catch (IOException e) { | |
String message = e.getMessage() != null ? e.getMessage() : ""; | |
IStatus s = new Status(IStatus.ERROR, CasEditorPlugin.ID, IStatus.OK, message, e); | |
throw new CoreException(s); | |
} | |
DotCorpus dotCorpus = new DotCorpus(); | |
// get corpora root element | |
Element configElement = dotCorpusDOM.getDocumentElement(); | |
if (CONFIG_ELEMENT.equals(configElement.getNodeName())) { | |
// TODO: | |
// throw exception | |
} | |
NodeList corporaChildNodes = configElement.getChildNodes(); | |
for (int i = 0; i < corporaChildNodes.getLength(); i++) { | |
Node corporaChildNode = corporaChildNodes.item(i); | |
if (!(corporaChildNode instanceof Element)) { | |
continue; | |
} | |
Element corporaChildElement = (Element) corporaChildNode; | |
// TODO: This code will emit NumberFormatExceptions if the values | |
// are incorrect, they should be caught, logged and replaced with default | |
// values | |
if (TYPESYSTEM_ELEMENT.equals(corporaChildElement.getNodeName())) { | |
dotCorpus.setTypeSystemFilename(corporaChildElement.getAttribute(TYPESYTEM_FILE_ATTRIBUTE)); | |
} else if (CORPUS_ELEMENT.equals(corporaChildElement.getNodeName())) { | |
String corpusFolderName = corporaChildElement.getAttribute(CORPUS_FOLDER_ATTRIBUTE); | |
dotCorpus.addCorpusFolder(corpusFolderName); | |
} else if (STYLE_ELEMENT.equals(corporaChildElement.getNodeName())) { | |
String type = corporaChildElement.getAttribute(STYLE_TYPE_ATTRIBUTE); | |
String styleString = corporaChildElement.getAttribute(STYLE_STYLE_ATTRIBUTE); | |
int colorInteger = Integer | |
.parseInt(corporaChildElement.getAttribute(STYLE_COLOR_ATTRIBUTE)); | |
Color color = new Color(colorInteger); | |
String drawingLayerString = corporaChildElement.getAttribute(STYLE_LAYER_ATTRIBUTE); | |
String drawingConfigString = corporaChildElement.getAttribute(STYLE_CONFIG_ATTRIBUTE); | |
if (drawingConfigString.length() == 0) | |
drawingConfigString = null; | |
int drawingLayer; | |
try { | |
drawingLayer = Integer.parseInt(drawingLayerString); | |
} catch (NumberFormatException e) { | |
drawingLayer = 0; | |
} | |
AnnotationStyle style = new AnnotationStyle(type, AnnotationStyle.Style | |
.valueOf(styleString), color, drawingLayer, drawingConfigString); | |
dotCorpus.setStyle(style); | |
} else if (CAS_PROCESSOR_ELEMENT.equals(corporaChildElement.getNodeName())) { | |
dotCorpus.addCasProcessorFolder(corporaChildElement | |
.getAttribute(CAS_PROCESSOR_FOLDER_ATTRIBUTE)); | |
} else if (EDITOR_ELEMENT.equals(corporaChildElement.getNodeName())) { | |
String lineLengthHintString = corporaChildElement | |
.getAttribute(EDITOR_LINE_LENGTH_ATTRIBUTE); | |
int lineLengthHint = Integer.parseInt(lineLengthHintString); | |
dotCorpus.setEditorLineLength(lineLengthHint); | |
} else if (SHOWN_ELEMENT.equals(corporaChildElement.getNodeName())) { | |
String type = corporaChildElement.getAttribute(SHOWN_TYPE_ATTRIBUTE); | |
String isVisisbleString = corporaChildElement.getAttribute(SHOWN_IS_VISISBLE_ATTRIBUTE); | |
boolean isVisible = Boolean.parseBoolean(isVisisbleString); | |
if (isVisible) { | |
dotCorpus.setShownType(type); | |
} | |
} | |
else { | |
String message = "Unexpected element: " + corporaChildElement.getNodeName(); | |
IStatus s = new Status(IStatus.ERROR, CasEditorPlugin.ID, IStatus.OK, message, null); | |
throw new CoreException(s); | |
} | |
} | |
return dotCorpus; | |
} | |
/** | |
* Writes the <code>DotCorpus</code> instance to the given <code>OutputStream</code>. | |
* | |
* @param dotCorpus | |
* the {@link DotCorpus} object to serialize. | |
* @param out | |
* - the stream to write the current <code>DotCorpus</code> instance. | |
* @throws CoreException - | |
*/ | |
public static void serialize(DotCorpus dotCorpus, OutputStream out) throws CoreException { | |
XMLSerializer xmlSerializer = new XMLSerializer(out, true); | |
ContentHandler xmlSerHandler = xmlSerializer.getContentHandler(); | |
try { | |
xmlSerHandler.startDocument(); | |
xmlSerHandler.startElement("", CONFIG_ELEMENT, CONFIG_ELEMENT, new AttributesImpl()); | |
for (String corpusFolder : dotCorpus.getCorpusFolderNameList()) { | |
AttributesImpl corpusFolderAttributes = new AttributesImpl(); | |
corpusFolderAttributes.addAttribute("", "", CORPUS_FOLDER_ATTRIBUTE, "", corpusFolder); | |
xmlSerHandler.startElement("", CORPUS_ELEMENT, CORPUS_ELEMENT, corpusFolderAttributes); | |
xmlSerHandler.endElement("", CORPUS_ELEMENT, CORPUS_ELEMENT); | |
} | |
for (AnnotationStyle style : dotCorpus.getAnnotationStyles()) { | |
AttributesImpl styleAttributes = new AttributesImpl(); | |
styleAttributes.addAttribute("", "", STYLE_TYPE_ATTRIBUTE, "", style.getAnnotation()); | |
styleAttributes.addAttribute("", "", STYLE_STYLE_ATTRIBUTE, "", style.getStyle().name()); | |
Color color = style.getColor(); | |
Integer colorInt = new Color(color.getRed(), color.getGreen(), color.getBlue()).getRGB(); | |
styleAttributes.addAttribute("", "", STYLE_COLOR_ATTRIBUTE, "", colorInt.toString()); | |
styleAttributes.addAttribute("", "", STYLE_LAYER_ATTRIBUTE, "", Integer.toString(style | |
.getLayer())); | |
if (style.getConfiguration() != null) { | |
styleAttributes.addAttribute("", "", STYLE_CONFIG_ATTRIBUTE, "", style | |
.getConfiguration()); | |
} | |
xmlSerHandler.startElement("", STYLE_ELEMENT, STYLE_ELEMENT, styleAttributes); | |
xmlSerHandler.endElement("", STYLE_ELEMENT, STYLE_ELEMENT); | |
} | |
for (String type : dotCorpus.getShownTypes()) { | |
AttributesImpl shownAttributes = new AttributesImpl(); | |
shownAttributes.addAttribute("", "", SHOWN_TYPE_ATTRIBUTE, "", type); | |
shownAttributes.addAttribute("", "", SHOWN_IS_VISISBLE_ATTRIBUTE, "", "true"); | |
xmlSerHandler.startElement("", SHOWN_ELEMENT, SHOWN_ELEMENT, shownAttributes); | |
xmlSerHandler.endElement("", SHOWN_ELEMENT, SHOWN_ELEMENT); | |
} | |
if (dotCorpus.getTypeSystemFileName() != null) { | |
AttributesImpl typeSystemFileAttributes = new AttributesImpl(); | |
typeSystemFileAttributes.addAttribute("", "", TYPESYTEM_FILE_ATTRIBUTE, "", dotCorpus | |
.getTypeSystemFileName()); | |
xmlSerHandler.startElement("", TYPESYSTEM_ELEMENT, TYPESYSTEM_ELEMENT, | |
typeSystemFileAttributes); | |
xmlSerHandler.endElement("", TYPESYSTEM_ELEMENT, TYPESYSTEM_ELEMENT); | |
} | |
for (String folder : dotCorpus.getCasProcessorFolderNames()) { | |
AttributesImpl taggerConfigAttributes = new AttributesImpl(); | |
taggerConfigAttributes.addAttribute("", "", CAS_PROCESSOR_FOLDER_ATTRIBUTE, "", folder); | |
xmlSerHandler.startElement("", CAS_PROCESSOR_ELEMENT, CAS_PROCESSOR_ELEMENT, | |
taggerConfigAttributes); | |
xmlSerHandler.endElement("", CAS_PROCESSOR_ELEMENT, CAS_PROCESSOR_ELEMENT); | |
} | |
if (dotCorpus.getEditorLineLengthHint() != DotCorpus.EDITOR_LINE_LENGTH_HINT_DEFAULT) { | |
AttributesImpl editorLineLengthHintAttributes = new AttributesImpl(); | |
editorLineLengthHintAttributes.addAttribute("", "", EDITOR_LINE_LENGTH_ATTRIBUTE, "", | |
Integer.toString(dotCorpus.getEditorLineLengthHint())); | |
xmlSerHandler.startElement("", EDITOR_ELEMENT, EDITOR_ELEMENT, | |
editorLineLengthHintAttributes); | |
xmlSerHandler.endElement("", EDITOR_ELEMENT, EDITOR_ELEMENT); | |
} | |
xmlSerHandler.endElement("", CONFIG_ELEMENT, CONFIG_ELEMENT); | |
xmlSerHandler.endDocument(); | |
} catch (SAXException e) { | |
String message = e.getMessage() != null ? e.getMessage() : ""; | |
IStatus s = new Status(IStatus.ERROR, CasEditorPlugin.ID, IStatus.OK, message, e); | |
throw new CoreException(s); | |
} | |
} | |
} |