001
002 /*
003 * Copyright (C) 2012 Archie L. Cobbs. All rights reserved.
004 *
005 * $Id: UpdatesXMLEventReader.java 259 2012-01-30 19:47:58Z archie.cobbs $
006 */
007
008 package org.dellroad.stuff.pobj;
009
010 import java.util.ArrayList;
011 import java.util.List;
012
013 import javax.xml.stream.XMLEventReader;
014 import javax.xml.stream.XMLStreamException;
015 import javax.xml.stream.events.StartElement;
016 import javax.xml.stream.events.XMLEvent;
017
018 import org.dellroad.stuff.xml.AnnotatedXMLEventReader;
019
020 /**
021 * {@link AnnotatedXMLEventReader} that reads the nested schema update list. Used by {@link PersistentObjectSchemaUpdater}.
022 */
023 public class UpdatesXMLEventReader extends AnnotatedXMLEventReader {
024
025 private ArrayList<String> updates;
026
027 public UpdatesXMLEventReader(XMLEventReader inner) {
028 super(inner);
029 }
030
031 /**
032 * Get the updates gleaned from the scan.
033 *
034 * @return list of updates, or null if the document didn't contain an updates element
035 */
036 public List<String> getUpdates() {
037 return this.updates;
038 }
039
040 @Override
041 protected boolean isAnnotationElement(StartElement event) {
042 return event.getName().equals(PersistentObjectSchemaUpdater.UPDATES_ELEMENT_NAME);
043 }
044
045 @Override
046 protected void readAnnotationElement(StartElement startElement) throws XMLStreamException {
047 this.updates = new ArrayList<String>();
048 while (true) {
049
050 // Skip to next event
051 XMLEvent event = this.advance();
052
053 // Skip whitespace and comments
054 event = this.skipWhiteSpace(event, true);
055
056 // Done with updates?
057 if (event.isEndElement()) {
058 this.advance();
059 return;
060 }
061
062 // Get <update> start element event
063 if (!event.isStartElement()
064 || !event.asStartElement().getName().equals(PersistentObjectSchemaUpdater.UPDATE_ELEMENT_NAME)) {
065 throw new XMLStreamException("XML parse error: expected " + PersistentObjectSchemaUpdater.UPDATE_ELEMENT_NAME
066 + " but got " + this.describe(event), event.getLocation());
067 }
068
069 // Get update name
070 StringBuilder buf = new StringBuilder();
071 for (event = this.advance(); event.isCharacters(); event = this.advance())
072 buf.append(event.asCharacters().getData());
073 this.updates.add(buf.toString());
074
075 // Get <update> end element event
076 if (!event.isEndElement()) {
077 throw new XMLStreamException("XML parse error: expected " + PersistentObjectSchemaUpdater.UPDATE_ELEMENT_NAME
078 + " closing tag but got " + this.describe(event), event.getLocation());
079 }
080 }
081 }
082
083 private String describe(XMLEvent event) {
084 return event.getClass().getSimpleName() + "[" + event + "]";
085 }
086 }
087