View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *  http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.maven.toolchain;
21  
22  import java.io.BufferedInputStream;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.io.InputStreamReader;
27  import java.lang.reflect.InvocationTargetException;
28  import java.lang.reflect.Method;
29  import java.util.ArrayList;
30  import java.util.Collections;
31  import java.util.HashMap;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.Map;
35  import org.apache.maven.execution.MavenSession;
36  import org.apache.maven.plugin.descriptor.PluginDescriptor;
37  import org.apache.maven.project.MavenProject;
38  import org.apache.maven.toolchain.model.PersistedToolchains;
39  import org.apache.maven.toolchain.model.ToolchainModel;
40  import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader;
41  import org.codehaus.plexus.PlexusConstants;
42  import org.codehaus.plexus.PlexusContainer;
43  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
44  import org.codehaus.plexus.context.Context;
45  import org.codehaus.plexus.context.ContextException;
46  import org.codehaus.plexus.logging.AbstractLogEnabled;
47  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
48  
49  /**
50   *
51   * @author mkleint
52   */
53  public class DefaultToolchainManager extends AbstractLogEnabled
54      implements ToolchainManager,
55                 ToolchainManagerPrivate,
56                 Contextualizable
57  {
58  
59      /**
60       * @component
61       */
62      private PlexusContainer container;
63  
64      public DefaultToolchainManager( )
65      {
66      }
67  
68      public void contextualize( Context context )
69          throws ContextException
70      {
71          container = (PlexusContainer) context.get(PlexusConstants.PLEXUS_KEY);
72      }
73  
74      public ToolchainPrivate[] getToolchainsForType( String type )
75          throws MisconfiguredToolchainException
76      {
77          try
78          {
79              PersistedToolchains pers = readToolchainSettings ();
80              Map factories = container.lookupMap( ToolchainFactory.ROLE );
81              List toRet = new ArrayList(  );
82              if ( pers != null )
83              {
84                  List lst = pers.getToolchains();
85                  if ( lst != null )
86                  {
87                      Iterator it = lst.iterator();
88                      while ( it.hasNext() )
89                      {
90                          ToolchainModel toolchainModel = (ToolchainModel) it.next();
91                          ToolchainFactory fact = (ToolchainFactory) factories.get( toolchainModel.getType() );
92                          if ( fact != null )
93                          {
94                              toRet.add( fact.createToolchain( toolchainModel ) );
95                          }
96                          else
97                          {
98                              getLogger().error("Missing toolchain factory for type:" + toolchainModel.getType() + ". Possibly caused by misconfigured project.");
99                          }
100                     }
101                 }
102             }
103             Iterator it = factories.values().iterator();
104             while ( it.hasNext() )
105             {
106                 ToolchainFactory fact = (ToolchainFactory) it.next();
107                 ToolchainPrivate tool = fact.createDefaultToolchain();
108                 if ( tool != null )
109                 {
110                     toRet.add( tool );
111                 }
112             }
113             ToolchainPrivate[] tc = new ToolchainPrivate[ toRet.size() ];
114             return (ToolchainPrivate[]) toRet.toArray(tc);
115         }
116         catch ( ComponentLookupException ex )
117         {
118             getLogger().fatalError("Error in component lookup", ex);
119         }
120         return new ToolchainPrivate[0];
121     }
122 
123     public Toolchain getToolchainFromBuildContext( String type,
124                                                    MavenSession session )
125     {
126         Map context = retrieveContext(session);
127         if ( "javac".equals( type )) 
128         {
129             //HACK to make compiler plugin happy
130             type = "jdk";
131         }
132         Object obj = context.get( getStorageKey( type ) );
133         ToolchainModel model = (ToolchainModel)obj;
134         
135         if ( model != null ) 
136         {
137             try
138             {
139                 ToolchainFactory fact = (ToolchainFactory) container.lookup(ToolchainFactory.ROLE, type);
140                 return fact.createToolchain( model );
141             }
142             catch ( ComponentLookupException ex )
143             {
144                 getLogger().fatalError("Error in component lookup", ex);
145             }
146             catch ( MisconfiguredToolchainException ex )
147             {
148                 getLogger().error("Misconfigured toolchain.", ex);
149             }
150         }
151         return null;
152     }
153 
154     private MavenProject getCurrentProject(MavenSession session) {
155         //use reflection since MavenSession.getCurrentProject() is not part of 3.0.8
156         try 
157         {
158             Method meth = session.getClass().getMethod("getCurrentProject", new Class[0]);
159             return (MavenProject) meth.invoke(session, null);
160         } catch (Exception ex) 
161         {
162             //just ignore, we're running in pre- 3.0.9
163         }
164         return null;
165     }
166     
167     private Map retrieveContext( MavenSession session ) 
168     {
169         if (session == null) 
170         {
171             return new HashMap();
172         }
173         PluginDescriptor desc = new PluginDescriptor();
174         desc.setGroupId( PluginDescriptor.getDefaultPluginGroupId() );
175         desc.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId ("toolchains") );
176         MavenProject current = getCurrentProject(session);
177         if ( current != null ) 
178         {
179             return session.getPluginContext( desc, current );
180             
181         }
182         return new HashMap();
183     }
184     
185 
186     public void storeToolchainToBuildContext( ToolchainPrivate toolchain,
187                                               MavenSession session )
188     {
189         Map context = retrieveContext( session );
190         context.put( getStorageKey( toolchain.getType() ), toolchain.getModel () );
191     }
192     
193     public static final String getStorageKey( String type )
194     {
195         return "toolchain-" + type; //NOI18N
196     }
197     
198 
199     private PersistedToolchains readToolchainSettings( )
200         throws MisconfiguredToolchainException
201     {
202         //TODO how to point to the local path?
203         File tch = new File( System.getProperty( "user.home" ),
204             ".m2/toolchains.xml" );
205         if ( tch.exists() )
206         {
207             MavenToolchainsXpp3Reader reader = new MavenToolchainsXpp3Reader();
208             InputStreamReader in = null;
209             try
210             {
211                 in = new InputStreamReader( new BufferedInputStream( new FileInputStream( tch ) ) );
212                 return reader.read( in );
213             }
214             catch ( Exception ex )
215             {
216                 throw new MisconfiguredToolchainException( "Cannot read toolchains file at " + tch.getAbsolutePath(  ),
217                     ex );
218             }
219             finally
220             {
221                 if (in != null) 
222                 {
223                     try 
224                     {
225                         in.close();
226                     } 
227                     catch (IOException ex) 
228                     { }
229                 }
230 //                IOUtil.close( in );
231             }
232         }
233         else
234         {
235             //TODO log the fact that no toolchains file was found.
236         }
237         return null;
238     }
239 }