/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.wps.executor; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import net.opengis.wps10.InputReferenceType; import net.opengis.wps10.InputType; import org.geoserver.ows.Dispatcher; import org.geoserver.ows.KvpRequestReader; import org.geoserver.ows.Request; import org.geoserver.ows.util.CaseInsensitiveMap; import org.geoserver.ows.util.KvpMap; import org.geoserver.ows.util.KvpUtils; import org.geoserver.wps.WPSException; import org.geoserver.wps.ppio.ComplexPPIO; import org.geoserver.wps.ppio.ProcessParameterIO; import org.geoserver.wps.validator.MaxSizeValidator; import org.geoserver.wps.validator.Validators; import org.opengis.util.ProgressListener; import org.springframework.context.ApplicationContext; import org.springframework.validation.Validator; /** * Base class for single value input providers * * @author Andrea Aime - GeoSolutions */ public abstract class AbstractInputProvider implements InputProvider { /** * Creates an input provider */ public static InputProvider getInputProvider(InputType input, ProcessParameterIO ppio, WPSExecutionManager executor, ApplicationContext context, Collection<Validator> validators) throws Exception { InputProvider provider; if (input.getReference() != null) { // this is a reference InputReferenceType ref = input.getReference(); // grab the location and method String href = ref.getHref(); if (href.startsWith("http://geoserver/wfs")) { provider = new InternalWFSInputProvider(input, ppio, context); } else if (href.startsWith("http://geoserver/wcs")) { provider = new InternalWCSInputProvider(input, ppio, context); } else if (href.startsWith("http://geoserver/wps")) { provider = new InternalWPSInputProvider(input, ppio, executor, context); } else { int maxSizeMB = Validators.getMaxSizeMB(validators); validators = Validators.filterOutClasses(validators, MaxSizeValidator.class); provider = new RemoteRequestInputProvider(input, (ComplexPPIO) ppio, executor.getConnectionTimeout(), maxSizeMB * 1024 * 1024); } } else { provider = new SimpleInputProvider(input, ppio); } // add validation if necessary return ValidatingInputProvider.wrap(provider, validators); } InputType input; ProcessParameterIO ppio; Object value; String inputId; public AbstractInputProvider(InputType input, ProcessParameterIO ppio) { this.input = input; this.ppio = ppio; this.inputId = input.getIdentifier().getValue(); } public String getInputId() { return inputId; } @Override public boolean resolved() { return value != null; } @Override final public Object getValue(ProgressListener listener) throws Exception { if (value == null) { value = getValueInternal(listener); } return value; } /** * Computes the value * * @param listener * * */ protected abstract Object getValueInternal(ProgressListener listener) throws Exception; /** * Simulates what the Dispatcher is doing when parsing a KVP request * * @param href * @param reader * */ protected Object kvpParse(String href, KvpRequestReader reader) throws Exception { Map original = new KvpMap(KvpUtils.parseQueryString(href)); KvpUtils.normalize(original); Map parsed = new KvpMap(original); List<Throwable> errors = KvpUtils.parse(parsed); if (errors.size() > 0) { throw new WPSException("Failed to parse KVP request", errors.get(0)); } // hack to allow wcs filters to work... we should really upgrade the WCS models instead... Request r = Dispatcher.REQUEST.get(); if (r != null) { Map kvp = new HashMap(r.getKvp()); r.setKvp(new CaseInsensitiveMap(parsed)); } return reader.read(reader.createRequest(), parsed, original); } /** * Returns the version from the kvp request * * @param href * */ protected String getVersion(String href) { return (String) new KvpMap(KvpUtils.parseQueryString(href)).get("VERSION"); } }