// first off, decide what is the target store
WorkspaceInfo ws;
if (workspace != null) {
ws = catalog.getWorkspaceByName(workspace);
if (ws == null) {
throw new ProcessException("Could not find workspace " + workspace);
}
} else {
ws = catalog.getDefaultWorkspace();
if (ws == null) {
throw new ProcessException(
"The catalog is empty, could not find a default workspace");
}
}
//create a builder to help build catalog objects
CatalogBuilder cb = new CatalogBuilder(catalog);
cb.setWorkspace( ws );
// ok, find the target store
StoreInfo storeInfo = null;
boolean add = false;
if (store != null) {
if (features != null)
{
storeInfo = catalog.getDataStoreByName(ws.getName(), store);
}
else if (coverage != null)
{
storeInfo = catalog.getCoverageStoreByName(ws.getName(), store);
}
if (storeInfo == null) {
throw new ProcessException("Could not find store " + store + " in workspace "
+ workspace);
// TODO: support store creation
}
} else if (features != null) {
storeInfo = catalog.getDefaultDataStore(ws);
if (storeInfo == null) {
throw new ProcessException("Could not find a default store in workspace "
+ ws.getName());
}
} else if (coverage != null) {
//create a new coverage store
LOGGER.info("Auto-configuring coverage store: " + (name != null ? name : coverage.getName().toString()));
storeInfo = cb.buildCoverageStore((name != null ? name : coverage.getName().toString()));
add = true;
store = (name != null ? name : coverage.getName().toString());
if (storeInfo == null) {
throw new ProcessException("Could not find a default store in workspace " + ws.getName());
}
}
// check the target style if any
StyleInfo targetStyle = null;
if (styleName != null) {
targetStyle = catalog.getStyleByName(styleName);
if (targetStyle == null) {
throw new ProcessException("Could not find style " + styleName);
}
}
if (features != null)
{
// check if the target layer and the target feature type are not
// already there (this is a half-assed attempt as we don't have
// an API telling us how the feature type name will be changed
// by DataStore.createSchema(...), but better than fully importing
// the data into the target store to find out we cannot create the layer...)
String tentativeTargetName = null;
if (name != null) {
tentativeTargetName = ws.getName() + ":" + name;
} else {
tentativeTargetName = ws.getName() + ":" + features.getSchema().getTypeName();
}
if (catalog.getLayer(tentativeTargetName) != null) {
throw new ProcessException("Target layer " + tentativeTargetName + " already exists");
}
// check the target crs
String targetSRSCode = null;
if (srs != null) {
try {
Integer code = CRS.lookupEpsgCode(srs, true);
if (code == null) {
throw new WPSException("Could not find a EPSG code for " + srs);
}
targetSRSCode = "EPSG:" + code;
} catch (Exception e) {
throw new ProcessException("Could not lookup the EPSG code for the provided srs", e);
}
} else {
// check we can extract a code from the original data
GeometryDescriptor gd = features.getSchema().getGeometryDescriptor();
if (gd == null) {
// data is geometryless, we need a fake SRS
targetSRSCode = "EPSG:4326";
srsHandling = ProjectionPolicy.FORCE_DECLARED;
} else {
CoordinateReferenceSystem nativeCrs = gd.getCoordinateReferenceSystem();
if (nativeCrs == null) {
throw new ProcessException("The original data has no native CRS, "
+ "you need to specify the srs parameter");
} else {
try {
Integer code = CRS.lookupEpsgCode(nativeCrs, true);
if (code == null) {
throw new ProcessException("Could not find an EPSG code for data "
+ "native spatial reference system: " + nativeCrs);
} else {
targetSRSCode = "EPSG:" + code;
}
} catch (Exception e) {
throw new ProcessException("Failed to loookup an official EPSG code for "
+ "the source data native " + "spatial reference system", e);
}
}
}
}
// import the data into the target store
SimpleFeatureType targetType;
try {
targetType = importDataIntoStore(features, name, (DataStoreInfo) storeInfo);
} catch (IOException e) {
throw new ProcessException("Failed to import data into the target store", e);
}
// now import the newly created layer into GeoServer
try {
cb.setStore(storeInfo);
// build the typeInfo and set CRS if necessary
FeatureTypeInfo typeInfo = cb.buildFeatureType(targetType.getName());
if (targetSRSCode != null) {
typeInfo.setSRS(targetSRSCode);
}
if (srsHandling != null) {
typeInfo.setProjectionPolicy(srsHandling);
}
// compute the bounds
cb.setupBounds(typeInfo);
// build the layer and set a style
LayerInfo layerInfo = cb.buildLayer(typeInfo);
if (targetStyle != null) {
layerInfo.setDefaultStyle(targetStyle);
}
catalog.add(typeInfo);
catalog.add(layerInfo);
return layerInfo.prefixedName();
} catch (Exception e) {
throw new ProcessException(
"Failed to complete the import inside the GeoServer catalog", e);
}
}
else if (coverage != null)
{
try {
final File directory = catalog.getResourceLoader().findOrCreateDirectory("data", workspace, store);
final File file = File.createTempFile(store, ".tif", directory);
((CoverageStoreInfo)storeInfo).setURL( file.toURL().toExternalForm() );
((CoverageStoreInfo)storeInfo).setType("GeoTIFF");
// check the target crs
CoordinateReferenceSystem cvCrs = coverage.getCoordinateReferenceSystem();
String targetSRSCode = null;
if (srs != null) {
try {
Integer code = CRS.lookupEpsgCode(srs, true);
if (code == null) {
throw new WPSException("Could not find a EPSG code for " + srs);
}
targetSRSCode = "EPSG:" + code;
} catch (Exception e) {
throw new ProcessException("Could not lookup the EPSG code for the provided srs", e);
}
} else {
// check we can extract a code from the original data
if (cvCrs == null) {
// data is geometryless, we need a fake SRS
targetSRSCode = "EPSG:4326";
srsHandling = ProjectionPolicy.FORCE_DECLARED;
srs = DefaultGeographicCRS.WGS84;
} else {
CoordinateReferenceSystem nativeCrs = cvCrs;
if (nativeCrs == null) {
throw new ProcessException("The original data has no native CRS, "
+ "you need to specify the srs parameter");
} else {
try {
Integer code = CRS.lookupEpsgCode(nativeCrs, true);
if (code == null) {
throw new ProcessException("Could not find an EPSG code for data "
+ "native spatial reference system: " + nativeCrs);
} else {
targetSRSCode = "EPSG:" + code;
srs = CRS.decode(targetSRSCode, true);
}
} catch (Exception e) {
throw new ProcessException("Failed to loookup an official EPSG code for "
+ "the source data native " + "spatial reference system", e);
}
}
}
}
MathTransform tx = CRS.findMathTransform(cvCrs, srs);
if (!tx.isIdentity() || !CRS.equalsIgnoreMetadata(cvCrs, srs))
{
coverage = WCSUtils.resample(coverage, cvCrs, srs, null, Interpolation.getInstance(Interpolation.INTERP_NEAREST));
}
GeoTiffWriter writer = new GeoTiffWriter(file);
// setting the write parameters for this geotiff
final ParameterValueGroup params = new GeoTiffFormat().getWriteParameters();
params.parameter(AbstractGridFormat.GEOTOOLS_WRITE_PARAMS.getName().toString()).setValue(
DEFAULT_WRITE_PARAMS);
final GeneralParameterValue[] wps = (GeneralParameterValue[]) params.values().toArray(
new GeneralParameterValue[1]);
try {
writer.write(coverage, wps);
} finally {
try {
writer.dispose();
} catch (Exception e) {
// we tried, no need to fuss around this one
}
}
//add or update the datastore info
if ( add ) {
catalog.add( (CoverageStoreInfo)storeInfo );
}
else {
catalog.save( (CoverageStoreInfo)storeInfo );
}
cb.setStore( (CoverageStoreInfo)storeInfo );
GridCoverage2DReader reader = new GeoTiffReader(file);
if ( reader == null ) {
throw new ProcessException( "Could not aquire reader for coverage." );
}
// coverage read params
final Map customParameters = new HashMap();
/*String useJAIImageReadParam = "USE_JAI_IMAGEREAD";
if (useJAIImageReadParam != null) {
customParameters.put(AbstractGridFormat.USE_JAI_IMAGEREAD.getName().toString(), Boolean.valueOf(useJAIImageReadParam));
}*/
CoverageInfo cinfo = cb.buildCoverage( reader, customParameters );
//check if the name of the coverage was specified
if ( name != null ) {
cinfo.setName( name );
}
if ( !add ) {
//update the existing
CoverageInfo existing = catalog.getCoverageByCoverageStore((CoverageStoreInfo) storeInfo, name != null ? name : coverage.getName().toString() );
if ( existing == null ) {
//grab the first if there is only one
List<CoverageInfo> coverages = catalog.getCoveragesByCoverageStore( (CoverageStoreInfo) storeInfo );
if ( coverages.size() == 1 ) {
existing = coverages.get(0);
}
if ( coverages.size() == 0 ) {
//no coverages yet configured, change add flag and continue on
add = true;
}
else {
// multiple coverages, and one to configure not specified
throw new ProcessException( "Unable to determine coverage to configure.");
}
}
if ( existing != null ) {
cb.updateCoverage(existing,cinfo);
catalog.save( existing );
cinfo = existing;
}
}
//do some post configuration, if srs is not known or unset, transform to 4326
if ("UNKNOWN".equals(cinfo.getSRS())) {
//CoordinateReferenceSystem sourceCRS = cinfo.getBoundingBox().getCoordinateReferenceSystem();
//CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326", true);
//ReferencedEnvelope re = cinfo.getBoundingBox().transform(targetCRS, true);
cinfo.setSRS( "EPSG:4326" );
//cinfo.setCRS( targetCRS );
//cinfo.setBoundingBox( re );
}
//add/save
if ( add ) {
catalog.add( cinfo );
LayerInfo layerInfo = cb.buildLayer( cinfo );
if ( styleName != null && targetStyle != null ) {
layerInfo.setDefaultStyle( targetStyle );
}
//JD: commenting this out, these sorts of edits should be handled
// with a second PUT request on the created coverage
/*
String styleName = form.getFirstValue("style");
if ( styleName != null ) {
StyleInfo style = catalog.getStyleByName( styleName );
if ( style != null ) {
layerInfo.setDefaultStyle( style );
if ( !layerInfo.getStyles().contains( style ) ) {
layerInfo.getStyles().add( style );
}
}
else {
LOGGER.warning( "Client specified style '" + styleName + "'but no such style exists.");
}
}
String path = form.getFirstValue( "path");
if ( path != null ) {
layerInfo.setPath( path );
}
*/
boolean valid = true;
try {
if (!catalog.validate(layerInfo, true).isValid()) {
valid = false;
}
} catch (Exception e) {
valid = false;
}
layerInfo.setEnabled(valid);
catalog.add(layerInfo);
return layerInfo.prefixedName();
}
else {
catalog.save( cinfo );
LayerInfo layerInfo = catalog.getLayerByName(cinfo.getName());
if ( styleName != null && targetStyle != null ) {
layerInfo.setDefaultStyle( targetStyle );
}
return layerInfo.prefixedName();
}
} catch (MalformedURLException e) {
throw new ProcessException( "URL Error", e );
} catch (IOException e) {
throw new ProcessException( "I/O Exception", e );
} catch (Exception e) {
e.printStackTrace();
throw new ProcessException( "Exception", e );
}
}
return null;
}