/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
Cyclos is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Cyclos is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package nl.strohalm.cyclos.setup;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Class used to read the version reader from a XML file
* @author luis
*/
public class VersionHistoryReader {
public static void main(final String[] args) {
System.out.println(new VersionHistoryReader().read());
}
/**
* Read the version history from classpath
* @throws ParserConfigurationException
*/
public VersionHistory read() {
final Document document = readDocument();
final VersionHistory history = new VersionHistory();
final NodeList versions = document.getElementsByTagName("version");
for (int i = 0; i < versions.getLength(); i++) {
final Element version = (Element) versions.item(i);
history.addVersion(readVersion(version));
}
history.onFinish();
return history;
}
/**
* Returns the first node element with the given tag name
*/
private Element firstChild(final Element element, final String tagName) {
final NodeList rootElements = element.getElementsByTagName(tagName);
if (rootElements.getLength() == 0) {
return null;
}
return (Element) rootElements.item(0);
}
/**
* Reads the DOM Document
*/
private Document readDocument() {
final InputStream in = getClass().getResourceAsStream("changelog.xml");
if (in == null) {
throw new RuntimeException("changelog.xml");
}
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder;
try {
documentBuilder = factory.newDocumentBuilder();
} catch (final ParserConfigurationException e) {
throw new RuntimeException("Error creating the document builder", e);
}
try {
return documentBuilder.parse(in);
} catch (final Exception e) {
throw new RuntimeException("Error parsing the changelog.xml file", e);
}
}
/**
* Reads a string list
*/
private List<String> readItems(final Element element) {
if (element == null) {
return Collections.emptyList();
}
final NodeList items = element.getElementsByTagName("item");
final List<String> list = new ArrayList<String>();
for (int i = 0; i < items.getLength(); i++) {
final Element item = (Element) items.item(i);
final String value = readValue(item);
if (value != null) {
list.add(value);
}
}
return list;
}
/**
* Read the java migrations from the element
*/
@SuppressWarnings("unchecked")
private void readMigrations(final Version version, final Element element) {
final NodeList migrationsList = element.getElementsByTagName("migration");
for (int i = 0; i < migrationsList.getLength(); i++) {
final Element migration = (Element) migrationsList.item(i);
final String className = StringUtils.trimToNull(migration.getAttribute("class"));
Class<Migration> clazz;
try {
clazz = (Class<Migration>) Class.forName(className);
} catch (final Exception e) {
throw new IllegalArgumentException("Illegal migration class name: " + className);
}
version.addMigration(migration.getAttribute("database"), clazz);
}
}
/**
* Read all database statements from the element
*/
private void readStatements(final Version version, final Element element) {
final NodeList statementsList = element.getElementsByTagName("statements");
for (int i = 0; i < statementsList.getLength(); i++) {
final Element statements = (Element) statementsList.item(i);
version.addStatements(statements.getAttribute("database"), readItems(statements));
}
}
/**
* Reads a child node value
*/
private String readValue(final Element element, final String tagName) {
return readValue(firstChild(element, tagName));
}
/**
* Reads a node value
*/
private String readValue(Node node) {
if (node instanceof Element) {
node = node.getFirstChild();
}
return node == null ? null : StringUtils.trimToNull(node.getNodeValue());
}
/**
* Read a version from the element
*/
private Version readVersion(final Element element) {
final String label = element.getAttribute("label");
final Version version = new Version(label);
version.setDescription(readValue(element, "description"));
readStatements(version, element);
readMigrations(version, element);
version.setBugFixes(readItems(firstChild(element, "bug-fixes")));
version.setEnhancements(readItems(firstChild(element, "enhancements")));
version.setNewLibraries(readItems(firstChild(element, "new-libraries")));
version.setRemovedLibraries(readItems(firstChild(element, "removed-libraries")));
version.setNewHelps(readItems(firstChild(element, "new-helps")));
version.setRemovedHelps(readItems(firstChild(element, "removed-helps")));
version.setNewStaticFiles(readItems(firstChild(element, "new-static-files")));
version.setRemovedStaticFiles(readItems(firstChild(element, "removed-static-files")));
version.setNewTranslationKeys(readItems(firstChild(element, "new-translation-keys")));
version.setRemovedTranslationKeys(readItems(firstChild(element, "removed-translation-keys")));
version.setNewSetupKeys(readItems(firstChild(element, "new-setup-keys")));
version.setRemovedSetupKeys(readItems(firstChild(element, "removed-setup-keys")));
version.setNewCssClasses(readItems(firstChild(element, "new-css-classes")));
version.setRemovedCssClasses(readItems(firstChild(element, "removed-css-classes")));
return version;
}
}