001/* 002 * Copyright 2002-2016 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.core.io.support; 018 019import java.io.IOException; 020import java.io.InputStream; 021import java.io.Reader; 022import java.net.URL; 023import java.net.URLConnection; 024import java.util.Enumeration; 025import java.util.Properties; 026 027import org.springframework.core.io.Resource; 028import org.springframework.util.Assert; 029import org.springframework.util.ClassUtils; 030import org.springframework.util.DefaultPropertiesPersister; 031import org.springframework.util.PropertiesPersister; 032import org.springframework.util.ResourceUtils; 033 034/** 035 * Convenient utility methods for loading of {@code java.util.Properties}, 036 * performing standard handling of input streams. 037 * 038 * <p>For more configurable properties loading, including the option of a 039 * customized encoding, consider using the PropertiesLoaderSupport class. 040 * 041 * @author Juergen Hoeller 042 * @author Rob Harrop 043 * @since 2.0 044 * @see PropertiesLoaderSupport 045 */ 046public abstract class PropertiesLoaderUtils { 047 048 private static final String XML_FILE_EXTENSION = ".xml"; 049 050 051 /** 052 * Load properties from the given EncodedResource, 053 * potentially defining a specific encoding for the properties file. 054 * @see #fillProperties(java.util.Properties, EncodedResource) 055 */ 056 public static Properties loadProperties(EncodedResource resource) throws IOException { 057 Properties props = new Properties(); 058 fillProperties(props, resource); 059 return props; 060 } 061 062 /** 063 * Fill the given properties from the given EncodedResource, 064 * potentially defining a specific encoding for the properties file. 065 * @param props the Properties instance to load into 066 * @param resource the resource to load from 067 * @throws IOException in case of I/O errors 068 */ 069 public static void fillProperties(Properties props, EncodedResource resource) 070 throws IOException { 071 072 fillProperties(props, resource, new DefaultPropertiesPersister()); 073 } 074 075 /** 076 * Actually load properties from the given EncodedResource into the given Properties instance. 077 * @param props the Properties instance to load into 078 * @param resource the resource to load from 079 * @param persister the PropertiesPersister to use 080 * @throws IOException in case of I/O errors 081 */ 082 static void fillProperties(Properties props, EncodedResource resource, PropertiesPersister persister) 083 throws IOException { 084 085 InputStream stream = null; 086 Reader reader = null; 087 try { 088 String filename = resource.getResource().getFilename(); 089 if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) { 090 stream = resource.getInputStream(); 091 persister.loadFromXml(props, stream); 092 } 093 else if (resource.requiresReader()) { 094 reader = resource.getReader(); 095 persister.load(props, reader); 096 } 097 else { 098 stream = resource.getInputStream(); 099 persister.load(props, stream); 100 } 101 } 102 finally { 103 if (stream != null) { 104 stream.close(); 105 } 106 if (reader != null) { 107 reader.close(); 108 } 109 } 110 } 111 112 /** 113 * Load properties from the given resource (in ISO-8859-1 encoding). 114 * @param resource the resource to load from 115 * @return the populated Properties instance 116 * @throws IOException if loading failed 117 * @see #fillProperties(java.util.Properties, Resource) 118 */ 119 public static Properties loadProperties(Resource resource) throws IOException { 120 Properties props = new Properties(); 121 fillProperties(props, resource); 122 return props; 123 } 124 125 /** 126 * Fill the given properties from the given resource (in ISO-8859-1 encoding). 127 * @param props the Properties instance to fill 128 * @param resource the resource to load from 129 * @throws IOException if loading failed 130 */ 131 public static void fillProperties(Properties props, Resource resource) throws IOException { 132 InputStream is = resource.getInputStream(); 133 try { 134 String filename = resource.getFilename(); 135 if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) { 136 props.loadFromXML(is); 137 } 138 else { 139 props.load(is); 140 } 141 } 142 finally { 143 is.close(); 144 } 145 } 146 147 /** 148 * Load all properties from the specified class path resource 149 * (in ISO-8859-1 encoding), using the default class loader. 150 * <p>Merges properties if more than one resource of the same name 151 * found in the class path. 152 * @param resourceName the name of the class path resource 153 * @return the populated Properties instance 154 * @throws IOException if loading failed 155 */ 156 public static Properties loadAllProperties(String resourceName) throws IOException { 157 return loadAllProperties(resourceName, null); 158 } 159 160 /** 161 * Load all properties from the specified class path resource 162 * (in ISO-8859-1 encoding), using the given class loader. 163 * <p>Merges properties if more than one resource of the same name 164 * found in the class path. 165 * @param resourceName the name of the class path resource 166 * @param classLoader the ClassLoader to use for loading 167 * (or {@code null} to use the default class loader) 168 * @return the populated Properties instance 169 * @throws IOException if loading failed 170 */ 171 public static Properties loadAllProperties(String resourceName, ClassLoader classLoader) throws IOException { 172 Assert.notNull(resourceName, "Resource name must not be null"); 173 ClassLoader classLoaderToUse = classLoader; 174 if (classLoaderToUse == null) { 175 classLoaderToUse = ClassUtils.getDefaultClassLoader(); 176 } 177 Enumeration<URL> urls = (classLoaderToUse != null ? classLoaderToUse.getResources(resourceName) : 178 ClassLoader.getSystemResources(resourceName)); 179 Properties props = new Properties(); 180 while (urls.hasMoreElements()) { 181 URL url = urls.nextElement(); 182 URLConnection con = url.openConnection(); 183 ResourceUtils.useCachesIfNecessary(con); 184 InputStream is = con.getInputStream(); 185 try { 186 if (resourceName.endsWith(XML_FILE_EXTENSION)) { 187 props.loadFromXML(is); 188 } 189 else { 190 props.load(is); 191 } 192 } 193 finally { 194 is.close(); 195 } 196 } 197 return props; 198 } 199 200}