// necessary ReadingParser instances.
// Creates an empty SBMLDocument instance and pushes it on
// the SBMLElements stack.
if (currentNode.getLocalPart().equals("sbml")) {
SBMLDocument sbmlDocument = new SBMLDocument();
// the output of the change listener is activated or not via log4j.properties
sbmlDocument.addTreeNodeChangeListener(listener == null
? new SimpleTreeNodeChangeListener() : listener);
for (@SuppressWarnings("unchecked")
Iterator<Attribute> iterator = startElement.getAttributes(); iterator.hasNext();)
{
Attribute attr = iterator.next();
if (attr.getName().toString().equals("level")) {
level = StringTools.parseSBMLInt(attr.getValue());
sbmlDocument.setLevel(level);
} else if (attr.getName().toString().equals("version")) {
version = StringTools.parseSBMLInt(attr.getValue());
sbmlDocument.setVersion(version);
}
}
sbmlElements.push(sbmlDocument);
}
else if (lastElement == null) // We are probably reading some 'free' XML, mathML or HTML
{
// We put a fake Constraint element in the stack that can take either math, notes or message.
// This a hack to be able to read some mathMl or notes by themselves.
// If the parent container is set in this SBMLReader, we use it instead.
if (currentNode.getLocalPart().equals("notes") || currentNode.getLocalPart().equals("message"))
{
initializedParsers.put("", sbmlCoreParser);
} else if (currentNode.getLocalPart().equals("math"))
{
initializedParsers.put("", new MathMLStaxParser());
initializedParsers.put(ASTNode.URI_MATHML_DEFINITION, new MathMLStaxParser());
currentNode = new QName(ASTNode.URI_MATHML_DEFINITION, "math");
}
// TODO: will not work with arbitrary SBML part
// TODO: we need to be able, somehow, to set the Model element in the Constraint
// to be able to have a fully functional parsing. Without it the functionDefinition, for examples, are
// not properly recognized.
if (astNodeParent != null)
{
sbmlElements.push(astNodeParent);
}
else
{
Constraint constraint = new Constraint(3,1);
sbmlElements.push(constraint);
}
} else if (currentNode.getLocalPart().equals("annotation")) {
// get the sbml namespace as some element can have similar names in different namespaces
SBMLDocument sbmlDoc = (SBMLDocument) sbmlElements.firstElement();
String sbmlNamespace = sbmlDoc.getSBMLDocumentNamespaces().get("xmlns");
if (currentNode.getNamespaceURI().equals(sbmlNamespace)) {
if (isInsideAnnotation) {
logger.warn("Starting to read a new annotation element while the previous annotation element is not finished.");
}
isInsideAnnotation = true;
annotationDeepness++;
}
} else if (isInsideAnnotation) {
// Count the number of open elements to know how deep we are in the annotation
// We should only parse the RDF is annotationDeepness == 1 && rdfDescriptionIndex == 0
annotationDeepness++;
}
else if (currentNode.getLocalPart().equals("notes"))
{
// get the sbml namespace as some element can have similar names in different namespaces
SBase firstElement = (SBase) sbmlElements.firstElement();
if (firstElement instanceof SBMLDocument) {
SBMLDocument sbmlDoc = (SBMLDocument) firstElement;
String sbmlNamespace = sbmlDoc.getSBMLDocumentNamespaces().get("xmlns");
if (currentNode.getNamespaceURI().equals(sbmlNamespace)) {
isInsideNotes = true;
}
} else if (firstElement instanceof Constraint) { // we are reading a partial document from SBMLReader#readNotes for example
isInsideNotes = true;
}
}
// setting isRDFSBMLSpecificAnnotation
if (currentNode.getLocalPart().equals("RDF") && currentNode.getNamespaceURI().equals(Annotation.URI_RDF_SYNTAX_NS) && annotationDeepness == 1) {
isRDFSBMLSpecificAnnotation = true;
} else if (currentNode.getLocalPart().equals("RDF") && currentNode.getNamespaceURI().equals(Annotation.URI_RDF_SYNTAX_NS)) {
isRDFSBMLSpecificAnnotation = false;
rdfDescriptionIndex = -1;
}
if (currentNode.getLocalPart().equals("Description") && currentNode.getNamespaceURI().equals(Annotation.URI_RDF_SYNTAX_NS) && isRDFSBMLSpecificAnnotation) {
rdfDescriptionIndex++;
}
if (isInsideAnnotation && logger.isDebugEnabled()) {
logger.debug("startElement: local part = " + currentNode.getLocalPart());
logger.debug("startElement: annotation deepness = " + annotationDeepness);
logger.debug("startElement: rdf description index = " + rdfDescriptionIndex);
logger.debug("startElement: isRDFSBMLSpecificAnnotation = " + isRDFSBMLSpecificAnnotation);
}
parser = processStartElement(startElement, currentNode, isHTML, sbmlElements,
isInsideNotes, annotationDeepness, isRDFSBMLSpecificAnnotation);
lastElement = sbmlElements.peek();
}
// Characters
else if (event.isCharacters()) {
Characters characters = event.asCharacters();
if (!characters.isWhiteSpace()) {
isText = true; // the characters are not only 'white spaces'
}
if (sbmlElements.peek() instanceof XMLNode || isInsideNotes) {
isText = true; // We want to keep the whitespace/formatting when reading html block
}
// process the text of a XML element.
if ((parser != null) && !sbmlElements.isEmpty() && (isText || isInsideAnnotation)) {
if (isInsideNotes) {
parser = initializedParsers.get(JSBML.URI_XHTML_DEFINITION);
}
// else if (isInsideAnnotation) {
// parser = initializedParsers.get("anyAnnotation");
// }
if (logger.isDebugEnabled()) {
logger.debug(" Parser = " + parser.getClass().getName());
logger.debug(" Characters = @" + characters.getData() + "@");
}
if (currentNode != null) {
// logger.debug("isCharacter: elementName = " + currentNode.getLocalPart());
parser.processCharactersOf(currentNode.getLocalPart(),
characters.getData(), sbmlElements.peek());
} else {
parser.processCharactersOf(null, characters.getData(),
sbmlElements.peek());
}
} else if (isText) {
logger.warn(MessageFormat.format("Some characters cannot be read: {0}", characters.getData()));
if (logger.isDebugEnabled()) {
logger.debug("Parser = " + parser);
if (sbmlElements.isEmpty()) {
logger.debug("The Object Stack is empty!");
} else {
logger.debug("The current Object in the stack is: " + sbmlElements.peek());
}
}
}
}
// EndElement
else if (event.isEndElement()) {
// the method processEndElement will return null until we arrive at the end of the 'sbml' element.
lastElement = sbmlElements.peek();
currentNode = event.asEndElement().getName();
if (currentNode != null) {
boolean isSBMLelement = true;
// get the sbml namespace as some element can have similar names in different namespaces
if (sbmlElements.firstElement() instanceof SBMLDocument) {
SBMLDocument sbmlDoc = (SBMLDocument) sbmlElements.firstElement();
String sbmlNamespace = sbmlDoc.getSBMLDocumentNamespaces().get("xmlns");
if (!currentNode.getNamespaceURI().equals(sbmlNamespace)) {
isSBMLelement = false;
}
}
if (currentNode.getLocalPart().equals("annotation")) {
if (isSBMLelement) {
isInsideAnnotation = false;
annotationDeepness = -1;
rdfDescriptionIndex = -1;
isRDFSBMLSpecificAnnotation = false;
}
} else if (isInsideAnnotation) {
annotationDeepness--;
}
else if (currentNode.getLocalPart().equals("notes") && isSBMLelement)
{
isInsideNotes = false;
}
if (currentNode.getLocalPart().equals("Description")
&& currentNode.getNamespaceURI().equals(Annotation.URI_RDF_SYNTAX_NS))
{
rdfDescriptionIndex--;
}
}
SBMLDocument sbmlDocument = processEndElement(currentNode, isNested, isText, isHTML,
level, version, parser, sbmlElements, isInsideNotes, annotationDeepness,
isRDFSBMLSpecificAnnotation);
if (sbmlDocument != null) {
return sbmlDocument;