001    /*
002     * Copyright 2002-2004 the original author or authors.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.springframework.richclient.image;
017    
018    import java.awt.Image;
019    
020    import javax.swing.Icon;
021    import javax.swing.ImageIcon;
022    
023    import org.apache.commons.logging.Log;
024    import org.apache.commons.logging.LogFactory;
025    import org.springframework.richclient.application.ApplicationServicesLocator;
026    import org.springframework.util.CachingMapDecorator;
027    
028    /**
029     * The default implementation of ImageIconRegistry. This implementation caches
030     * all icons using soft references (TODO it just lazy loads them, but it doesn't use SoftReference).
031     * More specifically, cached icons will remain
032     * in memory unless there is a shortage of resources in the system.
033     * 
034     * @author Keith Donald
035     */
036    public class DefaultIconSource implements IconSource {
037        protected static final Log logger = LogFactory.getLog(DefaultIconSource.class);
038    
039        private IconCache cache;
040    
041        /**
042         * Default constructor.  Will obtain services dependencies from the ApplicationServices
043         * locator.
044         */
045        public DefaultIconSource() {
046            this( (ImageSource)ApplicationServicesLocator.services().getService(ImageSource.class));
047        }
048    
049        /**
050         * Constructs a icon registry that loads images from the provided source.
051         * 
052         * @param images
053         *            the image source.
054         */
055        public DefaultIconSource(ImageSource images) {
056            this.cache = new IconCache(images);
057        }
058    
059        public Icon getIcon(String key) {
060            try {
061                if (logger.isDebugEnabled()) {
062                    logger.debug("Resolving icon with key '" + key + "'");
063                }
064                return (ImageIcon)cache.get(key);
065            }
066            catch (NoSuchImageResourceException e) {
067                if (logger.isInfoEnabled()) {
068                    logger.info("No image resource found for icon with key '" + key + "'; returning a <null> icon.");
069                }
070                return null;
071            }
072        }
073    
074        public void clear() {
075            cache.clear();
076        }
077    
078        protected String doProcessImageKeyBeforeLookup(String key) {
079            // subclasses can override
080            return key;
081        }
082    
083        protected IconCache cache() {
084            return cache;
085        }
086    
087        /**
088         * Icon cache using soft references.
089         * 
090         * @author Keith Donald
091         */
092        protected static class IconCache extends CachingMapDecorator {
093            private ImageSource images;
094    
095            public IconCache(ImageSource images) {
096                super(true);
097                this.images = images;
098            }
099    
100            public Object create(Object key) {
101                Image image = images.getImage((String)key);
102                return new ImageIcon(image);
103            }
104    
105            public ImageSource images() {
106                return images;
107            }
108        }
109    }