All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.vfny.geoserver.global.GeoserverDataDirectory Maven / Gradle / Ivy

There is a newer version: 1.7.0
Show newest version
/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
 * This code is licensed under the GPL 2.0 license, availible at the root
 * application directory.
 */
package org.vfny.geoserver.global;

import org.geoserver.platform.GeoServerResourceLoader;
import org.geotools.feature.FeatureType;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org.  All rights reserved.
 * This code is licensed under the GPL 2.0 license, availible at the root
 * application directory.
 */
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.NoSuchElementException;
import java.util.logging.Logger;
import javax.servlet.ServletContext;


/**
 * This class allows for abstracting the location of the Geoserver Data directory. Some people call this "GEOSERVER_HOME".
 *
 * Inside this directory should be two more directories: a. "WEB-INF/" Inside this is a catalog.xml b. "data/" Inside this is a set of other
 * directories.
 *
 * For the exact content of these directories, see any existing geoserver install's server/geoserver directory.
 *
 * In order to find the geoserver data directory the following steps take place:
 *
 * 1. search for the "GEOSERVER_DATA_DIR" system property. this will most likely have come from "java -DGEOSERVER_DATA_DIR=..." or from you
 * web container 2. search for a "GEOSERVER_DATA_DIR" in the web.xml document  GEOSERVER_DATA_DIR
 * ...  3. It defaults to the old behavior - ie. the application root - usually
 * "server/geoserver" in your .WAR.
 *
 *
 * NOTE: a set method is currently undefined because you should either modify you web.xml or set the environment variable and re-start
 * geoserver.
 *
 * @author dblasby
 *
 */
public class GeoserverDataDirectory {
    // caches the dataDir
    private static GeoServerResourceLoader loader;
    private static Data catalog;
    private static ApplicationContext appContext;
    private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.vfny.geoserver.global");
    private static boolean isTrueDataDir = false;

    /**
     * See the class documentation for more details. 1. search for the "GEOSERVER_DATA_DIR" system property. 2. search for a
     * "GEOSERVER_DATA_DIR" in the web.xml document 3. It defaults to the old behavior - ie. the application root - usually
     * "server/geoserver" in your .WAR.
     *
     * @return location of the geoserver data dir
     */
    static public File getGeoserverDataDirectory() {
        if (loader != null) {
            return loader.getBaseDirectory();
        } else {
            return null;
        }
    }
    
    /**
     * Locate feature type directory name using the FeatureType as a key into the catalog 
     * @see Data#getFeatureTypeInfo(String) 
     * @param name
     *            String The FeatureTypeInfo Name

     * @return the feature type dir name, or null if not found (either the feature type or the directory)
     *
     * @throws NoSuchElementException
     */
    static public String findFeatureTypeDirName(FeatureType featureType) {
        String name = featureType.getTypeName();
        URI namespace = featureType.getNamespace();
        FeatureTypeInfo ftInfo = null;
        Data data = getCatalog();
        if(namespace != null) {
            NameSpaceInfo nsInfo = data.getNameSpaceFromURI(namespace.toString());
            if(nsInfo != null)
                ftInfo = data.getFeatureTypeInfo(nsInfo.getPrefix() + ":" + name);
        }
        if(ftInfo == null) 
            ftInfo = data.getFeatureTypeInfo(name);
        if(ftInfo == null)
            return null;
        return ftInfo.getDirName();
    }

    /**
     * Returns whether GeoServer is using a true data directory, loaded from outside the webapp, or if its defaulting to the webapp embedded
     * dataDir. We're in the process of moving away from storing anything in the webapp but are keeping this to ease the transition.
     *
     * @return true if the directory being used for loading is not embedded in the webapp.
     */
    static public boolean isTrueDataDir() {
        return isTrueDataDir;
    }

    /**
     * Utility method to find the approriate sub-data dir config. This is a helper for the fact that we're transitioning away from the
     * WEB-INF type of hacky storage, but during the transition things can be in both places. So this method takes the root file, the
     * dataDir, and a name of a directory that is stored in the data dir, and checks for it in the data/ dir (the old way), and directly in
     * the dir (the new way)
     *
     * @param root
     *            Generally the Data Directory, the directory to try to find the config file in.
     * @param dirName
     *            The name of the directory to find in the data Dir.
     * @return The proper config directory.
     * @throws ConfigurationException
     *             if the directory could not be found at all.
     */
    public static File findConfigDir(File root, String dirName)
        throws ConfigurationException {
        File configDir;

        try {
            configDir = loader.find(dirName);
        } catch (IOException e) {
            throw new ConfigurationException(e);
        }

        return configDir;
    }

    /**
     * Same as {@link #findConfigDir(File, String), but it will create the configuration directory
     * if missing (as a top level directory inside the Geoserver data directory)
     * @param dirName
     * @return
     * @throws ConfigurationException
     */
    public static File findCreateConfigDir(String dirName)
        throws ConfigurationException {
        File configDir = findConfigDir(getGeoserverDataDirectory(), dirName);

        if ((configDir == null) || !configDir.exists()) {
            configDir = new File(getGeoserverDataDirectory(), dirName);
            configDir.mkdir();

            if (configDir.exists()) {
                return configDir;
            }
        }

        return configDir;
    }

    /**
     * Given a url, tries to interpret it as a file into the data directory, or as an absolute
     * location, and returns the actual absolute location of the File
     * @param path
     * @return
     */
    public static File findDataFile(URL url) {
        return findDataFile(url.getFile());
    }

    /**
     * Given a path, tries to interpret it as a file into the data directory, or as an absolute
     * location, and returns the actual absolute location of the File
     * @param path
     * @return
     */
    public static File findDataFile(String path) {
        File baseDir = GeoserverDataDirectory.getGeoserverDataDirectory();

        // do we ever have something that is not a file system reference?
        if (path.startsWith("file:")) {
            path = path.substring(5); // remove 'file:' prefix

            File f = new File(path);

            // if it's an absolute path, use it as such, 
            // otherwise try to map it inside the data dir
            if (f.isAbsolute() || f.exists()) {
                return f;
            } else {
                return new File(baseDir, path);
            }
        } else {
            return new File(path);
        }
    }

    /**
     * Utility method fofinding a config file under the data directory.
     *
     * @param file
     *            Path to file, absolute or relative to data dir.
     *
     * @return The file handle, or null.
     */
    public static File findConfigFile(String file) throws ConfigurationException {
        try {
            return loader.find(file);
        } catch (IOException e) {
            throw new ConfigurationException(e);
        }
    }

    /**
     * Initializes the data directory lookup service.
     * @param servContext
     */
    public static void init(WebApplicationContext context) {
        ServletContext servContext = context.getServletContext();
        
        // Oh, this is really sad. We need a reference to Data in order to
        // resolve feature type dirs, but gathering it here triggers the loading
        // of Geoserver (on whose Catalog depends on), which depends on having 
        // DataDirectory and Config initialized, but this is not possible here...
        // So we keep a reference to context in order to resolve Data later
        appContext = context;

        // This was once in the GetGeoserverDataDirectory method, I've moved
        // here so that servlet
        // context is not needed as a parameter anymore.
        // caching this, so we're not looking up everytime, and more
        // importantly, so we can actually look up this stuff without
        // having to pass in a ServletContext. This should be fine, since we
        // don't allow a set method, as we recommend restarting GeoServer,
        // so it should always get a ServletContext in the startup routine.
        // If this assumption can't be made, then we can't allow data_dir
        // _and_ webapp options with relative data/ links -ch
        if (loader == null) {
            //get the loader from the context
            loader = (GeoServerResourceLoader) context.getBean("resourceLoader");

            File dataDir = null;

            // see if there's a system property
            try {
                String prop = System.getProperty("GEOSERVER_DATA_DIR");

                if ((prop != null) && !prop.equals("")) {
                    // its defined!!
                    isTrueDataDir = true;
                    dataDir = new File(prop);
                    loader.setBaseDirectory(dataDir);
                    loader.addSearchLocation(new File(dataDir, "data"));
                    loader.addSearchLocation(new File(dataDir, "WEB-INF"));

                    LOGGER.severe("\n----------------------------------\n- GEOSERVER_DATA_DIR: "
                        + dataDir.getAbsolutePath() + "\n----------------------------------");

                    return;
                }
            } catch (SecurityException e) {
                // gobble exception
                LOGGER.fine("Security exception occurred. This is usually not a big deal.\n"
                    + e.getMessage());
            }

            // try the webxml
            String loc = servContext.getInitParameter("GEOSERVER_DATA_DIR");

            if (loc != null) {
                // its defined!!
                isTrueDataDir = true;
                dataDir = new File(loc);
                loader.setBaseDirectory(dataDir);
                loader.addSearchLocation(new File(dataDir, "data"));
                loader.addSearchLocation(new File(dataDir, "WEB-INF"));
                LOGGER.severe("\n----------------------------------\n- GEOSERVER_DATA_DIR: "
                    + dataDir.getAbsolutePath() + "\n----------------------------------");

                return;
            }

            // return default
            isTrueDataDir = false;

            String rootDir = servContext.getRealPath("/data");
            dataDir = new File(rootDir);

            //set the base directory of hte loader
            loader.setBaseDirectory(dataDir);
            loader.addSearchLocation(new File(dataDir, "data"));
            loader.addSearchLocation(new File(dataDir, "WEB-INF"));
            LOGGER.severe("\n----------------------------------\n- GEOSERVER_DATA_DIR: "
                + dataDir.getAbsolutePath() + "\n----------------------------------");
            loader.addSearchLocation(new File(servContext.getRealPath("WEB-INF")));
            loader.addSearchLocation(new File(servContext.getRealPath("data")));
        }
    }

    /**
     * Signals the data directory to throw away all global state.
     * 

* This code should *not* be called by any non-test GeoServer code. *

*/ public static void destroy() { loader = null; isTrueDataDir = false; } private static Data getCatalog() { if(catalog == null) { catalog = (Data) appContext.getBean("data"); } return catalog; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy