View Javadoc
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 }