001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.util; 018 019import java.net.URI; 020import java.net.URISyntaxException; 021import java.util.Collections; 022import java.util.HashMap; 023import java.util.Map; 024 025import org.springframework.lang.Nullable; 026import org.springframework.util.Assert; 027 028/** 029 * Abstract base class for {@link UriTemplateHandler} implementations. 030 * 031 * <p>Support {@link #setBaseUrl} and {@link #setDefaultUriVariables} properties 032 * that should be relevant regardless of the URI template expand and encode 033 * mechanism used in sub-classes. 034 * 035 * @author Rossen Stoyanchev 036 * @since 4.3 037 * @deprecated as of 5.0 in favor of {@link DefaultUriBuilderFactory} 038 */ 039@Deprecated 040public abstract class AbstractUriTemplateHandler implements UriTemplateHandler { 041 042 @Nullable 043 private String baseUrl; 044 045 private final Map<String, Object> defaultUriVariables = new HashMap<>(); 046 047 048 /** 049 * Configure a base URL to prepend URI templates with. The base URL must 050 * have a scheme and host but may optionally contain a port and a path. 051 * The base URL must be fully expanded and encoded which can be done via 052 * {@link UriComponentsBuilder}. 053 * @param baseUrl the base URL. 054 */ 055 public void setBaseUrl(@Nullable String baseUrl) { 056 if (baseUrl != null) { 057 UriComponents uriComponents = UriComponentsBuilder.fromUriString(baseUrl).build(); 058 Assert.hasText(uriComponents.getScheme(), "'baseUrl' must have a scheme"); 059 Assert.hasText(uriComponents.getHost(), "'baseUrl' must have a host"); 060 Assert.isNull(uriComponents.getQuery(), "'baseUrl' cannot have a query"); 061 Assert.isNull(uriComponents.getFragment(), "'baseUrl' cannot have a fragment"); 062 } 063 this.baseUrl = baseUrl; 064 } 065 066 /** 067 * Return the configured base URL. 068 */ 069 @Nullable 070 public String getBaseUrl() { 071 return this.baseUrl; 072 } 073 074 /** 075 * Configure default URI variable values to use with every expanded URI 076 * template. These default values apply only when expanding with a Map, and 077 * not with an array, where the Map supplied to {@link #expand(String, Map)} 078 * can override the default values. 079 * @param defaultUriVariables the default URI variable values 080 * @since 4.3 081 */ 082 public void setDefaultUriVariables(@Nullable Map<String, ?> defaultUriVariables) { 083 this.defaultUriVariables.clear(); 084 if (defaultUriVariables != null) { 085 this.defaultUriVariables.putAll(defaultUriVariables); 086 } 087 } 088 089 /** 090 * Return a read-only copy of the configured default URI variables. 091 */ 092 public Map<String, ?> getDefaultUriVariables() { 093 return Collections.unmodifiableMap(this.defaultUriVariables); 094 } 095 096 097 @Override 098 public URI expand(String uriTemplate, Map<String, ?> uriVariables) { 099 if (!getDefaultUriVariables().isEmpty()) { 100 Map<String, Object> map = new HashMap<>(); 101 map.putAll(getDefaultUriVariables()); 102 map.putAll(uriVariables); 103 uriVariables = map; 104 } 105 URI url = expandInternal(uriTemplate, uriVariables); 106 return insertBaseUrl(url); 107 } 108 109 @Override 110 public URI expand(String uriTemplate, Object... uriVariables) { 111 URI url = expandInternal(uriTemplate, uriVariables); 112 return insertBaseUrl(url); 113 } 114 115 116 /** 117 * Actually expand and encode the URI template. 118 */ 119 protected abstract URI expandInternal(String uriTemplate, Map<String, ?> uriVariables); 120 121 /** 122 * Actually expand and encode the URI template. 123 */ 124 protected abstract URI expandInternal(String uriTemplate, Object... uriVariables); 125 126 127 /** 128 * Insert a base URL (if configured) unless the given URL has a host already. 129 */ 130 private URI insertBaseUrl(URI url) { 131 try { 132 String baseUrl = getBaseUrl(); 133 if (baseUrl != null && url.getHost() == null) { 134 url = new URI(baseUrl + url.toString()); 135 } 136 return url; 137 } 138 catch (URISyntaxException ex) { 139 throw new IllegalArgumentException("Invalid URL after inserting base URL: " + url, ex); 140 } 141 } 142 143}