net.sf.ginp.setup.SetupManagerImpl.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.ginp.setup.SetupManagerImpl.java

Source

/*
 *  ginp - Java Web Application for Viewing Photo Collections
 *  Copyright (C) 2004  Douglas John Culnane <doug@culnane.net>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA  02110-1301  USA
 */
package net.sf.ginp.setup;

import com.thoughtworks.xstream.XStream;

import net.sf.ginp.config.Configuration;
import net.sf.ginp.setup.data.DirectoryPref;
import net.sf.ginp.setup.data.SetupVisit;
import net.sf.ginp.util.GinpUtil;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;

import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import org.dom4j.tree.DefaultDocumentType;

import org.xml.sax.InputSource;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;

import java.net.MalformedURLException;
import java.net.URL;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

import javax.xml.transform.TransformerException;

/**
 * Implementation of Setup Manager.
 * @author Justin Sher
 * @see net.sf.ginp.setup.SetupManager
 **/
public class SetupManagerImpl implements SetupManager {
    private static final String TROUBLE_PARSING = "troubleParsing";

    /**
     *  apache Commons Logger specific to this class.
     */
    private Log log = LogFactory.getLog(SetupManagerImpl.class);

    /**
     * @param configUrl the URL identifying the config to check
     * @return true or false
     * @see net.sf.ginp.setup.SetupManager#configExists(URL configUrl)
     */
    public final boolean configExists(final URL configUrl) {
        //String file= this.getConfiguration(configUrl);
        //if (file==null) { return false; }
        File fileTest = new File(GinpUtil.getConfigFileRealPath());

        if (!fileTest.canRead()) {
            return false;
        }

        return true;
    }

    /**
     * @see net.sf.ginp.setup.SetupManager#deleteConfiguration(java.net.URL)
     */
    public final void deleteConfiguration(final URL configUrl) {
        Preferences preferences = Preferences.userNodeForPackage(SetupManagerImpl.class);
        preferences.remove(configUrl.toExternalForm());

        try {
            preferences.flush();
        } catch (BackingStoreException e) {
            log.error("No big deal if we couldn't delete", e);
        }
    }

    /**
     * @throws SetupException
     * @see net.sf.ginp.setup.SetupManager#createConfiguration(
     * java.net.URL, java.lang.String)
     */
    public final void createConfiguration(final URL configUrl, final String configuration) throws SetupException {
        storeConfig(configUrl, configuration);
    }

    /**
     * @param configUrl
     * @param configuration
     * @return the saves prefs object
     */
    private Preferences storeConfig(final URL configUrl, final String configuration) {
        Preferences preferences = Preferences.userNodeForPackage(SetupManagerImpl.class);
        preferences.put(configUrl.toExternalForm(), configuration);

        return preferences;
    }

    /**
     * @see net.sf.ginp.setup.SetupManager#validConfigLoc(java.lang.String)
     */
    public final Boolean validConfigLoc(final String path) {
        File pathDir = new File(path);

        if (!pathDir.isDirectory()) {
            return new Boolean(false);
        }

        if (!pathDir.canWrite()) {
            return new Boolean(false);
        }

        if (!pathDir.canRead()) {
            return new Boolean(false);
        }

        return new Boolean(true);
    }

    /**
     * @throws SetupException if there's a problem reading the doc
     * note: don't be fooled, we can't report the path of the
     *       offending document because it is supplied as a Stream.
     * @throws IOException
     * @see net.sf.ginp.setup.SetupManager#testValidConfig(java.io.InputStream)
     */
    public final Document testValidConfig(final InputStream stream) throws SetupException, IOException {
        String reader = GinpUtil.readBufferIntoMemory(stream);

        try {
            return validateConfig(new ByteArrayInputStream(reader.getBytes()));
        } catch (DocumentException d) {
            SAXReader read = new SAXReader(false);

            try {
                InputSource source = new InputSource();
                source.setCharacterStream(new StringReader(reader));

                String ginpFile = this.getClass().getResource("/net/sf/ginp/config/ginp.dtd").toExternalForm();
                ginpFile = ginpFile.substring(0, ginpFile.lastIndexOf("/") + 1);
                source.setSystemId(ginpFile);
                source.setPublicId("ginp.dtd");

                Document document = read.read(source);
                List list = document.selectNodes("/ginp/collection/users");
                list.addAll(document.selectNodes("/ginp/collection/admins"));

                Iterator iter = list.iterator();

                while (iter.hasNext()) {
                    Element e = (Element) iter.next();
                    String value = e.getText();
                    String[] users = value.split(",");

                    for (int x = 0; x < users.length; x++) {
                        if (users[x].length() == 0) {
                            continue;
                        }

                        Element element = e.addElement("username");
                        element.setText(users[x].trim());
                    }

                    e.setText("");
                }

                try {
                    return validateConfig(new ByteArrayInputStream(document.asXML().getBytes()));
                } catch (DocumentException e) {
                    //Some XML parsers don't support validation
                    if (e.getMessage().indexOf("not supported") >= 0) {
                        log.warn("Validation Not Supported by your XML parser", e);

                        return document;
                    } else {
                        log.error("Validation Error:", e);
                    }

                    throw e;
                }
            } catch (DocumentException e) {
                log.error("throwing new SetupException", e);
                throw new SetupException(GinpUtil.message(TROUBLE_PARSING), d);
            }
        }
    }

    /**
     * @param stream
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    private Document validateConfig(final InputStream stream) throws IOException, DocumentException {
        SAXReader read = new SAXReader(true);
        InputSource source = new InputSource();
        StringReader stringRead = new StringReader(GinpUtil.readBufferIntoMemory(stream));
        String ginpFile = this.getClass().getResource("/net/sf/ginp/config/ginp.dtd").toExternalForm();
        ginpFile = ginpFile.substring(0, ginpFile.lastIndexOf("/") + 1);
        source.setSystemId(ginpFile);
        source.setPublicId("ginp.dtd");
        source.setCharacterStream(stringRead);

        return read.read(source);
    }

    /**
     * @see net.sf.ginp.setup.SetupManager#validPicturesLoc(java.lang.String)
     */
    public final Boolean validPicturesLoc(final String path) {
        File pathDir = new File(path);

        if (!pathDir.isDirectory()) {
            return new Boolean(false);
        }

        if (!pathDir.canWrite()) {
            return new Boolean(false);
        }

        if (!pathDir.canRead()) {
            return new Boolean(false);
        }

        return new Boolean(true);
    }

    /**
     * @throws SetupException
     * @see net.sf.ginp.setup.SetupManager#writeConfigFromVisit(
     * *net.sf.ginp.setup.data.SetupVisit)
     */
    public final Document writeConfigFromVisit(final SetupVisit visit) throws SetupException {
        try {
            Document outputDocument = getConfigFromSetupVisit(visit);

            if (!writeConfig(visit, outputDocument)) {
                log.warn("Config not written.");
            }

            return outputDocument;
        } catch (Exception e) {
            throw new SetupException(e);
        }
    }

    /**
     * @param visit
     * @param outputDocument
     * @throws UnsupportedEncodingException
     * @throws IOException generally, and specifically
     *  FileNotFoundException and UnsupportedEncodingException
     */
    public final boolean writeConfig(final SetupVisit visit, final Document outputDocument) throws IOException {
        FileOutputStream outputStream = null;
        XMLWriter write = null;
        boolean success = false;

        try {
            String confFileLocation = Configuration.getConfigfilelocation();

            if (confFileLocation == null) {
                log.warn("Configuration.getConfigfilelocation() is NULL!");
            }

            // make sure directory exists and be verbose about this to log.
            File configDir = new File(Configuration.getConfigfilelocationPath());

            if (!configDir.exists()) {
                if (configDir.mkdirs()) {
                    log.info("Config directory created at: " + configDir.getAbsolutePath());
                } else {
                    log.error("Can not create config directory at: " + configDir.getAbsolutePath());
                }
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("Config dir exists at:" + configDir.getAbsolutePath());
                }
            }

            // warn about overwrite
            File configFile = new File(confFileLocation);

            if (configFile.exists()) {
                log.warn("Overwriting config file at: " + configFile.getAbsolutePath());
            }

            outputStream = new FileOutputStream(configFile, false);

            OutputFormat format = OutputFormat.createPrettyPrint();
            write = new XMLWriter(outputStream, format);
            write.write(outputDocument);
            success = configFile.exists();
        } catch (Exception ex) {
            log.error("Error writing config.", ex);
        } finally {
            if (write != null) {
                write.flush();
                write.close();
            }

            if (outputStream != null) {
                outputStream.flush();
                outputStream.close();
            }
        }

        return success;
    }

    /**
     * @param visit
     * @return
     * @throws DocumentException
     * @throws TransformerException
     */
    private Document getConfigFromSetupVisit(final SetupVisit visit)
            throws DocumentException, TransformerException {
        XStream stream = new XStream();
        String visitXML = stream.toXML(visit);
        SAXReader read = new SAXReader();
        Document visitDoc = read.read(new StringReader(visitXML));
        Document outputDocument = GinpUtil.transform("/net/sf/ginp/setup/visitToConfig.xsl", visitDoc);

        // necessary because the xsl transform ignores the XSL:output tag
        outputDocument.setDocType(new DefaultDocumentType("ginp", "-//GINP//DTD ginp XML//EN", "ginp.dtd"));

        return outputDocument;
    }

    /**
     * @throws TransformerException
     * @throws DocumentException
     * @see net.sf.ginp.setup.SetupManager#finalPageTransform(
     * net.sf.ginp.setup.data.SetupVisit)
     */
    public final String finalPageTransform(final SetupVisit config) throws TransformerException, DocumentException {
        XStream stream = new XStream();
        String visitXML = stream.toXML(config);
        SAXReader reader = new SAXReader();
        Document setupDoc = reader.read(new StringReader(visitXML));
        Document i18nDoc = reader.read(this.getClass()
                .getResourceAsStream("/net/sf/ginp/setup/" + GinpUtil.message("finalPageI18n").trim()));
        setupDoc.getRootElement().add(i18nDoc.getRootElement());

        Document htmlOut = GinpUtil.transform("/net/sf/ginp/setup/finalPage.xsl", setupDoc);

        return htmlOut.asXML();
    }

    /**
     * @see net.sf.ginp.setup.SetupManager#getCommandLineForSetupVisit(
     * net.sf.ginp.setup.data.SetupVisit)
     */
    public final String getCommandLineForSetupVisit(final SetupVisit visit) {
        String javaCommand = "--url " + visit.getSetupURL() + " --config-path "
                + Configuration.getConfigfilelocation() + " --photo-path " + visit.getGinpPhotosPath()
                + " --admin-password " + visit.getAdminPassword() + " --guest-password " + visit.getGuestPassword();
        Iterator iterator = visit.getDirectoryPrefs().iterator();

        while (iterator.hasNext()) {
            DirectoryPref dirPref = (DirectoryPref) iterator.next();

            if (dirPref.getType().equals(DirectoryPref.ADMIN_ONLY)) {
                javaCommand += (" --admin " + dirPref.getRootDir());
            } else if (dirPref.getType().equals(DirectoryPref.PUBLIC)) {
                javaCommand += (" --public " + dirPref.getRootDir());
            } else if (dirPref.getType().equals(DirectoryPref.PRIVATE)) {
                javaCommand += (" --private " + dirPref.getRootDir());
            }
        }

        return javaCommand;
    }

    /**
     * @see net.sf.ginp.setup.SetupManager#getSetupVisitForCommandLine(
     * java.lang.String[])
     */
    public final SetupVisit getSetupVisitForCommandLine(final String[] argv)
            throws DocumentException, TransformerException {
        SetupVisit visit = new SetupVisit();

        for (int x = 0; x < argv.length; x++) {
            String command = argv[x];

            if (command.equals("--url")) {
                visit.setSetupURL(argv[x++]);
            } else if (command.equals("--photo-path")) {
                visit.setGinpPhotosPath(argv[x++]);
            } else if (command.equals("--admin-password")) {
                visit.setAdminPassword(argv[x++]);
            } else if (command.equals("--guest-password")) {
                visit.setGuestPassword(argv[x++]);
            } else if (command.equals("--private")) {
                DirectoryPref privDir = new DirectoryPref();
                privDir.setRootDir(privDir.getName());
                privDir.setType(DirectoryPref.PRIVATE);
                privDir.setUserVariables();
                visit.addCollection(privDir);
            } else if (command.equals("--admin")) {
                DirectoryPref privDir = new DirectoryPref();
                privDir.setRootDir(privDir.getName());
                privDir.setType(DirectoryPref.ADMIN_ONLY);
                privDir.setUserVariables();
                visit.addCollection(privDir);
            } else if (command.equals("--public")) {
                DirectoryPref privDir = new DirectoryPref();
                privDir.setRootDir(privDir.getName());
                privDir.setType(DirectoryPref.PUBLIC);
                privDir.setUserVariables();
                visit.addCollection(privDir);
            }
        }

        //Check for Sanity
        this.getConfigFromSetupVisit(visit);

        return visit;
    }

    /**
     * @param sampleConfig
     * @return
     * @see net.sf.ginp.setup.SetupManager#getDirectoriesInPictureDirectory(
     * net.sf.ginp.setup.data.SetupVisit)
     */
    public final List getDirectoriesInPictureDirectory(final SetupVisit sampleConfig) {
        File dir = new File(sampleConfig.getGinpPhotosPath());
        String[] strings = dir.list();
        ArrayList directories = new ArrayList();

        for (int x = 0; x < strings.length; x++) {
            String path = sampleConfig.getGinpPhotosPath() + System.getProperty("file.separator") + strings[x];
            File file = new File(path);

            if (!file.exists()) {
                path = sampleConfig.getGinpPhotosPath() + strings[x];
                file = new File(path);
            }

            if (file.canRead() && file.canWrite() && file.isDirectory()) {
                directories.add(file);
            }
        }

        return directories;
    }

    /**
     * Sets the configuration in the preferences from the
     * visit's path and url.
     * @throws SetupException
     * @throws MalformedURLException
     * @see net.sf.ginp.setup.SetupManager#setConfiguration(
     * net.sf.ginp.setup.data.SetupVisit)
     */
    public final void setConfiguration(final SetupVisit visit) throws MalformedURLException, SetupException {
        String uri = visit.getSetupURL();
        uri = uri.substring(0, uri.lastIndexOf('/'));
        deleteConfiguration(new URL(uri));
        createConfiguration(new URL(uri), Configuration.getConfigfilelocation());
    }
}