/* (c) 2014 - 2016 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.web.data.store;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.CoverageStoreInfo;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.ResourcePool;
import org.geoserver.web.wicket.GeoServerDialog;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.factory.GeoTools;
import org.opengis.coverage.grid.GridCoverageReader;
/**
* Supports coverage store configuration
*
* @author Andrea Aime
*/
public class CoverageStoreEditPage extends AbstractCoverageStorePage {
public static final String STORE_NAME = "storeName";
public static final String WS_NAME = "wsName";
/**
* Dialog to ask for save confirmation in case the store can't be reached
*/
private GeoServerDialog dialog;
/**
* Uses a "name" parameter to locate the datastore
* @param parameters
*/
public CoverageStoreEditPage(PageParameters parameters) {
String wsName = parameters.get(WS_NAME).toOptionalString();
String storeName = parameters.get(STORE_NAME).toString();
CoverageStoreInfo csi = getCatalog().getCoverageStoreByName(wsName, storeName);
if(csi == null) {
getSession().error(
new ParamResourceModel("CoverageStoreEditPage.notFound", this, storeName, wsName).getString()
);
doReturn(StorePage.class);
return;
}
initUI(csi);
}
/**
*
* @param storeId
* the store id
*/
public CoverageStoreEditPage(final String storeId) throws IllegalArgumentException {
Catalog catalog = getCatalog();
CoverageStoreInfo store = catalog.getCoverageStore(storeId);
if (store == null) {
throw new IllegalArgumentException("Cannot find coverage store " + storeId);
}
initUI(store);
}
/**
* Creates a new edit page directly from a store object.
*/
public CoverageStoreEditPage(CoverageStoreInfo store) throws IllegalArgumentException {
initUI(store);
}
@Override
void initUI(CoverageStoreInfo store) {
dialog = new GeoServerDialog("dialog");
add(dialog);
super.initUI(store);
if (store.getId() != null) {
//store id == null means the store is not part of catalog, forgo uniqueness check
String workspaceId = store.getWorkspace().getId();
workspacePanel.getFormComponent().add(
new CheckExistingResourcesInWorkspaceValidator(store.getId(), workspaceId));
}
}
@Override
protected final void onSave(final CoverageStoreInfo info, final AjaxRequestTarget requestTarget)
throws IllegalArgumentException {
if (null == info.getType()) {
throw new IllegalArgumentException("Coverage type has not been set");
}
final Catalog catalog = getCatalog();
final ResourcePool resourcePool = catalog.getResourcePool();
resourcePool.clear(info);
// Map<String, Serializable> connectionParameters = info.getConnectionParameters();
if (info.isEnabled()) {
// store's enabled, make sure it works
LOGGER.finer("Store " + info.getName() + " is enabled, verifying factory availability "
+ "before saving it...");
AbstractGridFormat gridFormat = resourcePool.getGridCoverageFormat(info);
if (gridFormat == null) {
throw new IllegalArgumentException(
"No grid format found capable of connecting to the provided URL."
+ " To save the store disable it, and check the required libraries are in place");
}
try {
// get the reader through ResourcePool so it resolves relative URL's for us
GridCoverageReader reader = resourcePool.getGridCoverageReader(info, GeoTools.getDefaultHints());
LOGGER.info("Connection to store " + info.getName() + " validated. Got a "
+ reader.getClass().getName() + ". Saving store");
doSaveStore(info);
doReturn(StorePage.class);
} catch (IOException e) {
confirmSaveOnConnectionFailure(info, requestTarget, e);
} catch (RuntimeException e) {
confirmSaveOnConnectionFailure(info, requestTarget, e);
}
} else {
// store's disabled, no need to check for availability
doSaveStore(info);
doReturn(StorePage.class);
}
}
@SuppressWarnings("serial")
private void confirmSaveOnConnectionFailure(final CoverageStoreInfo info,
final AjaxRequestTarget requestTarget, final Exception error) {
final String exceptionMessage = error.getMessage();
dialog.showOkCancel(requestTarget, new GeoServerDialog.DialogDelegate() {
boolean accepted = false;
@Override
protected Component getContents(String id) {
return new StoreConnectionFailedInformationPanel(id, info.getName(),
exceptionMessage);
}
@Override
protected boolean onSubmit(AjaxRequestTarget target, Component contents) {
doSaveStore(info);
accepted = true;
return true;
}
@Override
protected boolean onCancel(AjaxRequestTarget target) {
return true;
}
@Override
public void onClose(AjaxRequestTarget target) {
if (accepted) {
doReturn(StorePage.class);
}
}
});
}
/**
* Performs the save of the store.
* <p>
* This method may be subclasses to provide custom save functionality.
* </p>
*/
protected void doSaveStore(final CoverageStoreInfo info) {
try {
Catalog catalog = getCatalog();
final String prefix = info.getWorkspace().getName();
final NamespaceInfo namespace = catalog.getNamespaceByPrefix(prefix);
List<CoverageInfo> alreadyConfigured;
alreadyConfigured = catalog.getResourcesByStore(info, CoverageInfo.class);
for (CoverageInfo coverage : alreadyConfigured) {
coverage.setNamespace(namespace);
}
ResourcePool resourcePool = catalog.getResourcePool();
resourcePool.clear(info);
// Cloning into "expandedStore" through the super class "clone" method
CoverageStoreInfo expandedStore = resourcePool.clone(info, true);
catalog.validate(expandedStore, false).throwIfInvalid();
catalog.save(info);
for (CoverageInfo coverage : alreadyConfigured) {
catalog.save(coverage);
}
LOGGER.finer("Saved store " + info.getName());
} catch (RuntimeException e) {
LOGGER.log(Level.WARNING, "Saving the store for " + info.getURL(), e);
throw new IllegalArgumentException("Unable to save the store: " + e.getMessage());
}
}
}