View Javadoc
1   package org.codehaus.plexus.metadata;
2   
3   /*
4    * The MIT License
5    * 
6    * Copyright (c) 2004-2006, The Codehaus
7    * 
8    * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
9    * associated documentation files (the "Software"), to deal in the Software without restriction,
10   * including without limitation the rights to use, copy, modify, merge, publish, distribute,
11   * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
12   * furnished to do so, subject to the following conditions:
13   * 
14   * The above copyright notice and this permission notice shall be included in all copies or
15   * substantial portions of the Software.
16   * 
17   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
18   * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
20   * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22   */
23  
24  import java.io.BufferedWriter;
25  import java.io.File;
26  import java.io.FileOutputStream;
27  import java.io.OutputStreamWriter;
28  import java.util.ArrayList;
29  import java.util.Collection;
30  import java.util.Collections;
31  import java.util.Comparator;
32  import java.util.List;
33  import java.util.Map;
34  
35  import org.codehaus.plexus.component.annotations.Component;
36  import org.codehaus.plexus.component.annotations.Requirement;
37  import org.codehaus.plexus.component.repository.ComponentDependency;
38  import org.codehaus.plexus.component.repository.ComponentDescriptor;
39  import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
40  import org.codehaus.plexus.logging.AbstractLogEnabled;
41  import org.codehaus.plexus.metadata.gleaner.AnnotationComponentGleaner;
42  import org.codehaus.plexus.metadata.merge.Merger;
43  import org.codehaus.plexus.util.FileUtils;
44  import org.codehaus.plexus.util.IOUtil;
45  
46  /**
47   * @author Jason van Zyl
48   */
49  @Component(role = MetadataGenerator.class)
50  public class DefaultMetadataGenerator
51      extends AbstractLogEnabled
52      implements MetadataGenerator
53  {
54      @Requirement
55      private Merger merger;
56  
57      private ComponentDescriptor<?>[] roleDefaults;
58  
59      @Requirement
60      private Map<String, ComponentDescriptorExtractor> extractorMap;
61  
62      // should be a component
63      private ComponentDescriptorWriter writer = new DefaultComponentDescriptorWriter();
64  
65      public void generateDescriptor( MetadataGenerationRequest request )
66          throws Exception
67      {
68          assert request.outputFile != null;
69  
70          List<String> extractorHints = request.extractors;
71          
72          final Collection<ComponentDescriptorExtractor> extractors;
73          if ( extractorHints == null || extractorHints.size() == 0 )
74          {
75              extractors = extractorMap.values();
76          }
77          else
78          {
79              extractors = new ArrayList<ComponentDescriptorExtractor>( extractorHints.size() );
80              
81              for ( String hint : extractorHints )
82              {
83                  extractors.add( extractorMap.get( hint ) );
84              }
85          }
86  
87          List<ComponentDescriptor<?>> descriptors = new ArrayList<ComponentDescriptor<?>>();
88  
89          for ( ComponentDescriptorExtractor extractor : extractors )
90          {
91              try
92              {
93                  List<ComponentDescriptor<?>> list = extractor.extract( request, roleDefaults );
94                  if ( list != null && !list.isEmpty() )
95                  {
96                      descriptors.addAll( list );
97                  }
98              }
99              catch ( Exception e )
100             {
101                 throw new Exception( "Failed to extract descriptors", e );
102             }
103         }
104 
105         // Sort the descriptors by key to make the output reproducible
106         Collections.sort( descriptors, new Comparator<ComponentDescriptor>()
107         {
108             public int compare( ComponentDescriptor d1, ComponentDescriptor d2 )
109             {
110                 return d1.getHumanReadableKey().compareTo( d2.getHumanReadableKey() );
111             }
112         });
113 
114         List<File> componentDescriptors = new ArrayList<File>();        
115         
116         //
117         // If we found descriptors, write out the discovered descriptors
118         //
119         if ( descriptors.size() > 0 )
120         {
121             getLogger().info( "Discovered " + descriptors.size() + " component descriptors(s)" );
122 
123             ComponentSetDescriptor set = new ComponentSetDescriptor();
124             set.setComponents( descriptors );
125             set.setDependencies( Collections.<ComponentDependency> emptyList() );
126             
127             if ( request.componentDescriptorDirectory == null )
128             {
129                 writeDescriptor( set, request.outputFile );
130             }
131             else
132             {
133                 if ( request.intermediaryFile == null )
134                 {
135                     request.intermediaryFile = File.createTempFile( "plexus-metadata", "xml" );
136                     request.intermediaryFile.deleteOnExit();
137                 }
138                 writeDescriptor( set, request.intermediaryFile );
139                 componentDescriptors.add( request.intermediaryFile );
140             }
141         }
142         
143 
144         //
145         // Deal with merging
146         //
147         if ( request.componentDescriptorDirectory != null && request.componentDescriptorDirectory.isDirectory() )
148         {
149             File[] files = request.componentDescriptorDirectory.listFiles();
150 
151             for ( File file : files )
152             {
153                 if ( file.getName().endsWith( ".xml" ) && !file.getName().equals( "plexus.xml" ) )
154                 {
155                     componentDescriptors.add( file );
156                 }
157             }
158         }
159 
160         if ( componentDescriptors.size() > 0 )
161         {
162             merger.mergeDescriptors( request.outputFile, componentDescriptors );
163         }
164     }
165 
166     private void writeDescriptor( ComponentSetDescriptor desc, File outputFile )
167         throws Exception
168     {
169         assert desc != null;
170         assert outputFile != null;
171 
172         FileUtils.forceMkdir( outputFile.getParentFile() );
173 
174         BufferedWriter output = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( outputFile ), "UTF-8" ) );
175 
176         try
177         {
178             writer.writeDescriptorSet( output, desc, false );
179             output.flush();
180         }
181         finally
182         {
183             IOUtil.close( output );
184         }
185 
186         getLogger().debug( "Wrote: " + outputFile );
187     }
188 }