001    /*
002     * $Id: ResourcesFactoryBase.java 349025 2005-11-25 21:09:54Z niallp $
003     * $Revision: 349025 $
004     * $Date: 2005-11-25 21:09:54 +0000 (Fri, 25 Nov 2005) $
005     *
006     * ====================================================================
007     *
008     *  Copyright 2003-2005 The Apache Software Foundation
009     *
010     *  Licensed under the Apache License, Version 2.0 (the "License");
011     *  you may not use this file except in compliance with the License.
012     *  You may obtain a copy of the License at
013     *
014     *      http://www.apache.org/licenses/LICENSE-2.0
015     *
016     *  Unless required by applicable law or agreed to in writing, software
017     *  distributed under the License is distributed on an "AS IS" BASIS,
018     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019     *  See the License for the specific language governing permissions and
020     *  limitations under the License.
021     *
022     */
023    
024    package org.apache.commons.resources.impl;
025    
026    import java.util.HashMap;
027    import java.util.Iterator;
028    import java.util.Map;
029    
030    import org.apache.commons.resources.Resources;
031    import org.apache.commons.resources.ResourcesException;
032    import org.apache.commons.resources.ResourcesFactory;
033    
034    /**
035     * <p>Convenience base class for {@link ResourcesFactory} implementations.
036     * This implementation caches the {@link Resources} instances returned by
037     * a protected <code>createResources()</code> method, which must be implemented
038     * by concrete subclasses.</p>
039     *
040     * @see org.apache.commons.resources.impl.JDBCResourcesFactory
041     * @see org.apache.commons.resources.impl.PropertyResourcesFactory
042     * @see org.apache.commons.resources.impl.ResourceBundleResourcesFactory
043     * @see org.apache.commons.resources.impl.WebappResourcesFactoryBase
044     * @see org.apache.commons.resources.impl.WebappPropertyResourcesFactory
045     * @see org.apache.commons.resources.impl.WebappXMLResourcesFactory
046     * @see org.apache.commons.resources.impl.XMLResourcesFactory
047     */
048    public abstract class ResourcesFactoryBase implements ResourcesFactory {
049        
050    
051        // ----------------------------------------------------- Instance Variables
052    
053    
054        /**
055         * <p>The set of {@link Resources} instances previously created by
056         * this {@link ResourcesFactory}, keyed by logical name.</p>
057         */
058        private Map resources = new HashMap();
059    
060    
061        /**
062         * <p>The <code>returnNull</code> property value that will be configured
063         * on {@link Resources} instances created by this factory.</p>
064         */
065        private boolean returnNull = true;
066    
067    
068        // ------------------------------------------------------------- Properties
069    
070    
071        /**
072         * <p>Return the <code>returnNull</code> property value that will be
073         * configured on {@link Resources} instances created by this factory.</p>
074         * @return 'true' if null is returned for invalid key values.
075         */
076        public boolean isReturnNull() {
077    
078            return (this.returnNull);
079    
080        }
081    
082    
083        /**
084         * <p>Set the <code>returnNull</code> property value that will be
085         * configured on {@link Resources} instances created by this factory.</p>
086         *
087         * @param returnNull The new value to delegate
088         */
089        public void setReturnNull(boolean returnNull) {
090    
091            this.returnNull = returnNull;
092    
093        }
094    
095    
096        // --------------------------------------------------------- Public Methods
097    
098    
099        /**
100         * <p>Create (if necessary) and return a {@link Resources} instance
101         * for the specified logical name, with a default configuration.
102         * The default implementation of this method treats the name as the
103         * configuration String as well, and calls the
104         * <code>getResources(String,String)</code> method.
105         *
106         * @param name Logical name of the {@link Resources} instance to
107         *  be returned
108         * @return The resources instance.
109         *
110         * @exception ResourcesException if a {@link Resources} instance
111         *  of the specified logical name cannot be returned.
112         */
113        public Resources getResources(String name) {
114    
115            return (getResources(name, name));
116    
117        }
118    
119    
120        /**
121         * <p>Create (if necessary) and return a {@link Resources} instance
122         * for the specified logical name, with a configuration based on
123         * the specified configuration String.</p>
124         *
125         * @param name Logical name of the {@link Resources} instance to
126         *  be returned
127         * @param config Configuration string for this resource (meaning
128         *  is dependent upon the {@link ResourcesFactory} implementation
129         *  being utilized), or <code>null</code> for the default
130         *  configuration
131         * @return The resources instance.
132         *
133         * @exception ResourcesException if a {@link Resources} instance
134         *  of the specified logical name cannot be returned.
135         */
136        public Resources getResources(String name, String config) {
137    
138            synchronized (resources) {
139                Resources instance = (Resources) resources.get(name);
140                if (instance == null) {
141                    instance = createResources(name, config);
142                    resources.put(name, instance);
143                }
144                return (instance);
145            }
146    
147        }
148    
149    
150        /**
151         * <p>Release any internal references to {@link Resources} instances
152         * that have been returned previously, after calling the
153         * <code>destroy()</code> method on each such instance.</p>
154         *
155         * @exception ResourcesException if a problem occurred while releasing
156         */
157        public void release() {
158    
159            synchronized (resources) {
160                Iterator names = resources.keySet().iterator();
161                while (names.hasNext()) {
162                    String name = (String) names.next();
163                    ((Resources) resources.get(name)).destroy();
164                }
165                resources.clear();
166            }
167    
168        }
169    
170    
171    
172        // ------------------------------------------------------ Protected Methods
173    
174    
175        /**
176         * <p>Create and return a new {@link Resources} instance with the
177         * specified logical name, after calling its <code>init()</code>
178         * method and delegating the relevant properties.  Concrete
179         * subclasses <strong>MUST</strong> implement this method.</p>
180         *
181         * @param name Logical name of the {@link Resources} instance to create
182         * @param config Configuration string for this resource (if any)
183         * @return The new Resources instance.
184         *
185         * @exception ResourcesException if a {@link Resources} instance
186         *  of the specified logical name cannot be created.
187         */
188        protected abstract Resources createResources(String name, String config);
189    
190    
191    }