1 package org.apache.maven.plugins.assembly.filter;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.commons.io.input.XmlStreamReader;
23 import org.apache.commons.io.output.XmlStreamWriter;
24 import org.codehaus.plexus.archiver.Archiver;
25 import org.codehaus.plexus.archiver.ArchiverException;
26 import org.codehaus.plexus.archiver.ResourceIterator;
27 import org.codehaus.plexus.archiver.UnArchiver;
28 import org.codehaus.plexus.components.io.fileselectors.FileInfo;
29 import org.codehaus.plexus.util.xml.Xpp3Dom;
30 import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
31 import org.codehaus.plexus.util.xml.Xpp3DomWriter;
32 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
33
34 import javax.inject.Named;
35
36 import java.io.BufferedReader;
37 import java.io.File;
38 import java.io.IOException;
39 import java.io.Reader;
40 import java.io.Writer;
41 import java.nio.file.Files;
42 import java.util.Collections;
43 import java.util.LinkedHashMap;
44 import java.util.List;
45 import java.util.Map;
46
47
48
49
50
51
52
53 @Named( "plexus" )
54 public class ComponentsXmlArchiverFileFilter
55 implements ContainerDescriptorHandler
56 {
57 public static final String COMPONENTS_XML_PATH = "META-INF/plexus/components.xml";
58
59
60
61
62 Map<String, Xpp3Dom> components;
63
64 private boolean excludeOverride = false;
65
66 void addComponentsXml( final Reader componentsReader )
67 throws XmlPullParserException, IOException
68 {
69 Xpp3Dom newDom = Xpp3DomBuilder.build( componentsReader );
70
71 if ( newDom != null )
72 {
73 newDom = newDom.getChild( "components" );
74 }
75
76 if ( newDom != null )
77 {
78 final Xpp3Dom[] children = newDom.getChildren();
79
80 for ( final Xpp3Dom component : children )
81 {
82 if ( components == null )
83 {
84 components = new LinkedHashMap<>();
85 }
86
87 final String role = component.getChild( "role" ).getValue();
88 final Xpp3Dom child = component.getChild( "role-hint" );
89 final String roleHint = child != null ? child.getValue() : "";
90
91 final String key = role + roleHint;
92 if ( !components.containsKey( key ) )
93 {
94 components.put( key, component );
95 }
96 }
97 }
98 }
99
100 private void addToArchive( final Archiver archiver )
101 throws IOException
102 {
103 if ( components != null )
104 {
105 final File f = File.createTempFile( "maven-assembly-plugin", "tmp" );
106 f.deleteOnExit();
107
108
109 try ( Writer fileWriter = new XmlStreamWriter( Files.newOutputStream( f.toPath() ) ) )
110 {
111 final Xpp3Dom dom = new Xpp3Dom( "component-set" );
112 final Xpp3Dom componentDom = new Xpp3Dom( "components" );
113 dom.addChild( componentDom );
114
115 for ( final Xpp3Dom component : components.values() )
116 {
117 componentDom.addChild( component );
118 }
119
120 Xpp3DomWriter.write( fileWriter, dom );
121 }
122
123 excludeOverride = true;
124
125 archiver.addFile( f, COMPONENTS_XML_PATH );
126
127 excludeOverride = false;
128 }
129 }
130
131 @Override
132 public void finalizeArchiveCreation( final Archiver archiver )
133 {
134
135
136
137
138
139 for ( final ResourceIterator it = archiver.getResources(); it.hasNext(); )
140 {
141 it.next();
142 }
143
144 try
145 {
146 addToArchive( archiver );
147 }
148 catch ( final IOException e )
149 {
150 throw new ArchiverException( "Error finalizing component-set for archive. Reason: " + e.getMessage(), e );
151 }
152 }
153
154 @Override
155 public List<String> getVirtualFiles()
156 {
157 if ( ( components != null ) && !components.isEmpty() )
158 {
159 return Collections.singletonList( COMPONENTS_XML_PATH );
160 }
161
162 return null;
163 }
164
165 @Override
166 public boolean isSelected( final FileInfo fileInfo )
167 throws IOException
168 {
169 if ( fileInfo.isFile() )
170 {
171 if ( excludeOverride )
172 {
173 return true;
174 }
175
176 String entry = fileInfo.getName().replace( '\\', '/' );
177
178 if ( entry.startsWith( "/" ) )
179 {
180 entry = entry.substring( 1 );
181 }
182
183 if ( ComponentsXmlArchiverFileFilter.COMPONENTS_XML_PATH.equals( entry ) )
184 {
185 try ( Reader reader = new BufferedReader( new XmlStreamReader( fileInfo.getContents() ) ) )
186 {
187 addComponentsXml( reader );
188 }
189 catch ( final XmlPullParserException e )
190 {
191 final IOException error =
192 new IOException( "Error finalizing component-set for archive. Reason: " + e.getMessage(), e );
193
194 throw error;
195 }
196 return false;
197 }
198 else
199 {
200 return true;
201 }
202 }
203 else
204 {
205 return true;
206 }
207 }
208
209 @Override
210 public void finalizeArchiveExtraction( final UnArchiver unarchiver )
211 {
212 }
213
214 }