001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.commons.discovery.resource.names;
018    
019    import java.util.Hashtable;
020    import java.util.Map;
021    
022    import org.apache.commons.discovery.ResourceNameDiscover;
023    import org.apache.commons.discovery.ResourceNameIterator;
024    import org.apache.commons.logging.Log;
025    import org.apache.commons.logging.LogFactory;
026    
027    /**
028     * Recover resource name from Managed Properties,
029     * using OLD property names.
030     * 
031     * This class maintains a mapping between old names and
032     * (new) the class names they represent.  The discovery
033     * mechanism uses the class names as property names.
034     * 
035     * @see org.apache.commons.discovery.tools.ManagedProperties
036     */
037    public class DiscoverMappedNames extends ResourceNameDiscoverImpl implements ResourceNameDiscover {
038    
039        private static Log log = LogFactory.getLog(DiscoverMappedNames.class);
040    
041        /**
042         * Sets the {@code Log} for this class.
043         *
044         * @param _log This class {@code Log}
045         * @deprecated This method is not thread-safe
046         */
047        @Deprecated
048        public static void setLog(Log _log) {
049            log = _log;
050        }
051    
052        /**
053         * The String name ==> String[] newNames mapping
054         */
055        private final Map<String, String[]> mapping = new Hashtable<String, String[]>();
056    
057        /**
058         * Construct a new resource discoverer
059         */
060        public DiscoverMappedNames() {
061        }
062    
063        /**
064         * Maps a name to another name.
065         *
066         * @param fromName The name has to be mapped
067         * @param toName The mapping target
068         */
069        public void map(String fromName, String toName) {
070            map(fromName, new String[]{ toName });
071        }
072    
073        /**
074         * Maps a name to multiple names.
075         *
076         * @param fromName The name has to be mapped
077         * @param toNames The mapping targets
078         */
079        public void map(String fromName, String [] toNames) {
080            mapping.put(fromName, toNames);
081        }
082    
083        /**
084         * {@inheritDoc}
085         */
086        @Override
087        public ResourceNameIterator findResourceNames(final String resourceName) {
088            if (log.isDebugEnabled()) {
089                log.debug("find: resourceName='" + resourceName + "', mapping to constants");
090            }
091    
092            final String[] names = mapping.get(resourceName);
093    
094            return new ResourceNameIterator() {
095    
096                private int idx = 0;
097    
098                public boolean hasNext() {
099                    if (names != null) {
100                        while (idx < names.length  &&  names[idx] == null) {
101                            idx++;
102                        }
103                        return idx < names.length;
104                    }
105                    return false;
106                }
107    
108                public String nextResourceName() {
109                    return hasNext() ? names[idx++] : null;
110                }
111            };
112        }
113    
114    }