/* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.importer;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.io.FilenameUtils;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.importer.job.ProgressMonitor;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.platform.resource.Files;
import org.geoserver.platform.resource.Paths;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.coverage.grid.io.GridFormatFinder;
import org.geotools.coverage.grid.io.UnknownFormat;
import org.geotools.data.DataStoreFactorySpi;
import org.geotools.data.FileDataStoreFactorySpi;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.util.logging.Logging;
import org.vfny.geoserver.util.DataStoreUtils;
/**
* Represents a type of data and encapsulates I/O operations.
*
* @author Justin Deoliveira, OpenGeo
*
*/
public abstract class DataFormat implements Serializable {
/** serialVersionUID */
private static final long serialVersionUID = 1L;
static Logger LOG = Logging.getLogger(DataFormat.class);
/**
* looks up a format based on file extension.
*/
public static DataFormat lookup(File file) {
FileData fileData = new FileData(file);
for (DataFormat df : GeoServerExtensions.extensions(DataFormat.class)) {
try {
if (df.canRead(fileData)) {
return df;
}
} catch (IOException e) {
LOG.log(Level.FINER, String.format("Error checking if format %s can read file %s, " +
df.getName(), file.getPath()), e);
}
}
//look for a datastore that can handle the file
String ext = FilenameUtils.getExtension(file.getName());
FileDataStoreFactorySpi factory = FileDataStoreFinder.getDataStoreFactory(ext);
if (factory != null) {
return new DataStoreFormat(factory);
}
//look for a gridformat that can handle the file
Set<AbstractGridFormat> formats = GridFormatFinder.findFormats(file);
AbstractGridFormat format = null;
// in the case of 2 formats, let's ensure any ambiguity that cannot
// be resolved is an error to prevent spurious bugs related to
// the first format that is found being returned (and this can vary
// to to hashing in the set)
if (formats.size() > 1) {
for (AbstractGridFormat f: formats) {
// prefer GeoTIFF over WorldImageFormat
if ("GeoTIFF".equals(f.getName())) {
format = f;
break;
}
}
if (format == null) {
throw new RuntimeException("multiple formats found but not handled " + formats);
}
} else if (formats.size() == 1) {
format = formats.iterator().next();
}
if (format != null && !(format instanceof UnknownFormat)) {
return new GridFormat(format);
}
return null;
}
/**
* Looks up a format based on a set of connection parameters.
*/
public static DataFormat lookup(Map<String,Serializable> params) {
DataStoreFactorySpi factory = (DataStoreFactorySpi) DataStoreUtils.aquireFactory(params);
if (factory != null) {
return new DataStoreFormat(factory);
}
return null;
}
/**
* Converts an absolute URL to a resource to be relative to the data directory if applicable.
* @return The relative path, or the original path if it does not contain the data directory
*/
protected String relativeDataFileURL(String url, Catalog catalog) {
if (catalog == null) {
return url;
}
File baseDirectory = catalog.getResourceLoader().getBaseDirectory();
File f = Files.url(baseDirectory, url);
return f == null ? url : "file:"+Paths.convert(baseDirectory, f);
}
public abstract String getName();
public abstract boolean canRead(ImportData data) throws IOException;
public abstract StoreInfo createStore(ImportData data, WorkspaceInfo workspace, Catalog catalog)
throws IOException;
public abstract List<ImportTask> list(ImportData data, Catalog catalog, ProgressMonitor monitor)
throws IOException;
/**
* Returns a File from the ImportData, assuming the import data itself is a FileData (a class
* cast exception will happen otherwise)
*
* @param data
*
*/
protected File getFileFromData(ImportData data) {
assert data instanceof FileData;
FileData fileData = (FileData) data;
File file = fileData.getFile();
return file;
}
}