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