001    /*
002     * Copyright (C) 2006-2007 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    
017    package org.codehaus.gmaven.runtime.loader;
018    
019    import org.apache.commons.lang.time.StopWatch;
020    import org.codehaus.gmaven.feature.Provider;
021    import org.codehaus.gmaven.feature.ProviderException;
022    import org.codehaus.gmaven.feature.ProviderManager;
023    import org.codehaus.gmaven.feature.ProviderRegistry;
024    import org.codehaus.gmaven.feature.ProviderSelector;
025    import org.slf4j.Logger;
026    import org.slf4j.LoggerFactory;
027    
028    import java.util.HashMap;
029    import java.util.Map;
030    
031    /**
032     * Default {@link ProviderManager}.
033     *
034     * @plexus.component role="org.codehaus.gmaven.feature.ProviderManager"
035     *
036     * @version $Id: DefaultProviderManager.java 21 2009-07-16 09:42:35Z user57 $
037     * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
038     */
039    public class DefaultProviderManager
040        implements ProviderManager
041    {
042        private final Logger log = LoggerFactory.getLogger(getClass());
043    
044        private Map cachedSelection = new HashMap();
045    
046        /**
047         * @plexus.requirement
048         *
049         * @noinspection UnusedDeclaration
050         */
051        private ProviderRegistry registry;
052    
053        /**
054         * @plexus.requirement
055         *
056         * @noinspection UnusedDeclaration
057         */
058        private ProviderSelector selector;
059    
060        public ProviderRegistry getRegistry() {
061            if (registry == null) {
062                throw new IllegalStateException("Registry not bound");
063            }
064    
065            return registry;
066        }
067    
068        public ProviderSelector getSelector() {
069            if (registry == null) {
070                throw new IllegalStateException("Selector not bound");
071            }
072    
073            return selector;
074        }
075    
076        //
077        // TODO: Expose more default selection API
078        //
079    
080        private String getDefaultSelection() {
081            return ProviderSelector.SELECT_DEFAULT;
082        }
083    
084        //
085        // TODO: Add loader and provider dynamic look up?
086        //
087    
088        public Provider select(final String selection) {
089            assert selection != null;
090    
091            Provider provider = (Provider) cachedSelection.get(selection);
092            if (provider != null) {
093                log.debug("Using cached provider '{}' for selection: {}", provider, selection);    
094            }
095            else {
096                log.debug("Selecting provider; selection: {}", selection);
097    
098                StopWatch watch = new StopWatch();
099                watch.start();
100    
101                try {
102                    provider = getSelector().select(getRegistry(), selection);
103                }
104                catch (Exception e) {
105                    throw new ProviderException("Selection of provider failed; selection: " + selection, e);
106                }
107    
108                if (provider == null) {
109                    throw new ProviderException("No providers found matching selection: " + selection);
110                }
111    
112                cachedSelection.put(selection, provider);
113                
114                watch.stop();
115    
116                log.debug("Selected provider: {} ({})", provider, watch);
117            }
118    
119            return provider;
120        }
121    
122        public Provider select() {
123            return select(getDefaultSelection());
124        }
125    }