001package org.apache.commons.jcs.utils.props; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import java.io.InputStream; 023import java.util.Properties; 024 025/** 026 * I modified this class to work with .ccf files in particular. I also removed 027 * the resource bundle functionality. 028 * <p> 029 * A simple class for loading java.util.Properties backed by .ccf files deployed 030 * as classpath resources. See individual methods for details. 031 * <p> 032 * The original source is from: 033 * <p> 034 * @author (C) <a 035 * href="http://www.javaworld.com/columns/jw-qna-index.shtml">Vlad 036 * Roubtsov </a>, 2003 037 */ 038public abstract class PropertyLoader 039{ 040 /** throw an error if we can load the file */ 041 private static final boolean THROW_ON_LOAD_FAILURE = true; 042 043 /** File suffix. */ 044 private static final String SUFFIX = ".ccf"; 045 046 /** property suffix */ 047 private static final String SUFFIX_PROPERTIES = ".properties"; 048 049 /** 050 * Looks up a resource named 'name' in the classpath. The resource must map 051 * to a file with .ccf extention. The name is assumed to be absolute and can 052 * use either "/" or "." for package segment separation with an optional 053 * leading "/" and optional ".ccf" suffix. 054 * <p> 055 * The suffix ".ccf" will be appended if it is not set. This can also handle 056 * .properties files 057 * <p> 058 * Thus, the following names refer to the same resource: 059 * 060 * <pre> 061 * 062 * some.pkg.Resource 063 * some.pkg.Resource.ccf 064 * some/pkg/Resource 065 * some/pkg/Resource.ccf 066 * /some/pkg/Resource 067 * /some/pkg/Resource.ccf 068 * </pre> 069 * 070 * @param name 071 * classpath resource name [may not be null] 072 * @param loader 073 * classloader through which to load the resource [null is 074 * equivalent to the application loader] 075 * @return resource converted to java.util.properties [may be null if the 076 * resource was not found and THROW_ON_LOAD_FAILURE is false] 077 * @throws IllegalArgumentException 078 * if the resource was not found and THROW_ON_LOAD_FAILURE is 079 * true 080 */ 081 public static Properties loadProperties( String name, ClassLoader loader ) 082 { 083 boolean isCCFSuffix = true; 084 085 if ( name == null ) 086 throw new IllegalArgumentException( "null input: name" ); 087 088 ClassLoader classLoader = ( loader == null ) ? ClassLoader.getSystemClassLoader() : loader; 089 090 String fileName = name.startsWith( "/" ) ? name.substring( 1 ) : name; 091 092 if ( fileName.endsWith( SUFFIX ) ) 093 { 094 fileName = fileName.substring( 0, fileName.length() - SUFFIX.length() ); 095 } 096 097 if ( fileName.endsWith( SUFFIX_PROPERTIES ) ) 098 { 099 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}