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