StoreUtils.java

/***************************************************************************
   Copyright 2015 Emily Estes

   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 net.metanotion.contentstore;


import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import javax.sql.DataSource;

import net.metanotion.io.JavaFileSystem;
import net.metanotion.util.Pair;
import net.metanotion.web.HttpValues;
import net.metanotion.web.concrete.HttpUtil;
import net.metanotion.web.concrete.SimpleHttpValues;

/** A collection of utility methods for interacting with content stores. */
public final class StoreUtils {
	/** Convert a ContentStore entry into an HTTP response.
		@param entry The entry to convert into an HTTP response.
		@return The HTTP response representing the file/content stored as the entry.
	*/
	public static HttpValues get(final Entry entry) {
		if(entry.isFile()) {
			return new SimpleHttpValues(
				Arrays.asList((Map.Entry<String,Object>) new Pair<String,Object>("Content-Type", entry.getContentType()),
					(Map.Entry<String,Object>)
						new Pair<String,Object>("Content-Disposition", "inline;filename=\"" + entry.getFilename() + "\"")),
				new ArrayList<Map.Entry<String,Object>>(),
				entry.readFile());
		} else {
			return HttpUtil.newTypedContent(entry.readContent(), entry.getContentType());
		}
	}

	/** Create a new {@link net.metanotion.contentstore.BasicStore} instance from a folder on disk. If the folder
	represents a collection of stores, use the subfolder "store" name to determine the appropriate subfolder. If the
	directory for the content store doesn't exist create it(recursively). After the store instance has been created,
	guarantee that the provided list of collections exist in the store.
		@param ds The database containing the store schema.
		@param es The executor service for deleted file GC threads.
		@param store The subfolder for this store instance or the empty string("") if this is the only store.
		@param storeRoot The file system folder for the content store(s).
		@param constantCollections The list of collections that should always exist in the store.
		@return The content store instance created.
		@throws IOException if there was a problem creating the content store instance.
	*/
	public static ContentStore getStore(final DataSource ds,
			final ScheduledExecutorService es,
			final String store,
			final File storeRoot,
			final Iterable<String> constantCollections) throws IOException {
		final ContentStore s = getStore(ds, es, store, storeRoot);
		guaranteeCollections(s, constantCollections);
		return s;
	}

	/** Create a new {@link net.metanotion.contentstore.BasicStore} instance from a folder on disk. If the folder
	represents a collection of stores, use the subfolder "store" name to determine the appropriate subfolder. If the
	directory for the content store doesn't exist create it(recursively).
		@param ds The database containing the store schema.
		@param es The executor service for deleted file GC threads.
		@param store The subfolder for this store instance or the empty string("") if this is the only store.
		@param storeRoot The file system folder for the content store(s).
		@return The content store instance created.
		@throws IOException if there was a problem creating the content store instance.
	*/
	public static ContentStore getStore(final DataSource ds,
			final ScheduledExecutorService es,
			final String store,
			final File storeRoot) throws IOException {
		if(store.length() > 0) {
			final File folder = new File(storeRoot.toString() + File.separator + store);
			if(!folder.exists()) {
				if(!folder.mkdirs()) {
					throw new RuntimeException("Failed to create content store folder for instance '" + store + "'");
				}
			}
			final JavaFileSystem storeFs = new JavaFileSystem(folder.toString());
			return new BasicStore(ds, storeFs, es);
		} else {
			final JavaFileSystem storeFs = new JavaFileSystem(storeRoot.toString());
			return new BasicStore(ds, storeFs, es);
		}
	}

	/** Gurantee that the list of collections provided exists in the content store.
		@param store The content store instance.
		@param constantCollections The list of collections that should always exist in the store.
	*/
	public static void guaranteeCollections(final ContentStore store, final Iterable<String> constantCollections) {
		for(final String cName: constantCollections) {
			try {
				store.getCollection(cName);
			} catch (final Exception e) {
				store.makeCollection(cName);
			}
		}
	}
}