fll.xml.XMLUtils.java Source code

Java tutorial

Introduction

Here is the source code for fll.xml.XMLUtils.java

Source

/*
 * Copyright (c) 2000-2002 INSciTE.  All rights reserved
 * INSciTE is on the web at: http://www.hightechkids.org
 * This code is released under GPL; see LICENSE.txt for details.
 */
package fll.xml;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.CodeSource;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

import net.mtu.eggplant.xml.NodelistElementCollectionAdapter;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.custommonkey.xmlunit.Diff;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import fll.util.LogUtils;

/**
 * XML utilities for FLL.
 */
@SuppressFBWarnings(value = {
        "NM_SAME_SIMPLE_NAME_AS_SUPERCLASS" }, justification = "Intentionally shadowing parent class")
public final class XMLUtils extends net.mtu.eggplant.xml.XMLUtils {

    private static final Logger LOGGER = LogUtils.getLogger();

    private XMLUtils() {
    }

    /**
     * Find a subjective category by name.
     * 
     * @param challengeDocument the document to look in
     * @param name the name to look for
     * @return the element or null if one is not found
     */
    public static Element getSubjectiveCategoryByName(final Document challengeDocument, final String name) {
        for (final Element categoryElement : new NodelistElementCollectionAdapter(
                challengeDocument.getDocumentElement().getElementsByTagName("subjectiveCategory"))) {
            final String categoryName = categoryElement.getAttribute("name");
            if (categoryName.equals(name)) {
                return categoryElement;
            }
        }
        return null;
    }

    /**
     * Check if an element describes an enumerated goal or not.
     * 
     * @param element the goal element
     * @return if the element represents an enumerated goal
     */
    public static boolean isEnumeratedGoal(final Element element) {
        if (!"goal".equals(element.getNodeName())) {
            // not a goal element
            return false;
        }

        final Iterator<Element> values = new NodelistElementCollectionAdapter(element.getElementsByTagName("value"))
                .iterator();
        return values.hasNext();
    }

    /**
     * Check if an element describes a computed goal or not.
     * 
     * @param element the goal element
     * @return if the element represents a computed goal
     */
    public static boolean isComputedGoal(final Element element) {
        return "computedGoal".equals(element.getNodeName());
    }

    /**
     * Get the winner criteria for a particular element.
     */
    public static WinnerType getWinnerCriteria(final Element element) {
        if (element.hasAttribute("winner")) {
            final String str = element.getAttribute("winner");
            final String sortStr;
            if (!str.isEmpty()) {
                sortStr = str.toUpperCase();
            } else {
                sortStr = "HIGH";
            }
            return Enum.valueOf(WinnerType.class, sortStr);
        } else {
            return WinnerType.HIGH;
        }
    }

    /**
     * Get the score type for a particular element.
     */
    public static ScoreType getScoreType(final Element element) {
        if (element.hasAttribute("scoreType")) {
            final String str = element.getAttribute("scoreType");
            final String sortStr;
            if (!str.isEmpty()) {
                sortStr = str.toUpperCase();
            } else {
                sortStr = "INTEGER";
            }
            return Enum.valueOf(ScoreType.class, sortStr);
        } else {
            return ScoreType.INTEGER;
        }
    }

    /**
     * @see #getDoubleAttributeValue(Element, String)
     */
    public static String getStringAttributeValue(final Element element, final String attributeName) {
        if (null == element) {
            return null;
        }
        final String str = element.getAttribute(attributeName);
        return str;
    }

    /**
     * @see #getDoubleAttributeValue(Element, String)
     */
    @SuppressFBWarnings(value = {
            "NP_BOOLEAN_RETURN_NULL" }, justification = "Need to return Null so that we can determine when there is no score")
    public static Boolean getBooleanAttributeValue(final Element element, final String attributeName) {
        if (null == element) {
            return null;
        }
        final String str = element.getAttribute(attributeName);
        if (str.isEmpty()) {
            return null;
        } else {
            return Boolean.valueOf(str);
        }
    }

    /**
     * Get a double value from an attribute.
     * 
     * @param element the element to get the attribute from, may be null
     * @param attributeName the attribute name to get
     * @return the value, null if element is null or the attribute value is null
     *         or empty
     */
    public static Double getDoubleAttributeValue(final Element element, final String attributeName) {
        if (null == element) {
            return null;
        }
        final String str = element.getAttribute(attributeName);
        if (str.isEmpty()) {
            return null;
        } else {
            return Double.valueOf(str);
        }
    }

    /**
     * Compare two documents and check if they are the same or not.
     * 
     * @param controlDoc
     * @param testDoc
     * @return true if the documents have the same elements and attributes,
     *         reguardless of order
     */
    public static boolean compareDocuments(final Document controlDoc, final Document testDoc) {
        final Diff xmldiff = new Diff(controlDoc, testDoc);
        return xmldiff.similar();
    }

    public static List<String> getSubjectiveCategoryNames(final Document challengeDocument) {
        final List<String> subjectiveCategories = new LinkedList<String>();
        for (final Element categoryElement : new NodelistElementCollectionAdapter(
                challengeDocument.getDocumentElement().getElementsByTagName("subjectiveCategory"))) {
            final String categoryName = categoryElement.getAttribute("name");
            subjectiveCategories.add(categoryName);
        }
        return subjectiveCategories;
    }

    public static boolean isValidCategoryName(final Document challengeDocument, final String name) {
        return getSubjectiveCategoryNames(challengeDocument).contains(name);
    }

    /**
     * Get all challenge descriptors build into the software.
     */
    public static Collection<URL> getAllKnownChallengeDescriptorURLs() {
        final String baseDir = "fll/resources/challenge-descriptors/";

        final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        final URL directory = classLoader.getResource(baseDir);
        if (null == directory) {
            LOGGER.warn("base dir for challenge descriptors not found");
            return Collections.emptyList();
        }

        final Collection<URL> urls = new LinkedList<URL>();
        if ("file".equals(directory.getProtocol())) {
            try {
                final URI uri = directory.toURI();
                final File fileDir = new File(uri);
                final File[] files = fileDir.listFiles();
                if (null != files) {
                    for (final File file : files) {
                        if (file.getName().endsWith(".xml")) {
                            try {
                                final URL fileUrl = file.toURI().toURL();
                                urls.add(fileUrl);
                            } catch (final MalformedURLException e) {
                                LOGGER.error("Unable to convert file to URL: " + file.getAbsolutePath(), e);
                            }
                        }
                    }
                }
            } catch (final URISyntaxException e) {
                LOGGER.error("Unable to convert URL to URI: " + e.getMessage(), e);
            }
        } else if (directory.getProtocol().equals("jar")) {
            final CodeSource src = XMLUtils.class.getProtectionDomain().getCodeSource();
            if (null != src) {
                final URL jar = src.getLocation();

                JarInputStream zip = null;
                try {
                    zip = new JarInputStream(jar.openStream());

                    JarEntry ze = null;
                    while ((ze = zip.getNextJarEntry()) != null) {
                        final String entryName = ze.getName();
                        if (entryName.startsWith(baseDir) && entryName.endsWith(".xml")) {
                            // add 1 to baseDir to skip past the path separator
                            final String challengeName = entryName.substring(baseDir.length());

                            // check that the file really exists and turn it into a URL
                            final URL challengeUrl = classLoader.getResource(baseDir + challengeName);
                            if (null != challengeUrl) {
                                urls.add(challengeUrl);
                            } else {
                                // TODO could write the resource out to a temporary file if
                                // needed
                                // then mark the file as delete on exit
                                LOGGER.warn("URL doesn't exist for " + baseDir + challengeName + " entry: "
                                        + entryName);
                            }
                        }
                    }

                    zip.close();
                } catch (final IOException e) {
                    LOGGER.error("Error reading jar file at: " + jar.toString(), e);
                } finally {
                    IOUtils.closeQuietly(zip);
                }

            } else {
                LOGGER.warn("Null code source in protection domain, cannot get challenge descriptors");
            }
        } else {
            throw new UnsupportedOperationException("Cannot list files for URL " + directory);

        }

        return urls;

    }
}