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

com.cloudhopper.datastore.DataStoreManager Maven / Gradle / Ivy

The newest version!
package com.cloudhopper.datastore;

/*
 * #%L
 * ch-datastore
 * %%
 * Copyright (C) 2012 Cloudhopper by Twitter
 * %%
 * 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.
 * #L%
 */

import com.cloudhopper.commons.util.URL;
import com.cloudhopper.commons.util.URLParser;
import com.cloudhopper.commons.xbean.XmlBean;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author joelauer
 */
public class DataStoreManager {
    private final static Logger logger = LoggerFactory.getLogger(DataStoreManager.class);

    static private ConcurrentHashMap> providers = new ConcurrentHashMap>();

    static {
        providers.put("tokyo", com.cloudhopper.datastore.tokyo.TokyoDataStore.class);
        providers.put("kyoto", com.cloudhopper.datastore.kyoto.KyotoDataStore.class);
        providers.put("leveldb", com.cloudhopper.datastore.leveldb.LevelDbDataStore.class);
    }

    /**
     * Checks if the provider is registered as a DataStore. This method is
     * thread-safe.
     * @param provider The provider name to check if registered such as "tokyo"
     * @return True if registered or false if not registered.
     */
    static public boolean isProviderRegistered(String provider) {
        return providers.containsKey(provider);
    }

    /**
     * Registers a new DataStore provider.  Will replace a current provider
     * if one is already registered.  This method is thread-safe.
     * @param provider The name of the provider to register such as "tokyo"
     * @param clazz The DataStore class to register
     */
    static public void registerProvider(String provider, Class clazz) {
        providers.put(provider, clazz);
    }

    /**
     * Creates a new DataStore based on a URL.  A DataStore URL is in the form:
     * [provider]://[name]?[parameters...].  The "provider" must be registered
     * and determines which underlying implementation will be instantiated.
     * The parameters are dynamic and will execute bean-named methods on the
     * underlying class.
     * @param url The URL of the DataStore to create
     * @return The new DataStore
     * @throws DataStoreFatalException Thrown if there is an error while
     *      creating the new DataStore.
     */
    static public DataStore create(String url) throws DataStoreFatalException {
        //
        // parse data store url
        //
        URL parsedUrl = null;

        try {
            parsedUrl = URLParser.parse(url);
        } catch (MalformedURLException e) {
            throw new DataStoreFatalException("Unable to parse URL: " + url, e);
        }

        //
        // the "host" is the data store "name"
        //
        String dataStoreName = parsedUrl.getHost();
        if (dataStoreName == null) {
            throw new DataStoreFatalException("The host portion of the DataStore URL needs to include the name of the DataStore");
        }

        //
        // convert url protocol to the underlying implementation
        //
        //DataStoreProtocol protocol = DataStoreProtocol.parseProtocol(parsedUrl.getProtocol());
        Class dataStoreClass = providers.get(parsedUrl.getProtocol());

        if (dataStoreClass == null) {
            throw new DataStoreFatalException("Unable to load DataStore provider for '" + parsedUrl.getProtocol() + "'. Probably not a valid provider?");
        }

        DataStore ds = null;

        try {
            ds = dataStoreClass.newInstance();
        } catch (Exception e) {
            throw new DataStoreFatalException("Unable to load data store class '" + dataStoreClass + "'");
        }

        Properties props = parsedUrl.getQueryProperties();

        // create a temporary xml configuration in-memory to take advantage of
        // the ability for an Xbean to auto configure an object
        if (props != null) {
            StringBuilder xml = new StringBuilder(200);
            xml.append("");
            for (Object k : props.keySet()) {
                String key = (String)k;
                xml.append("  <" + key + ">" + props.getProperty(key) + "");
            }
            xml.append("");

            XmlBean xbean = new XmlBean();
            try {
                xbean.configure(xml.toString(), ds);
            } catch (Exception e) {
                throw new DataStoreFatalException("Unable to configure data store", e);
            }
        }

        ds.setName(dataStoreName);

        return ds;
    }

    static public DataStore createFromProperties(String filename) throws IOException, DataStoreFatalException {
        InputStream is = ClassLoader.getSystemResourceAsStream(filename);
        if (is == null) {
	    logger.warn("The properties file {} was not found in the CLASSPATH, trying file path", filename);
	    is = new FileInputStream(filename);
	    if (is == null) {
		throw new IOException("The properties file " + filename + " was not found in the CLASSPATH or file path");
	    }
	}

        Properties props = new Properties();
        props.load(is);
	try {
	    return createFromProperties(props); 
	} finally {
	    is.close();
	}
    }

    static public DataStore createFromProperties(Properties props) throws IOException, DataStoreFatalException {
        if (!props.containsKey("datastore.directory")) {
            throw new IOException("The property 'datastore.directory' was not found");
        }
	
        if (!props.containsKey("datastore.url")) {
            throw new IOException("The property 'datastore.url' was not found");
        }

        String url = props.getProperty("datastore.url");
        String directory = props.getProperty("datastore.directory");

        DataStore ds = DataStoreManager.create(url);
        ds.setDirectory(new File(directory));

        return ds;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy