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