This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.common.plexusbridge;
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
022import org.codehaus.plexus.DefaultContainerConfiguration;
023import org.codehaus.plexus.DefaultPlexusContainer;
024import org.codehaus.plexus.PlexusConstants;
025import org.codehaus.plexus.PlexusContainerException;
026import org.codehaus.plexus.classworlds.ClassWorld;
027import org.codehaus.plexus.classworlds.realm.ClassRealm;
028import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031import org.springframework.stereotype.Service;
032
033import javax.annotation.PostConstruct;
034import java.lang.reflect.Method;
035import java.net.URL;
036import java.net.URLClassLoader;
037import java.util.List;
038import java.util.Map;
039
040/**
041 * Simple component which will initiate the plexus shim component
042 * to see plexus components inside a guice container.<br>
043 * So move all of this here to be able to change quickly if needed.
044 *
045 * @author Olivier Lamy
046 */
047@Service( "plexusSisuBridge" )
048public class PlexusSisuBridge
049{
050
051    private Logger log = LoggerFactory.getLogger( getClass() );
052
053    private boolean containerAutoWiring = true;
054
055    private String containerClassPathScanning = PlexusConstants.SCANNING_INDEX;// PlexusConstants.SCANNING_ON;
056
057    private String containerComponentVisibility = PlexusConstants.REALM_VISIBILITY;
058
059    private URL overridingComponentsXml;
060
061    private ClassRealm containerRealm;
062
063    private DefaultPlexusContainer plexusContainer;
064
065    @PostConstruct
066    public void initialize()
067        throws PlexusSisuBridgeException
068    {
069        DefaultContainerConfiguration conf = new DefaultContainerConfiguration();
070
071        conf.setAutoWiring( containerAutoWiring );
072        conf.setClassPathScanning( containerClassPathScanning );
073        conf.setComponentVisibility( containerComponentVisibility );
074
075        conf.setContainerConfigurationURL( overridingComponentsXml );
076
077        ClassWorld classWorld = new ClassWorld();
078
079        ClassLoader tccl = Thread.currentThread().getContextClassLoader();
080
081        containerRealm = new ClassRealm( classWorld, "maven", tccl );
082
083        // olamy hackhish but plexus-sisu need a URLClassLoader with URL filled
084
085        if ( tccl instanceof URLClassLoader )
086        {
087            URL[] urls = ( (URLClassLoader) tccl ).getURLs();
088            for ( URL url : urls )
089            {
090                containerRealm.addURL( url );
091            }
092        }
093
094        conf.setRealm( containerRealm );
095
096        //conf.setClassWorld( classWorld );
097
098        ClassLoader ori = Thread.currentThread().getContextClassLoader();
099
100        try
101        {
102            Thread.currentThread().setContextClassLoader( containerRealm );
103            plexusContainer = new DefaultPlexusContainer( conf );
104        }
105        catch ( PlexusContainerException e )
106        {
107            throw new PlexusSisuBridgeException( e.getMessage(), e );
108        }
109        finally
110        {
111            Thread.currentThread().setContextClassLoader( ori );
112        }
113    }
114
115
116    private URL[] getClassLoaderURLs( ClassLoader classLoader )
117    {
118        try
119        {
120            // can be WebappClassLoader when using tomcat maven plugin
121            //java.net.URL[] getURLs
122            Method method = classLoader.getClass().getMethod( "getURLs", new Class[]{ } );
123            if ( method != null )
124            {
125                return (URL[]) method.invoke( classLoader );
126            }
127        }
128        catch ( Exception e )
129        {
130            log.info( "ignore issue trying to find url[] from classloader {}", e.getMessage() );
131        }
132        return new URL[]{ };
133    }
134
135    public <T> T lookup( Class<T> clazz )
136        throws PlexusSisuBridgeException
137    {
138        ClassLoader ori = Thread.currentThread().getContextClassLoader();
139        try
140        {
141            Thread.currentThread().setContextClassLoader( containerRealm );
142            return plexusContainer.lookup( clazz );
143        }
144        catch ( ComponentLookupException e )
145        {
146            throw new PlexusSisuBridgeException( e.getMessage(), e );
147        }
148        finally
149        {
150            Thread.currentThread().setContextClassLoader( ori );
151        }
152    }
153
154    public <T> T lookup( Class<T> clazz, String hint )
155        throws PlexusSisuBridgeException
156    {
157        ClassLoader ori = Thread.currentThread().getContextClassLoader();
158
159        try
160        {
161            Thread.currentThread().setContextClassLoader( containerRealm );
162            return plexusContainer.lookup( clazz, hint );
163        }
164        catch ( ComponentLookupException e )
165        {
166            throw new PlexusSisuBridgeException( e.getMessage(), e );
167        }
168        finally
169        {
170            Thread.currentThread().setContextClassLoader( ori );
171        }
172    }
173
174    public <T> List<T> lookupList( Class<T> clazz )
175        throws PlexusSisuBridgeException
176    {
177        ClassLoader ori = Thread.currentThread().getContextClassLoader();
178
179        try
180        {
181            Thread.currentThread().setContextClassLoader( containerRealm );
182            return plexusContainer.lookupList( clazz );
183        }
184        catch ( ComponentLookupException e )
185        {
186            throw new PlexusSisuBridgeException( e.getMessage(), e );
187        }
188        finally
189        {
190            Thread.currentThread().setContextClassLoader( ori );
191        }
192    }
193
194    public <T> Map<String, T> lookupMap( Class<T> clazz )
195        throws PlexusSisuBridgeException
196    {
197        ClassLoader ori = Thread.currentThread().getContextClassLoader();
198
199        try
200        {
201            Thread.currentThread().setContextClassLoader( containerRealm );
202            return plexusContainer.lookupMap( clazz );
203        }
204        catch ( ComponentLookupException e )
205        {
206            throw new PlexusSisuBridgeException( e.getMessage(), e );
207        }
208        finally
209        {
210            Thread.currentThread().setContextClassLoader( ori );
211        }
212    }
213}