1 package org.apache.maven.plugin.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 import java.io.BufferedReader;
38 import java.io.File;
39 import java.io.FileOutputStream;
40 import java.io.IOException;
41 import java.io.InputStream;
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
60
61
62 Map<String, Xpp3Dom> components;
63
64 private boolean excludeOverride = false;
65
66 public static final String COMPONENTS_XML_PATH = "META-INF/plexus/components.xml";
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 System.out.println( "Adding " + key );
97 components.put( key, component );
98 }
99 else
100 {
101 System.out.println( "Component: " + key + " is already defined. Skipping." );
102 }
103 }
104 }
105 }
106
107 private void addToArchive( final Archiver archiver )
108 throws IOException
109 {
110 if ( components != null )
111 {
112 final File f = File.createTempFile( "maven-assembly-plugin", "tmp" );
113 f.deleteOnExit();
114
115 final Writer fileWriter = WriterFactory.newXmlWriter( new FileOutputStream( f ) );
116 try
117 {
118 final Xpp3Dom dom = new Xpp3Dom( "component-set" );
119 final Xpp3Dom componentDom = new Xpp3Dom( "components" );
120 dom.addChild( componentDom );
121
122 for ( final Xpp3Dom component : components.values() )
123 {
124 componentDom.addChild( component );
125 }
126
127 Xpp3DomWriter.write( fileWriter, dom );
128 }
129 finally
130 {
131 IOUtil.close( fileWriter );
132 }
133
134 excludeOverride = true;
135
136 archiver.addFile( f, COMPONENTS_XML_PATH );
137
138 excludeOverride = false;
139 }
140 }
141
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 public List<String> getVirtualFiles()
165 {
166 if ( ( components != null ) && !components.isEmpty() )
167 {
168 return Collections.singletonList( COMPONENTS_XML_PATH );
169 }
170
171 return null;
172 }
173
174 public boolean isSelected( @Nonnull final FileInfo fileInfo )
175 throws IOException
176 {
177 if ( fileInfo.isFile() )
178 {
179 if ( excludeOverride )
180 {
181 return true;
182 }
183
184 String entry = fileInfo.getName().replace( '\\', '/' );
185
186 if ( entry.startsWith( "/" ) )
187 {
188 entry = entry.substring( 1 );
189 }
190
191 if ( ComponentsXmlArchiverFileFilter.COMPONENTS_XML_PATH.equals( entry ) )
192 {
193 InputStream stream = null;
194 Reader reader = null;
195
196 try
197 {
198 stream = fileInfo.getContents();
199 reader = ReaderFactory.newXmlReader( stream );
200 addComponentsXml( new BufferedReader( reader ) );
201 }
202 catch ( final XmlPullParserException e )
203 {
204 final IOException error =
205 new IOException( "Error finalizing component-set for archive. Reason: " + e.getMessage() );
206 error.initCause( e );
207
208 throw error;
209 }
210 finally
211 {
212 IOUtil.close( stream );
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 public void finalizeArchiveExtraction( final UnArchiver unarchiver )
230 {
231 }
232
233 }