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  package org.apache.maven.plugins.assembly.filter;
20  
21  import java.io.BufferedReader;
22  import java.io.File;
23  import java.io.FileOutputStream;
24  import java.io.IOException;
25  import java.io.InputStreamReader;
26  import java.io.OutputStreamWriter;
27  import java.io.PrintWriter;
28  import java.nio.file.Files;
29  import java.util.ArrayList;
30  import java.util.HashMap;
31  import java.util.List;
32  import java.util.Map;
33  
34  import org.apache.maven.plugins.assembly.utils.AssemblyFileUtils;
35  import org.codehaus.plexus.archiver.Archiver;
36  import org.codehaus.plexus.archiver.ArchiverException;
37  import org.codehaus.plexus.archiver.ResourceIterator;
38  import org.codehaus.plexus.archiver.UnArchiver;
39  import org.codehaus.plexus.components.io.fileselectors.FileInfo;
40  
41  abstract class AbstractLineAggregatingHandler implements ContainerDescriptorHandler {
42  
43      private Map<String, List<String>> catalog = new HashMap<>();
44  
45      private boolean excludeOverride = false;
46  
47      protected abstract String getOutputPathPrefix(FileInfo fileInfo);
48  
49      protected abstract boolean fileMatches(FileInfo fileInfo);
50  
51      String getEncoding() {
52          return "UTF-8";
53      }
54  
55      @Override
56      public void finalizeArchiveCreation(final Archiver archiver) {
57          // this will prompt the isSelected() call, below, for all resources added to the archive.
58          // FIXME: This needs to be corrected in the AbstractArchiver, where
59          // runArchiveFinalizers() is called before regular resources are added...
60          // which is done because the manifest needs to be added first, and the
61          // manifest-creation component is a finalizer in the assembly plugin...
62          for (final ResourceIterator it = archiver.getResources(); it.hasNext(); ) {
63              it.next();
64          }
65  
66          addToArchive(archiver);
67      }
68  
69      void addToArchive(final Archiver archiver) {
70          for (final Map.Entry<String, List<String>> entry : catalog.entrySet()) {
71              final String name = entry.getKey();
72              final String fname = new File(name).getName();
73  
74              File f;
75              try {
76                  f = Files.createTempFile("assembly-" + fname, ".tmp").toFile();
77                  f.deleteOnExit();
78  
79                  try (PrintWriter writer =
80                          new PrintWriter(new OutputStreamWriter(new FileOutputStream(f), getEncoding()))) {
81                      for (final String line : entry.getValue()) {
82                          writer.println(line);
83                      }
84                  }
85              } catch (final IOException e) {
86                  throw new ArchiverException(
87                          "Error adding aggregated content for: " + fname + " to finalize archive creation. Reason: "
88                                  + e.getMessage(),
89                          e);
90              }
91  
92              excludeOverride = true;
93              archiver.addFile(f, name);
94              excludeOverride = false;
95          }
96      }
97  
98      @Override
99      public void finalizeArchiveExtraction(final UnArchiver unArchiver) {}
100 
101     @Override
102     public List<String> getVirtualFiles() {
103         return new ArrayList<>(catalog.keySet());
104     }
105 
106     @Override
107     public boolean isSelected(final FileInfo fileInfo) throws IOException {
108         if (excludeOverride) {
109             return true;
110         }
111 
112         String name = AssemblyFileUtils.normalizeFileInfo(fileInfo);
113 
114         if (fileInfo.isFile() && fileMatches(fileInfo)) {
115             name = getOutputPathPrefix(fileInfo) + new File(name).getName();
116 
117             List<String> lines = catalog.get(name);
118             if (lines == null) {
119                 lines = new ArrayList<>();
120                 catalog.put(name, lines);
121             }
122 
123             readLines(fileInfo, lines);
124 
125             return false;
126         }
127 
128         return true;
129     }
130 
131     void readLines(final FileInfo fileInfo, final List<String> lines) throws IOException {
132         try (BufferedReader reader = new BufferedReader(new InputStreamReader(fileInfo.getContents(), getEncoding()))) {
133             for (String line = reader.readLine(); line != null; line = reader.readLine()) {
134                 if (!lines.contains(line)) {
135                     lines.add(line);
136                 }
137             }
138         }
139     }
140 
141     protected final Map<String, List<String>> getCatalog() {
142         return catalog;
143     }
144 
145     protected final void setCatalog(final Map<String, List<String>> catalog) {
146         this.catalog = catalog;
147     }
148 }