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