Java tutorial
/* * 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()); } }