it.grid.storm.namespace.config.xml.XMLNamespaceLoader.java Source code

Java tutorial

Introduction

Here is the source code for it.grid.storm.namespace.config.xml.XMLNamespaceLoader.java

Source

/*
 * 
 * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2010.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package it.grid.storm.namespace.config.xml;

import it.grid.storm.namespace.NamespaceValidator;
import it.grid.storm.namespace.config.NamespaceLoader;

import java.io.File;
import java.io.IOException;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Observable;
import java.util.Observer;
import java.util.Timer;
import java.util.TimerTask;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

/**
 * <p>
 * Title:
 * </p>
 * 
 * <p>
 * Description:
 * </p>
 * 
 * <p>
 * Copyright: Copyright (c) 2006
 * </p>
 * 
 * <p>
 * Company: INFN-CNAF
 * </p>
 * 
 * @author Riccardo Zappi
 * @version 1.0
 */
public class XMLNamespaceLoader extends Observable implements NamespaceLoader {

    private static Logger log = LoggerFactory.getLogger(XMLNamespaceLoader.class);

    public String filename;
    public String path;
    public int refresh; // refresh time in seconds before the configuration is
    // checked for a change in parameters!
    private XMLConfiguration config = null;
    private final int delay = 1000; // delay for 5 sec.
    private long period = -1;
    private final Timer timer = new Timer();
    private XMLReloadingStrategy xmlStrategy;
    private String namespaceFN = null;
    private boolean verbose = false;
    private final String namespaceSchemaURL;

    public boolean schemaValidity = false;

    public XMLNamespaceLoader() {

        // Build the namespaceFileName
        namespaceFN = getNamespaceFileName();
        namespaceSchemaURL = getNamespaceSchemaFileName();
        init(namespaceFN, refresh);
    }

    public XMLNamespaceLoader(int refresh) {

        if (refresh < 0) {
            this.refresh = 0;
        } else {
            this.refresh = refresh;
        }
        namespaceFN = getNamespaceFileName();
        namespaceSchemaURL = getNamespaceSchemaFileName();
        log.debug("Namespace XSD : " + namespaceSchemaURL);
        init(namespaceFN, refresh);
    }

    public XMLNamespaceLoader(String filename) {

        this.filename = filename;
        namespaceFN = getNamespaceFileName();
        namespaceSchemaURL = getNamespaceSchemaFileName();
        log.debug("Namespace XSD : " + namespaceSchemaURL);
        init(namespaceFN, refresh);
    }

    public XMLNamespaceLoader(String path, String filename) {

        this.path = path;
        this.filename = filename;
        namespaceFN = getNamespaceFileName();
        namespaceSchemaURL = getNamespaceSchemaFileName();
        log.debug("Namespace XSD : " + namespaceSchemaURL);
        init(namespaceFN, refresh);
    }

    public XMLNamespaceLoader(String path, String filename, int refresh, boolean verboseMode) {

        if (refresh < 0) {
            this.refresh = 0;
        } else {
            this.refresh = refresh;
        }
        this.path = path;
        this.filename = filename;
        namespaceFN = getNamespaceFileName();
        namespaceSchemaURL = getNamespaceSchemaFileName();
        log.debug("Namespace XSD : " + namespaceSchemaURL);
        verbose = verboseMode;
        init(namespaceFN, refresh);
    }

    public void setObserver(Observer obs) {

        addObserver(obs);
    }

    public void setNotifyManaged() {

        xmlStrategy.notifingPerformed();
        config.setReloadingStrategy(xmlStrategy);
    }

    public void setVerbosity(boolean verbosity) {

        verbose = verbosity;
    }

    /**
     * The setChanged() protected method must overridden to make it public
     */
    @Override
    public synchronized void setChanged() {

        super.setChanged();
    }

    private void init(String namespaceFileName, int refresh) {

        log.info("Reading Namespace configuration file " + namespaceFileName + " and setting refresh rate to "
                + refresh + " seconds.");

        // create reloading strategy for refresh
        xmlStrategy = new XMLReloadingStrategy();
        period = 3000; // Conversion in millisec.
        log.debug(" Refresh time is " + period + " millisec");
        xmlStrategy.setRefreshDelay(period); // Set to refresh sec the refreshing
                                             // delay.

        namespaceFN = namespaceFileName;

        // specify the properties file and set the reloading strategy for that file
        try {
            config = new XMLConfiguration();
            config.setFileName(namespaceFileName);

            // Validation of Namespace.xml
            log.debug(" ... CHECK of VALIDITY of NAMESPACE Configuration ...");

            schemaValidity = XMLNamespaceLoader.checkValidity(namespaceSchemaURL, namespaceFileName);
            if (!(schemaValidity)) {
                log.error("NAMESPACE IS NOT VALID IN RESPECT OF NAMESPACE SCHEMA! ");
                throw new ConfigurationException("XML is not valid!");
            } else {
                log.debug("Namespace is valid in respect of NAMESPACE SCHEMA.");
            }

            // This will throw a ConfigurationException if the XML document does not
            // conform to its DTD.

            config.setReloadingStrategy(xmlStrategy);

            Peeper peeper = new Peeper(this);
            timer.schedule(peeper, delay, period);

            log.debug("Timer initialized");

            config.load();
            log.debug("Namespace Configuration read!");

        } catch (ConfigurationException cex) {
            log.error("ATTENTION! Unable to load Namespace Configuration!");
            log.error(toString());
        }

    }

    private String getNamespaceFileName() {

        String configurationDir = it.grid.storm.config.Configuration.getInstance().configurationDir();
        // Looking for namespace configuration file
        String namespaceFN = it.grid.storm.config.Configuration.getInstance().getNamespaceConfigFilename();
        // Build the filename
        if (configurationDir.charAt(configurationDir.length() - 1) != File.separatorChar) {
            configurationDir += File.separatorChar;
        }
        String namespaceAbsFN = configurationDir + namespaceFN;
        // Check the namespace conf file accessibility
        File nsFile = new File(namespaceAbsFN);
        if (nsFile.exists()) {
            log.debug("Found the namespace file : " + namespaceAbsFN);
        } else {
            log.error("Unable to find the namespace file :" + namespaceAbsFN);
        }
        return namespaceAbsFN;
    }

    private String getNamespaceSchemaFileName() {

        String schemaName = it.grid.storm.config.Configuration.getInstance().getNamespaceSchemaFilename();

        if (schemaName.equals("Schema UNKNOWN!")) {

            schemaName = "namespace.xsd";
            String namespaceFN = getNamespaceFileName();
            File namespaceFile = new File(namespaceFN);
            if (namespaceFile.exists()) {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                try {
                    DocumentBuilder builder = factory.newDocumentBuilder();
                    Document doc = builder.parse(namespaceFN);
                    Element rootElement = doc.getDocumentElement();
                    String tagName = rootElement.getTagName();
                    if (tagName.equals("namespace")) {
                        if (rootElement.hasAttributes()) {
                            String value = rootElement.getAttribute("xsi:noNamespaceSchemaLocation");
                            if ((value != null) && (value.length() > 0)) {
                                schemaName = value;
                                // log.debug("namespace schema is : " + schemaName);
                            }
                        } else {
                            log.error(namespaceFN + " don't have a valid root element attributes");
                        }
                    } else {
                        log.error(namespaceFN + "  don't have a valid root element.");
                    }

                } catch (ParserConfigurationException e) {
                    log.error("Error while parsing " + namespaceFN + e.getMessage());
                } catch (SAXException e) {
                    log.error("Error while parsing " + namespaceFN + e.getMessage());
                } catch (IOException e) {
                    log.error("Error while parsing " + namespaceFN + e.getMessage());
                }
            }
        }

        return schemaName;

    }

    public Configuration getConfiguration() {

        return config;
    }

    private static boolean checkValidity(String namespaceSchemaURL, String filename) {

        NamespaceValidator validator = new NamespaceValidator();
        boolean valid = validator.validateSchema(namespaceSchemaURL, filename);
        return valid;
    }

    /**
     * 
     * <p>
     * Title:
     * </p>
     * 
     * <p>
     * Description:
     * </p>
     * 
     * <p>
     * Copyright: Copyright (c) 2006
     * </p>
     * 
     * <p>
     * Company: INFN-CNAF and ICTP/eGrid project
     * </p>
     * 
     * @author Riccardo Zappi
     * @version 1.0
     */
    private class Peeper extends TimerTask {

        private XMLReloadingStrategy reloadingStrategy;

        private boolean signal;
        private final XMLNamespaceLoader observed;

        public Peeper(XMLNamespaceLoader obs) {

            observed = obs;
        }

        @Override
        public void run() {

            // log.debug(" The glange of peeper..");
            reloadingStrategy = (XMLReloadingStrategy) config.getReloadingStrategy();
            if (verbose) {
                File xmlFile = reloadingStrategy.getConfigurationFile();
                log.debug(" Peeper glance on XMLReloadingStrategy bound with FILE : " + xmlFile.getName());
                long lastFileModified = xmlFile.lastModified();
                Date dateFile = new Date(lastFileModified);
                long lastFileModifiedReload = reloadingStrategy.getLastReload();
                reloadingStrategy.reloadingPerformed();
                Date dateReload = new Date(lastFileModifiedReload);
                if (lastFileModifiedReload < lastFileModified) {
                    log.debug("RELOAD NEEDED!");
                    Format formatter = new SimpleDateFormat("HH.mm.ss  dd.MM.yyyy");
                    log.debug(" FILE XML Last Modified : " + formatter.format(dateFile));
                    log.debug(" FILE XML Last RELOAD : " + formatter.format(dateReload));
                }
            }
            boolean changed = reloadingStrategy.reloadingRequired();
            if (changed) {
                log.debug(" NAMESPACE CONFIGURATION is changed ! ");
                log.debug(" ... CHECK of VALIDITY of NAMESPACE Configuration ...");
                boolean valid = XMLNamespaceLoader.checkValidity(namespaceSchemaURL, namespaceFN);
                if (!valid) {
                    log.debug(" Namespace configuration is not reloaded.. Please rectify the error.");
                    schemaValidity = false;
                    reloadingStrategy.notifingPerformed();
                    reloadingStrategy.reloadingPerformed();
                } else {
                    log.debug(" ... NAMESPACE Configuration is VALID in respect of Schema Grammar.");
                    log.debug(" ----> RELOADING  ");

                    schemaValidity = true;

                    boolean forceReloading = it.grid.storm.config.Configuration.getInstance()
                            .getNamespaceAutomaticReloading();
                    if (forceReloading) {
                        config.reload();
                    } else {
                        log.debug(
                                " ----> RELOAD of namespace don't be executed because NO AUTOMATIC RELOAD is configured.");
                    }
                    reloadingStrategy.reloadingPerformed();
                }
            }

            signal = reloadingStrategy.notifingRequired();
            if ((signal)) {
                observed.setChanged();
                observed.notifyObservers(" MSG : Namespace is changed!");
                reloadingStrategy.notifingPerformed();
            }

        }

    }

}