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.Arrays;
30  import java.util.Collection;
31  import java.util.Collections;
32  import java.util.Comparator;
33  import java.util.List;
34  import java.util.Map;
35  
36  import org.codehaus.plexus.component.annotations.Component;
37  import org.codehaus.plexus.component.annotations.Requirement;
38  import org.codehaus.plexus.component.repository.ComponentDependency;
39  import org.codehaus.plexus.component.repository.ComponentDescriptor;
40  import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
41  import org.codehaus.plexus.logging.AbstractLogEnabled;
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 extends AbstractLogEnabled implements MetadataGenerator {
51      @Requirement
52      private Merger merger;
53  
54      private ComponentDescriptor<?>[] roleDefaults;
55  
56      @Requirement
57      private Map<String, ComponentDescriptorExtractor> extractorMap;
58  
59      // should be a component
60      private ComponentDescriptorWriter writer = new DefaultComponentDescriptorWriter();
61  
62      public void generateDescriptor(MetadataGenerationRequest request) throws Exception {
63          assert request.outputFile != null;
64  
65          List<String> extractorHints = request.extractors;
66  
67          final Collection<ComponentDescriptorExtractor> extractors;
68          if (extractorHints == null || extractorHints.size() == 0) {
69              extractors = extractorMap.values();
70          } else {
71              extractors = new ArrayList<ComponentDescriptorExtractor>(extractorHints.size());
72  
73              for (String hint : extractorHints) {
74                  extractors.add(extractorMap.get(hint));
75              }
76          }
77  
78          List<ComponentDescriptor<?>> descriptors = new ArrayList<ComponentDescriptor<?>>();
79  
80          for (ComponentDescriptorExtractor extractor : extractors) {
81              try {
82                  List<ComponentDescriptor<?>> list = extractor.extract(request, roleDefaults);
83                  if (list != null && !list.isEmpty()) {
84                      descriptors.addAll(list);
85                  }
86              } catch (Exception e) {
87                  throw new Exception("Failed to extract descriptors", e);
88              }
89          }
90  
91          // Sort the descriptors by key to make the output reproducible
92          Collections.sort(descriptors, new Comparator<ComponentDescriptor>() {
93              public int compare(ComponentDescriptor d1, ComponentDescriptor d2) {
94                  return d1.getHumanReadableKey().compareTo(d2.getHumanReadableKey());
95              }
96          });
97  
98          List<File> componentDescriptors = new ArrayList<File>();
99  
100         //
101         // If we found descriptors, write out the discovered descriptors
102         //
103         if (descriptors.size() > 0) {
104             getLogger().info("Discovered " + descriptors.size() + " component descriptor(s)");
105 
106             ComponentSetDescriptor set = new ComponentSetDescriptor();
107             set.setComponents(descriptors);
108             set.setDependencies(Collections.<ComponentDependency>emptyList());
109 
110             if (request.componentDescriptorDirectory == null) {
111                 writeDescriptor(set, request.outputFile);
112             } else {
113                 if (request.intermediaryFile == null) {
114                     request.intermediaryFile = File.createTempFile("plexus-metadata", "xml");
115                     request.intermediaryFile.deleteOnExit();
116                 }
117                 writeDescriptor(set, request.intermediaryFile);
118                 componentDescriptors.add(request.intermediaryFile);
119             }
120         }
121 
122         //
123         // Deal with merging
124         //
125         if (request.componentDescriptorDirectory != null && request.componentDescriptorDirectory.isDirectory()) {
126             File[] files = request.componentDescriptorDirectory.listFiles();
127 
128             // Sort the files by name to make the output reproducible
129             Arrays.sort(files, new Comparator<File>() {
130                 public int compare(File f1, File f2) {
131                     return f1.getName().compareTo(f2.getName());
132                 }
133             });
134 
135             int added = 0;
136             for (File file : files) {
137                 if (file.getName().endsWith(".xml") && !file.getName().equals("plexus.xml")) {
138                     componentDescriptors.add(file);
139                     added++;
140                 }
141             }
142 
143             getLogger().info("Merging " + added + " manually-crafted descriptor file(s)");
144         }
145 
146         if (componentDescriptors.size() > 0) {
147             merger.mergeDescriptors(request.outputFile, componentDescriptors);
148         }
149     }
150 
151     private void writeDescriptor(ComponentSetDescriptor desc, File outputFile) throws Exception {
152         assert desc != null;
153         assert outputFile != null;
154 
155         FileUtils.forceMkdir(outputFile.getParentFile());
156 
157         BufferedWriter output = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8"));
158 
159         try {
160             writer.writeDescriptorSet(output, desc, false);
161             output.flush();
162         } finally {
163             IOUtil.close(output);
164         }
165 
166         getLogger().debug("Wrote: " + outputFile);
167     }
168 }