1 package org.apache.commons.jcs.utils.props; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import java.io.InputStream; 23 import java.util.Properties; 24 25 /** 26 * I modified this class to work with .ccf files in particular. I also removed 27 * the resource bundle functionality. 28 * <p> 29 * A simple class for loading java.util.Properties backed by .ccf files deployed 30 * as classpath resources. See individual methods for details. 31 * <p> 32 * The original source is from: 33 * <p> 34 * @author (C) <a 35 * href="http://www.javaworld.com/columns/jw-qna-index.shtml">Vlad 36 * Roubtsov </a>, 2003 37 */ 38 public abstract class PropertyLoader 39 { 40 /** throw an error if we can load the file */ 41 private static final boolean THROW_ON_LOAD_FAILURE = true; 42 43 /** File suffix. */ 44 private static final String SUFFIX = ".ccf"; 45 46 /** property suffix */ 47 private static final String SUFFIX_PROPERTIES = ".properties"; 48 49 /** 50 * Looks up a resource named 'name' in the classpath. The resource must map 51 * to a file with .ccf extention. The name is assumed to be absolute and can 52 * use either "/" or "." for package segment separation with an optional 53 * leading "/" and optional ".ccf" suffix. 54 * <p> 55 * The suffix ".ccf" will be appended if it is not set. This can also handle 56 * .properties files 57 * <p> 58 * Thus, the following names refer to the same resource: 59 * 60 * <pre> 61 * 62 * some.pkg.Resource 63 * some.pkg.Resource.ccf 64 * some/pkg/Resource 65 * some/pkg/Resource.ccf 66 * /some/pkg/Resource 67 * /some/pkg/Resource.ccf 68 * </pre> 69 * 70 * @param name 71 * classpath resource name [may not be null] 72 * @param loader 73 * classloader through which to load the resource [null is 74 * equivalent to the application loader] 75 * @return resource converted to java.util.properties [may be null if the 76 * resource was not found and THROW_ON_LOAD_FAILURE is false] 77 * @throws IllegalArgumentException 78 * if the resource was not found and THROW_ON_LOAD_FAILURE is 79 * true 80 */ 81 public static Properties loadProperties( String name, ClassLoader loader ) 82 { 83 boolean isCCFSuffix = true; 84 85 if ( name == null ) 86 throw new IllegalArgumentException( "null input: name" ); 87 88 ClassLoader classLoader = ( loader == null ) ? ClassLoader.getSystemClassLoader() : loader; 89 90 String fileName = name.startsWith( "/" ) ? name.substring( 1 ) : name; 91 92 if ( fileName.endsWith( SUFFIX ) ) 93 { 94 fileName = fileName.substring( 0, fileName.length() - SUFFIX.length() ); 95 } 96 97 if ( fileName.endsWith( SUFFIX_PROPERTIES ) ) 98 { 99 fileName = fileName.substring( 0, fileName.length() - SUFFIX_PROPERTIES.length() ); 100 isCCFSuffix = false; 101 } 102 103 Properties result = null; 104 105 InputStream in = null; 106 try 107 { 108 fileName = fileName.replace( '.', '/' ); 109 110 if ( !fileName.endsWith( SUFFIX ) && isCCFSuffix ) 111 { 112 fileName = fileName.concat( SUFFIX ); 113 } 114 else if ( !fileName.endsWith( SUFFIX_PROPERTIES ) && !isCCFSuffix ) 115 { 116 fileName = fileName.concat( SUFFIX_PROPERTIES ); 117 } 118 119 // returns null on lookup failures: 120 in = classLoader.getResourceAsStream( fileName ); 121 if ( in != null ) 122 { 123 result = new Properties(); 124 result.load( in ); // can throw IOException 125 } 126 } 127 catch ( Exception e ) 128 { 129 result = null; 130 } 131 finally 132 { 133 if ( in != null ) 134 try 135 { 136 in.close(); 137 } 138 catch ( Throwable ignore ) 139 { 140 // swallow 141 } 142 } 143 144 if ( THROW_ON_LOAD_FAILURE && result == null ) 145 { 146 throw new IllegalArgumentException( "could not load [" + fileName + "]" + " as " + "a classloader resource" ); 147 } 148 149 return result; 150 } 151 152 /** 153 * A convenience overload of {@link #loadProperties(String, ClassLoader)} 154 * that uses the current thread's context classloader. A better strategy 155 * would be to use techniques shown in 156 * http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html 157 * <p> 158 * @param name 159 * @return Properties 160 */ 161 public static Properties loadProperties( final String name ) 162 { 163 return loadProperties( name, Thread.currentThread().getContextClassLoader() ); 164 } 165 166 /** 167 * Can't use this one. 168 */ 169 private PropertyLoader() 170 { 171 super(); 172 } // this class is not extentible 173 174 }