/* (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.net.URL; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import javax.management.RuntimeErrorException; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.validation.IValidatable; import org.apache.wicket.validation.IValidationError; import org.apache.wicket.validation.IValidator; import org.apache.wicket.validation.ValidationError; import org.geoserver.catalog.CatalogBuilder; import org.geoserver.catalog.WMSStoreInfo; import org.geoserver.platform.GeoServerEnvironment; import org.geoserver.platform.GeoServerExtensions; import org.geoserver.util.EntityResolverProvider; import org.geoserver.web.data.layer.NewLayerPage; import org.geotools.data.ows.HTTPClient; import org.geotools.data.ows.SimpleHttpClient; import org.geotools.data.wms.WebMapServer; import org.geotools.data.wms.xml.WMSSchema; import org.geotools.ows.ServiceException; import org.geotools.xml.DocumentFactory; import org.geotools.xml.XMLHandlerHints; import org.geotools.xml.handlers.DocumentHandler; import org.xml.sax.EntityResolver; public class WMSStoreNewPage extends AbstractWMSStorePage { public WMSStoreNewPage() { try { CatalogBuilder builder = new CatalogBuilder(getCatalog()); WMSStoreInfo store = builder.buildWMSStore(null); initUI(store); final GeoServerEnvironment gsEnvironment = GeoServerExtensions.bean(GeoServerEnvironment.class); // AF: Disable Binding if GeoServer Env Parametrization is enabled! if (gsEnvironment == null || !GeoServerEnvironment.ALLOW_ENV_PARAMETRIZATION) { capabilitiesURL.getFormComponent().add(new WMSCapabilitiesURLValidator()); } } catch (IOException e) { throw new RuntimeException("Could not setup the WMS store: " + e.getMessage(), e); } } @Override protected void onSave(WMSStoreInfo info, AjaxRequestTarget target) throws IllegalArgumentException { /* * Try saving a copy of it so if the process fails somehow the original "info" does not end * up with an id set */ WMSStoreInfo expandedStore = getCatalog().getResourcePool().clone(info, true); WMSStoreInfo savedStore = getCatalog().getFactory().createWebMapServer(); // GR: this shouldn't fail, the Catalog.save(StoreInfo) API does not declare any action in // case of a failure!... strange, why a save can't fail? // Still, be cautious and wrap it in a try/catch block so the page does not blow up try { // GeoServer Env substitution; validate first getCatalog().validate(expandedStore, false).throwIfInvalid(); // GeoServer Env substitution; force to *AVOID* resolving env placeholders... savedStore = getCatalog().getResourcePool().clone(info, false); // ... and save getCatalog().save(savedStore); } catch (RuntimeException e) { LOGGER.log(Level.INFO, "Adding the store for " + info.getCapabilitiesURL(), e); throw new IllegalArgumentException( "The WMS store could not be saved. Failure message: " + e.getMessage()); } // the StoreInfo save succeeded... try to present the list of coverages (well, _the_ // coverage while the getotools coverage api does not allow for more than one NewLayerPage layerChooserPage; try { // The ID is assigned by the catalog and therefore cannot be cloned layerChooserPage = new NewLayerPage(savedStore.getId()); } catch (RuntimeException e) { LOGGER.log(Level.INFO, "Getting list of layers for the WMS store " + info.getCapabilitiesURL(), e); // doh, can't present the list of coverages, means saving the StoreInfo is meaningless. try {// be extra cautious getCatalog().remove(expandedStore); getCatalog().remove(savedStore); } catch (RuntimeErrorException shouldNotHappen) { LOGGER.log(Level.WARNING, "Can't remove CoverageStoreInfo after adding it!", e); } // tell the caller why we failed... throw new IllegalArgumentException(e.getMessage(), e); } setResponsePage(layerChooserPage); } final class WMSCapabilitiesURLValidator implements IValidator { @Override public void validate(IValidatable validatable) { String url = (String) validatable.getValue(); try { HTTPClient client = new SimpleHttpClient(); usernamePanel.getFormComponent().processInput(); String user = usernamePanel.getFormComponent().getInput(); password.getFormComponent().processInput(); String pwd = password.getFormComponent().getInput(); if (user != null && user.length() > 0 && pwd != null && pwd.length() > 0) { client.setUser(user); client.setPassword(pwd); } Map<String, Object> hints = new HashMap<>(); hints.put(DocumentHandler.DEFAULT_NAMESPACE_HINT_KEY, WMSSchema.getInstance()); hints.put(DocumentFactory.VALIDATION_HINT, Boolean.FALSE); EntityResolverProvider provider = getCatalog().getResourcePool().getEntityResolverProvider(); if(provider != null) { EntityResolver entityResolver = provider.getEntityResolver(); if(entityResolver != null) { hints.put(XMLHandlerHints.ENTITY_RESOLVER, entityResolver); } } WebMapServer server = new WebMapServer(new URL(url), client, hints); server.getCapabilities(); } catch(IOException | ServiceException e) { IValidationError err = new ValidationError("WMSCapabilitiesValidator.connectionFailure") .addKey("WMSCapabilitiesValidator.connectionFailure") .setVariable("error", e.getMessage()); validatable.error(err); } } } }