package net.rrm.ehour.backup.service.restore;
import net.rrm.ehour.backup.domain.ExportElements;
import net.rrm.ehour.backup.domain.ImportException;
import net.rrm.ehour.backup.domain.ParseSession;
import net.rrm.ehour.config.ConfigurationItem;
import net.rrm.ehour.domain.Configuration;
import org.apache.log4j.Logger;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
/**
* @author thies (Thies Edeling - thies@te-con.nl)
* Created on: 12/6/10 - 3:40 PM
*/
public class XmlParser {
private static final Logger LOG = Logger.getLogger(XmlParser.class);
private final ParseContext ctx;
public XmlParser(ParseContext ctx) {
this.ctx = ctx;
}
public void parseXml(final ParseSession session, final XMLEventReader eventReader) throws Exception {
JoinTables joinTables = new JoinTables();
session.start();
while (eventReader.hasNext()) {
session.eventProgressed();
final XMLEvent event = eventReader.nextTag();
if (event.isStartElement()) {
parseEvent(session, eventReader, event, joinTables);
} else if (event.isEndDocument() || event.isEndElement()) {
break;
}
}
session.finish();
}
private void parseEvent(ParseSession session, XMLEventReader eventReader, XMLEvent event, JoinTables joinTables)
throws ImportException, XMLStreamException, InstantiationException, IllegalAccessException, ClassNotFoundException {
StartElement startElement = event.asStartElement();
String startName = startElement.getName().getLocalPart();
ExportElements element = safelyGetExportElements(startName);
LOG.info("Element found in backup file: " + element.name() + " = " + startName);
switch (element) {
case EHOUR:
if (!ctx.skipValidation) {
checkDatabaseVersion(startElement);
}
break;
case CONFIGURATION:
ctx.configurationParser.parseConfiguration(eventReader);
break;
case JOIN_TABLES:
parseJoinTables(joinTables);
break;
case ENTITY_TABLES:
parseEntityTables(joinTables, session);
break;
default:
break;
}
}
private ExportElements safelyGetExportElements(String name) {
try {
return ExportElements.valueOf(name);
} catch (IllegalArgumentException iae) {
return ExportElements.OTHER;
}
}
private JoinTables parseJoinTables(JoinTables joinTables) throws XMLStreamException {
return ctx.joinTableParser.parseJoinTables(joinTables);
}
private void parseEntityTables(JoinTables joinTables, ParseSession session) throws XMLStreamException, ClassNotFoundException, ImportException, InstantiationException, IllegalAccessException {
ctx.entityTableParser.parseEntityTables(joinTables, session);
}
private void checkDatabaseVersion(StartElement element) throws ImportException {
Attribute attribute = element.getAttributeByName(new QName(ExportElements.DB_VERSION.name()));
String dbVersion = attribute.getValue();
Configuration version = ctx.configurationDao.findById(ConfigurationItem.VERSION.getDbField());
isDatabaseCompatible(version.getConfigValue(), dbVersion);
}
private void isDatabaseCompatible(String version, String dbVersion) throws ImportException {
dbVersion = dbVersion != null && dbVersion.equalsIgnoreCase("0.8.3") ? "0.8.4" : dbVersion;
version = version != null && version.equalsIgnoreCase("0.8.3") ? "0.8.4" : version;
if (version == null || !version.equalsIgnoreCase(dbVersion)) {
String foundVersion = version != null ? version : "n/a";
throw new ImportException("Invalid database version (" + dbVersion + ") specified in file, target database should match backup database version (" + foundVersion + ")");
}
}
}