This project has retired. For details please refer to its Attic page.
PlexusSisuBridge xref
View Javadoc
1   package org.apache.archiva.common.plexusbridge;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import com.google.inject.AbstractModule;
23  import org.apache.maven.bridge.MavenRepositorySystem;
24  import org.codehaus.plexus.DefaultContainerConfiguration;
25  import org.codehaus.plexus.DefaultPlexusContainer;
26  import org.codehaus.plexus.PlexusConstants;
27  import org.codehaus.plexus.PlexusContainerException;
28  import org.codehaus.plexus.classworlds.ClassWorld;
29  import org.codehaus.plexus.classworlds.realm.ClassRealm;
30  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
31  import org.eclipse.sisu.inject.TypeArguments;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  import org.springframework.stereotype.Service;
35  
36  import javax.annotation.PostConstruct;
37  import javax.inject.Inject;
38  import java.lang.reflect.Method;
39  import java.net.URL;
40  import java.net.URLClassLoader;
41  import java.util.List;
42  import java.util.Map;
43  
44  /**
45   * Simple component which will initiate the plexus shim component
46   * to see plexus components inside a guice container.<br>
47   * So move all of this here to be able to change quickly if needed.
48   *
49   * @author Olivier Lamy
50   */
51  @Service( "plexusSisuBridge" )
52  public class PlexusSisuBridge
53  {
54  
55      private MavenRepositorySystem mavenRepositorySystem = new MavenRepositorySystem();
56  
57      private Logger log = LoggerFactory.getLogger( getClass() );
58  
59      private boolean containerAutoWiring = true;
60  
61      private String containerClassPathScanning = PlexusConstants.SCANNING_INDEX;// PlexusConstants.SCANNING_ON;
62  
63      private String containerComponentVisibility = PlexusConstants.REALM_VISIBILITY;
64  
65      private URL overridingComponentsXml;
66  
67      private ClassRealm containerRealm;
68  
69      private DefaultPlexusContainer plexusContainer;
70  
71      class InternalBinder extends AbstractModule {
72  
73          @Override
74          protected void configure( )
75          {
76              bind( MavenRepositorySystem.class ).toInstance( mavenRepositorySystem );
77              // bind(TypeArguments.implicitKey( MavenRepositorySystem.class )).to(MavenRepositorySystem.class);
78          }
79      }
80  
81      @PostConstruct
82      public void initialize()
83          throws PlexusSisuBridgeException
84      {
85          DefaultContainerConfiguration conf = new DefaultContainerConfiguration();
86  
87          conf.setAutoWiring( containerAutoWiring );
88          conf.setClassPathScanning( containerClassPathScanning );
89          conf.setComponentVisibility( containerComponentVisibility );
90  
91          conf.setContainerConfigurationURL( overridingComponentsXml );
92  
93          ClassWorld classWorld = new ClassWorld();
94  
95          ClassLoader tccl = Thread.currentThread().getContextClassLoader();
96  
97          containerRealm = new ClassRealm( classWorld, "maven", tccl );
98  
99          // olamy hackhish but plexus-sisu need a URLClassLoader with URL filled
100 
101         if ( tccl instanceof URLClassLoader )
102         {
103             URL[] urls = ( (URLClassLoader) tccl ).getURLs();
104             for ( URL url : urls )
105             {
106                 containerRealm.addURL( url );
107                 log.debug("Added url {}", url);
108             }
109         }
110 
111         conf.setRealm( containerRealm );
112 
113         //conf.setClassWorld( classWorld );
114 
115         ClassLoader ori = Thread.currentThread().getContextClassLoader();
116 
117         try
118         {
119             Thread.currentThread().setContextClassLoader( containerRealm );
120             InternalBinder binder = new InternalBinder( );
121             plexusContainer = new DefaultPlexusContainer( conf, binder );
122 
123         }
124         catch ( PlexusContainerException e )
125         {
126             throw new PlexusSisuBridgeException( e.getMessage(), e );
127         } catch (Throwable ex) {
128             log.error("PlexusSisuBridge initialization failed {}", ex.getMessage(), ex);
129             throw new PlexusSisuBridgeException( ex.getMessage(), ex );
130         }
131         finally
132         {
133             Thread.currentThread().setContextClassLoader( ori );
134         }
135     }
136 
137 
138     private URL[] getClassLoaderURLs( ClassLoader classLoader )
139     {
140         try
141         {
142             // can be WebappClassLoader when using tomcat maven plugin
143             //java.net.URL[] getURLs
144             Method method = classLoader.getClass().getMethod( "getURLs", new Class[]{ } );
145             if ( method != null )
146             {
147                 return (URL[]) method.invoke( classLoader );
148             }
149         }
150         catch ( Exception e )
151         {
152             log.info( "ignore issue trying to find url[] from classloader {}", e.getMessage() );
153         }
154         return new URL[]{ };
155     }
156 
157     public <T> T lookup( Class<T> clazz )
158         throws PlexusSisuBridgeException
159     {
160         ClassLoader ori = Thread.currentThread().getContextClassLoader();
161         try
162         {
163             Thread.currentThread().setContextClassLoader( containerRealm );
164             return plexusContainer.lookup( clazz );
165         }
166         catch ( ComponentLookupException e )
167         {
168             throw new PlexusSisuBridgeException( e.getMessage(), e );
169         }
170         finally
171         {
172             Thread.currentThread().setContextClassLoader( ori );
173         }
174     }
175 
176     public <T> T lookup( Class<T> clazz, String hint )
177         throws PlexusSisuBridgeException
178     {
179         ClassLoader ori = Thread.currentThread().getContextClassLoader();
180 
181         try
182         {
183             Thread.currentThread().setContextClassLoader( containerRealm );
184             return plexusContainer.lookup( clazz, hint );
185         }
186         catch ( ComponentLookupException e )
187         {
188             throw new PlexusSisuBridgeException( e.getMessage(), e );
189         }
190         finally
191         {
192             Thread.currentThread().setContextClassLoader( ori );
193         }
194     }
195 
196     public <T> List<T> lookupList( Class<T> clazz )
197         throws PlexusSisuBridgeException
198     {
199         ClassLoader ori = Thread.currentThread().getContextClassLoader();
200 
201         try
202         {
203             Thread.currentThread().setContextClassLoader( containerRealm );
204             return plexusContainer.lookupList( clazz );
205         }
206         catch ( ComponentLookupException e )
207         {
208             throw new PlexusSisuBridgeException( e.getMessage(), e );
209         }
210         finally
211         {
212             Thread.currentThread().setContextClassLoader( ori );
213         }
214     }
215 
216     public <T> Map<String, T> lookupMap( Class<T> clazz )
217         throws PlexusSisuBridgeException
218     {
219         ClassLoader ori = Thread.currentThread().getContextClassLoader();
220 
221         try
222         {
223             Thread.currentThread().setContextClassLoader( containerRealm );
224             return plexusContainer.lookupMap( clazz );
225         }
226         catch ( ComponentLookupException e )
227         {
228             throw new PlexusSisuBridgeException( e.getMessage(), e );
229         }
230         finally
231         {
232             Thread.currentThread().setContextClassLoader( ori );
233         }
234     }
235 }