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.InputStreamReader;
26  import java.lang.reflect.Method;
27  import java.util.ArrayList;
28  import java.util.HashMap;
29  import java.util.Iterator;
30  import java.util.List;
31  import java.util.Map;
32  
33  import org.apache.maven.execution.MavenSession;
34  import org.apache.maven.plugin.descriptor.PluginDescriptor;
35  import org.apache.maven.project.MavenProject;
36  import org.apache.maven.toolchain.model.PersistedToolchains;
37  import org.apache.maven.toolchain.model.ToolchainModel;
38  import org.apache.maven.toolchain.model.io.xpp3.MavenToolchainsXpp3Reader;
39  import org.codehaus.plexus.PlexusConstants;
40  import org.codehaus.plexus.PlexusContainer;
41  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
42  import org.codehaus.plexus.context.Context;
43  import org.codehaus.plexus.context.ContextException;
44  import org.codehaus.plexus.logging.AbstractLogEnabled;
45  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
46  import org.codehaus.plexus.util.IOUtil;
47  
48  /**
49   *
50   * @author mkleint
51   */
52  public class DefaultToolchainManager extends AbstractLogEnabled
53      implements ToolchainManager,
54                 ToolchainManagerPrivate,
55                 Contextualizable
56  {
57  
58      /**
59       * @component
60       */
61      private PlexusContainer container;
62  
63      public DefaultToolchainManager( )
64      {
65      }
66  
67      public void contextualize( Context context )
68          throws ContextException
69      {
70          container = (PlexusContainer) context.get(PlexusConstants.PLEXUS_KEY);
71      }
72  
73      public ToolchainPrivate[] getToolchainsForType( String type )
74          throws MisconfiguredToolchainException
75      {
76          try
77          {
78              PersistedToolchains pers = readToolchainSettings ();
79              Map factories = container.lookupMap( ToolchainFactory.ROLE );
80              List toRet = new ArrayList(  );
81              if ( pers != null )
82              {
83                  List lst = pers.getToolchains();
84                  if ( lst != null )
85                  {
86                      Iterator it = lst.iterator();
87                      while ( it.hasNext() )
88                      {
89                          ToolchainModel toolchainModel = (ToolchainModel) it.next();
90                          ToolchainFactory fact = (ToolchainFactory) factories.get( toolchainModel.getType() );
91                          if ( fact != null )
92                          {
93                              toRet.add( fact.createToolchain( toolchainModel ) );
94                          }
95                          else
96                          {
97                              getLogger().error("Missing toolchain factory for type:" + toolchainModel.getType() + ". Possibly caused by misconfigured project.");
98                          }
99                      }
100                 }
101             }
102             Iterator it = factories.values().iterator();
103             while ( it.hasNext() )
104             {
105                 ToolchainFactory fact = (ToolchainFactory) it.next();
106                 ToolchainPrivate tool = fact.createDefaultToolchain();
107                 if ( tool != null )
108                 {
109                     toRet.add( tool );
110                 }
111             }
112             ToolchainPrivate[] tc = new ToolchainPrivate[ toRet.size() ];
113             return (ToolchainPrivate[]) toRet.toArray(tc);
114         }
115         catch ( ComponentLookupException ex )
116         {
117             getLogger().fatalError("Error in component lookup", ex);
118         }
119         return new ToolchainPrivate[0];
120     }
121 
122     public Toolchain getToolchainFromBuildContext( String type,
123                                                    MavenSession session )
124     {
125         Map context = retrieveContext(session);
126         if ( "javac".equals( type )) 
127         {
128             //HACK to make compiler plugin happy
129             type = "jdk";
130         }
131         Object obj = context.get( getStorageKey( type ) );
132         ToolchainModel model = (ToolchainModel)obj;
133         
134         if ( model != null ) 
135         {
136             try
137             {
138                 ToolchainFactory fact = (ToolchainFactory) container.lookup(ToolchainFactory.ROLE, type);
139                 return fact.createToolchain( model );
140             }
141             catch ( ComponentLookupException ex )
142             {
143                 getLogger().fatalError("Error in component lookup", ex);
144             }
145             catch ( MisconfiguredToolchainException ex )
146             {
147                 getLogger().error("Misconfigured toolchain.", ex);
148             }
149         }
150         return null;
151     }
152 
153     private MavenProject getCurrentProject(MavenSession session) {
154         //use reflection since MavenSession.getCurrentProject() is not part of 2.0.8
155         try 
156         {
157             Method meth = session.getClass().getMethod("getCurrentProject", new Class[0]);
158             return (MavenProject) meth.invoke(session, null);
159         } catch (Exception ex) 
160         {
161             //just ignore, we're running in pre- 2.0.9
162         }
163         return null;
164     }
165     
166     private Map retrieveContext( MavenSession session ) 
167     {
168         if (session == null) 
169         {
170             return new HashMap();
171         }
172         PluginDescriptor desc = new PluginDescriptor();
173         desc.setGroupId( PluginDescriptor.getDefaultPluginGroupId() );
174         desc.setArtifactId( PluginDescriptor.getDefaultPluginArtifactId ("toolchains") );
175         MavenProject current = getCurrentProject(session);
176         if ( current != null ) 
177         {
178             return session.getPluginContext( desc, current );
179             
180         }
181         return new HashMap();
182     }
183     
184 
185     public void storeToolchainToBuildContext( ToolchainPrivate toolchain,
186                                               MavenSession session )
187     {
188         Map context = retrieveContext( session );
189         context.put( getStorageKey( toolchain.getType() ), toolchain.getModel () );
190     }
191     
192     public static final String getStorageKey( String type )
193     {
194         return "toolchain-" + type; //NOI18N
195     }
196     
197 
198     private PersistedToolchains readToolchainSettings( )
199         throws MisconfiguredToolchainException
200     {
201         //TODO how to point to the local path?
202         File tch = new File( System.getProperty( "user.home" ),
203             ".m2/toolchains.xml" );
204         if ( tch.exists() )
205         {
206             MavenToolchainsXpp3Reader reader = new MavenToolchainsXpp3Reader();
207             InputStreamReader in = null;
208             try
209             {
210                 in = new InputStreamReader( new BufferedInputStream( new FileInputStream( tch ) ) );
211                 return reader.read( in );
212             }
213             catch ( Exception ex )
214             {
215                 throw new MisconfiguredToolchainException( "Cannot read toolchains file at " + tch.getAbsolutePath(  ),
216                     ex );
217             }
218             finally
219             {
220                 IOUtil.close( in );
221             }
222         }
223         else
224         {
225             //TODO log the fact that no toolchains file was found.
226         }
227         return null;
228     }
229 }