001/* 002 * Copyright 2002-2020 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 javax.servlet.ServletContext; 020 021import org.springframework.lang.Nullable; 022import org.springframework.util.PropertyPlaceholderHelper; 023import org.springframework.util.SystemPropertyUtils; 024 025/** 026 * Helper class for resolving placeholders in texts. Usually applied to file paths. 027 * 028 * <p>A text may contain {@code ${...}} placeholders, to be resolved as servlet context 029 * init parameters or system properties: e.g. {@code ${user.dir}}. Default values can 030 * be supplied using the ":" separator between key and value. 031 * 032 * @author Juergen Hoeller 033 * @author Marten Deinum 034 * @since 3.2.2 035 * @see SystemPropertyUtils 036 * @see ServletContext#getInitParameter(String) 037 */ 038public abstract class ServletContextPropertyUtils { 039 040 private static final PropertyPlaceholderHelper strictHelper = 041 new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX, 042 SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, false); 043 044 private static final PropertyPlaceholderHelper nonStrictHelper = 045 new PropertyPlaceholderHelper(SystemPropertyUtils.PLACEHOLDER_PREFIX, 046 SystemPropertyUtils.PLACEHOLDER_SUFFIX, SystemPropertyUtils.VALUE_SEPARATOR, true); 047 048 049 /** 050 * Resolve ${...} placeholders in the given text, replacing them with corresponding 051 * servlet context init parameter or system property values. 052 * @param text the String to resolve 053 * @param servletContext the servletContext to use for lookups. 054 * @return the resolved String 055 * @throws IllegalArgumentException if there is an unresolvable placeholder 056 * @see SystemPropertyUtils#PLACEHOLDER_PREFIX 057 * @see SystemPropertyUtils#PLACEHOLDER_SUFFIX 058 * @see SystemPropertyUtils#resolvePlaceholders(String, boolean) 059 */ 060 public static String resolvePlaceholders(String text, ServletContext servletContext) { 061 return resolvePlaceholders(text, servletContext, false); 062 } 063 064 /** 065 * Resolve ${...} placeholders in the given text, replacing them with corresponding 066 * servlet context init parameter or system property values. Unresolvable placeholders 067 * with no default value are ignored and passed through unchanged if the flag is set to true. 068 * @param text the String to resolve 069 * @param servletContext the servletContext to use for lookups. 070 * @param ignoreUnresolvablePlaceholders flag to determine is unresolved placeholders are ignored 071 * @return the resolved String 072 * @throws IllegalArgumentException if there is an unresolvable placeholder and the flag is false 073 * @see SystemPropertyUtils#PLACEHOLDER_PREFIX 074 * @see SystemPropertyUtils#PLACEHOLDER_SUFFIX 075 * @see SystemPropertyUtils#resolvePlaceholders(String, boolean) 076 */ 077 public static String resolvePlaceholders( 078 String text, ServletContext servletContext, boolean ignoreUnresolvablePlaceholders) { 079 080 if (text.isEmpty()) { 081 return text; 082 } 083 PropertyPlaceholderHelper helper = (ignoreUnresolvablePlaceholders ? nonStrictHelper : strictHelper); 084 return helper.replacePlaceholders(text, new ServletContextPlaceholderResolver(text, servletContext)); 085 } 086 087 088 private static class ServletContextPlaceholderResolver implements PropertyPlaceholderHelper.PlaceholderResolver { 089 090 private final String text; 091 092 private final ServletContext servletContext; 093 094 public ServletContextPlaceholderResolver(String text, ServletContext servletContext) { 095 this.text = text; 096 this.servletContext = servletContext; 097 } 098 099 @Override 100 @Nullable 101 public String resolvePlaceholder(String placeholderName) { 102 try { 103 String propVal = this.servletContext.getInitParameter(placeholderName); 104 if (propVal == null) { 105 // Fall back to system properties. 106 propVal = System.getProperty(placeholderName); 107 if (propVal == null) { 108 // Fall back to searching the system environment. 109 propVal = System.getenv(placeholderName); 110 } 111 } 112 return propVal; 113 } 114 catch (Throwable ex) { 115 System.err.println("Could not resolve placeholder '" + placeholderName + "' in [" + 116 this.text + "] as ServletContext init-parameter or system property: " + ex); 117 return null; 118 } 119 } 120 } 121 122}