001    package org.apache.archiva.proxy.common;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     *  http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    import org.apache.commons.lang.StringUtils;
023    import org.apache.maven.wagon.Wagon;
024    import org.slf4j.Logger;
025    import org.slf4j.LoggerFactory;
026    import org.springframework.beans.BeansException;
027    import org.springframework.context.ApplicationContext;
028    import org.springframework.stereotype.Service;
029    
030    import javax.inject.Inject;
031    import java.lang.reflect.Method;
032    import java.util.Map;
033    import java.util.Properties;
034    
035    /**
036     * @author Olivier Lamy
037     * @since 1.4-M1
038     */
039    @Service ("wagonFactory")
040    public class DefaultWagonFactory
041        implements WagonFactory
042    {
043    
044        private ApplicationContext applicationContext;
045    
046        private Logger logger = LoggerFactory.getLogger( getClass() );
047    
048        private DebugTransferListener debugTransferListener = new DebugTransferListener();
049    
050        @Inject
051        public DefaultWagonFactory( ApplicationContext applicationContext )
052        {
053            this.applicationContext = applicationContext;
054        }
055    
056        public Wagon getWagon( WagonFactoryRequest wagonFactoryRequest )
057            throws WagonFactoryException
058        {
059            try
060            {
061                String protocol = StringUtils.startsWith( wagonFactoryRequest.getProtocol(), "wagon#" )
062                    ? wagonFactoryRequest.getProtocol()
063                    : "wagon#" + wagonFactoryRequest.getProtocol();
064    
065                // if it's a ntlm proxy we have to lookup the wagon light which support thats
066                // wagon http client doesn't support that
067                if ( wagonFactoryRequest.getNetworkProxy() != null && wagonFactoryRequest.getNetworkProxy().isUseNtlm() )
068                {
069                    protocol = protocol + "-ntlm";
070                }
071    
072                Wagon wagon = applicationContext.getBean( protocol, Wagon.class );
073                wagon.addTransferListener( debugTransferListener );
074                configureUserAgent( wagon, wagonFactoryRequest );
075                return wagon;
076            }
077            catch ( BeansException e )
078            {
079                throw new WagonFactoryException( e.getMessage(), e );
080            }
081        }
082    
083        protected void configureUserAgent( Wagon wagon, WagonFactoryRequest wagonFactoryRequest )
084        {
085            try
086            {
087                Class clazz = wagon.getClass();
088                Method getHttpHeaders = clazz.getMethod( "getHttpHeaders", null );
089    
090                Properties headers = (Properties) getHttpHeaders.invoke( wagon, null );
091                if ( headers == null )
092                {
093                    headers = new Properties();
094                }
095    
096                headers.put( "User-Agent", wagonFactoryRequest.getUserAgent() );
097    
098                if ( !wagonFactoryRequest.getHeaders().isEmpty() )
099                {
100                    for ( Map.Entry<String, String> entry : wagonFactoryRequest.getHeaders().entrySet() )
101                    {
102                        headers.put( entry.getKey(), entry.getValue() );
103                    }
104                }
105    
106                Method setHttpHeaders = clazz.getMethod( "setHttpHeaders", new Class[]{ Properties.class } );
107                setHttpHeaders.invoke( wagon, headers );
108    
109                logger.debug( "http headers set to: {}", headers );
110            }
111            catch ( Exception e )
112            {
113                logger.warn( "fail to configure User-Agent: " + e.getMessage(), e );
114            }
115        }
116    }