package org.mapfish.print.processor.http; import com.google.common.collect.Maps; import org.mapfish.print.ExceptionUtils; import org.mapfish.print.config.Configuration; import org.mapfish.print.http.AbstractMfClientHttpRequestFactoryWrapper; import org.mapfish.print.http.MfClientHttpRequestFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpRequest; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * <p>This processor maps uris submitted to the {@link org.mapfish.print.http.MfClientHttpRequestFactory} to a modified uri * as specified by the mapping parameter.</p> * <p>Example: change the hostname of all requests that are http requests and have the hostname: myhost.com to localhost instead * of myhost.com</p> * <pre><code> * - !mapUri * mapping: {(http)://myhost.com(.*) : "$1://localhost$2"} * </code></pre> * * <p>Can be applied conditionally using matchers, like in {@link RestrictUrisProcessor} * (<a href="processors.html#!restrictUris">!restrictUris</a>).</p> * [[examples=http_processors,osm_custom_params]] */ public final class MapUriProcessor extends AbstractClientHttpRequestFactoryProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(MapUriProcessor.class); private final Map<Pattern, String> uriMapping = Maps.newHashMap(); /** * Set the uri mappings. * * The key is a regular expression that must match uri's string form. The value will be used for the replacement. * * @param mapping the uri mappings. */ public void setMapping(final Map<String, String> mapping) { this.uriMapping.clear(); for (Map.Entry<String, String> entry: mapping.entrySet()) { Pattern pattern = Pattern.compile(entry.getKey()); this.uriMapping.put(pattern, entry.getValue()); } } @Override public MfClientHttpRequestFactory createFactoryWrapper(final ClientHttpFactoryProcessorParam clientHttpFactoryProcessorParam, final MfClientHttpRequestFactory requestFactory) { return new AbstractMfClientHttpRequestFactoryWrapper(requestFactory, matchers, false) { @Override protected ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod, final MfClientHttpRequestFactory requestFactory) throws IOException { final String uriString = uri.toString(); for (Map.Entry<Pattern, String> entry : MapUriProcessor.this.uriMapping.entrySet()) { Matcher matcher = entry.getKey().matcher(uriString); if (matcher.matches()) { LOGGER.debug("URI {} matched {}", uriString, entry.getKey()); final String finalUri = matcher.replaceAll(entry.getValue()); try { return requestFactory.createRequest(new URI(finalUri), httpMethod); } catch (URISyntaxException e) { throw ExceptionUtils.getRuntimeException(e); } } else { LOGGER.debug("URI {} did not match {}", uriString, entry.getKey()); } } return requestFactory.createRequest(uri, httpMethod); } }; } @Override protected void extraValidation(final List<Throwable> validationErrors, final Configuration configuration) { super.extraValidation(validationErrors, configuration); if (this.uriMapping.isEmpty()) { validationErrors.add(new IllegalArgumentException("No uri mappings were defined")); } } }