1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.eclipse.writers.rad;
20
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.util.Arrays;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.Set;
29 import java.util.jar.Attributes;
30 import java.util.jar.Manifest;
31
32 import org.apache.maven.artifact.repository.ArtifactRepository;
33 import org.apache.maven.model.Resource;
34 import org.apache.maven.plugin.MojoExecutionException;
35 import org.apache.maven.plugin.eclipse.Constants;
36 import org.apache.maven.plugin.eclipse.EclipseSourceDir;
37 import org.apache.maven.plugin.eclipse.Messages;
38 import org.apache.maven.plugin.eclipse.writers.AbstractEclipseWriter;
39 import org.apache.maven.plugin.eclipse.writers.wtp.AbstractWtpResourceWriter;
40 import org.apache.maven.plugin.ide.IdeDependency;
41 import org.apache.maven.plugin.ide.IdeUtils;
42 import org.apache.maven.plugin.ide.JeeUtils;
43 import org.apache.maven.project.MavenProject;
44
45
46
47
48
49
50
51
52
53 public class RadManifestWriter
54 extends AbstractEclipseWriter
55 {
56
57 private static final String MANIFEST_MF_FILENAME = "MANIFEST.MF";
58
59 private static final String META_INF_DIRECTORY = "META-INF";
60
61 private static final String DEFAULT_WEBAPP_RESOURCE_DIR =
62 "src" + File.separatorChar + "main" + File.separatorChar + "webapp";
63
64
65
66
67
68
69
70 private String getMetaInfBaseDirectory( MavenProject project )
71 throws MojoExecutionException
72 {
73 String metaInfBaseDirectory = null;
74
75 if ( config.getProject().getPackaging().equals( Constants.PROJECT_PACKAGING_WAR ) )
76 {
77
78 File warSourceDirectory =
79 new File( IdeUtils.getPluginSetting( config.getProject(), JeeUtils.ARTIFACT_MAVEN_WAR_PLUGIN,
80 "warSourceDirectory",
81 DEFAULT_WEBAPP_RESOURCE_DIR ) );
82
83 String webContentDir =
84 IdeUtils.toRelativeAndFixSeparator( config.getEclipseProjectDirectory(), warSourceDirectory, false );
85
86 metaInfBaseDirectory =
87 config.getProject().getBasedir().getAbsolutePath() + File.separatorChar + webContentDir;
88
89 log.debug( "Attempting to use: " + metaInfBaseDirectory + " for location of META-INF in war project." );
90
91 File metaInfDirectoryFile = new File( metaInfBaseDirectory + File.separatorChar + META_INF_DIRECTORY );
92
93 if ( metaInfDirectoryFile.exists() && !metaInfDirectoryFile.isDirectory() )
94 {
95 metaInfBaseDirectory = null;
96 }
97 }
98
99 if ( metaInfBaseDirectory == null )
100 {
101 for ( Iterator iterator = project.getResources().iterator(); iterator.hasNext(); )
102 {
103 metaInfBaseDirectory = ( (Resource) iterator.next() ).getDirectory();
104
105 File metaInfDirectoryFile = new File( metaInfBaseDirectory + File.separatorChar + META_INF_DIRECTORY );
106
107 log.debug( "Checking for existence of META-INF directory: " + metaInfDirectoryFile );
108
109 if ( metaInfDirectoryFile.exists() && !metaInfDirectoryFile.isDirectory() )
110 {
111 metaInfBaseDirectory = null;
112 }
113 }
114 }
115
116 return metaInfBaseDirectory;
117 }
118
119
120
121
122
123
124
125
126
127
128
129 public void write()
130 throws MojoExecutionException
131 {
132 String metaInfBaseDirectory = getMetaInfBaseDirectory( config.getProject() );
133
134 if ( metaInfBaseDirectory == null )
135 {
136
137 throw new MojoExecutionException( Messages.getString( "EclipseCleanMojo.nofilefound",
138 new Object[] { META_INF_DIRECTORY } ) );
139 }
140
141 Manifest manifest = createNewManifest();
142
143 File manifestFile =
144 new File( metaInfBaseDirectory + File.separatorChar + META_INF_DIRECTORY + File.separatorChar +
145 MANIFEST_MF_FILENAME );
146
147 log.info( "MANIFEST LOCATION: " + manifestFile );
148
149 if ( shouldNewManifestFileBeWritten( manifest, manifestFile ) )
150 {
151 log.info( "Writing manifest..." );
152
153 manifestFile.getParentFile().mkdirs();
154
155 try
156 {
157 FileOutputStream stream = new FileOutputStream( manifestFile );
158
159 manifest.write( stream );
160
161 stream.close();
162
163 verifyManifestBasedirInSourceDirs( metaInfBaseDirectory );
164
165 }
166 catch ( Exception e )
167 {
168 log.error( Messages.getString( "EclipsePlugin.cantwritetofile", new Object[] { metaInfBaseDirectory +
169 File.separatorChar + MANIFEST_MF_FILENAME } ) );
170 }
171
172 }
173 }
174
175
176 private void verifyManifestBasedirInSourceDirs( String metaInfBaseDirectory )
177 {
178 EclipseSourceDir[] sourceDirs = config.getSourceDirs();
179
180 if ( sourceDirs != null )
181 {
182 boolean foundMetaInfBaseDirectory = false;
183
184 for ( int i = 0; i < sourceDirs.length; i++ )
185 {
186 EclipseSourceDir esd = sourceDirs[i];
187
188 if ( esd.getPath().equals( metaInfBaseDirectory ) )
189 {
190 foundMetaInfBaseDirectory = true;
191 break;
192 }
193 }
194
195 if ( !foundMetaInfBaseDirectory )
196 {
197 EclipseSourceDir dir =
198 new EclipseSourceDir( metaInfBaseDirectory, null, true, false, null, null, false );
199
200 EclipseSourceDir[] newSourceDirs = new EclipseSourceDir[sourceDirs.length + 1];
201 newSourceDirs[sourceDirs.length] = dir;
202
203 System.arraycopy( sourceDirs, 0, newSourceDirs, 0, sourceDirs.length );
204
205 config.setSourceDirs( newSourceDirs );
206 }
207 }
208 }
209
210
211
212
213
214
215
216
217 private void addDependencyToClassPath( StringBuffer classpath, IdeDependency dependency )
218 {
219 if ( !dependency.isTestDependency() && !dependency.isProvided() )
220 {
221
222 if ( classpath.length() != 0 )
223 {
224 classpath.append( ' ' );
225 }
226
227
228 if ( !dependency.isReferencedProject() )
229 {
230 classpath.append( dependency.getFile().getName() );
231 }
232 else
233 {
234 classpath.append( dependency.getArtifactId() + ".jar" );
235 }
236 }
237 }
238
239
240
241
242
243
244
245
246
247
248 private boolean areManifestsEqual( Manifest manifest, Manifest existingManifest )
249 {
250 if ( existingManifest == null )
251 {
252 return false;
253 }
254
255 Set keys = new HashSet();
256 Attributes existingMap = existingManifest.getMainAttributes();
257 Attributes newMap = manifest.getMainAttributes();
258 keys.addAll( existingMap.keySet() );
259 keys.addAll( newMap.keySet() );
260 Iterator iterator = keys.iterator();
261 while ( iterator.hasNext() )
262 {
263 Attributes.Name key = (Attributes.Name) iterator.next();
264 String newValue = (String) newMap.get( key );
265 String existingValue = (String) existingMap.get( key );
266
267
268 if ( Attributes.Name.CLASS_PATH.equals( key ) )
269 {
270 newValue = orderClasspath( newValue );
271 existingValue = orderClasspath( existingValue );
272 }
273 if ( ( newValue == null || !newValue.equals( existingValue ) ) &&
274 ( existingValue == null || !existingValue.equals( newValue ) ) )
275 {
276 return false;
277 }
278 }
279 return true;
280 }
281
282
283
284
285
286
287 private String constructManifestClasspath()
288 {
289 StringBuffer stringBuffer = new StringBuffer();
290 IdeDependency[] deps = config.getDepsOrdered();
291
292 for ( int index = 0; index < deps.length; index++ )
293 {
294 addDependencyToClassPath( stringBuffer, deps[index] );
295 }
296
297 return stringBuffer.toString();
298 }
299
300
301
302
303
304
305 private Manifest createNewManifest()
306 {
307 Manifest manifest = new Manifest();
308 manifest.getMainAttributes().put( Attributes.Name.MANIFEST_VERSION, "1.0" );
309 manifest.getMainAttributes().put( Attributes.Name.CLASS_PATH, constructManifestClasspath() );
310 return manifest;
311 }
312
313
314
315
316
317
318
319 private String orderClasspath( String newValue )
320 {
321 String[] entries = newValue.split( " " );
322 Arrays.sort( entries );
323 StringBuffer buffer = new StringBuffer( newValue.length() );
324 for ( int index = 0; index < entries.length; index++ )
325 {
326 buffer.append( entries[index] );
327 buffer.append( ' ' );
328 }
329 return buffer.toString();
330 }
331
332
333
334
335
336
337
338
339 private Manifest readExistingManifest( File manifestFile )
340 throws IOException
341 {
342 if ( !manifestFile.exists() )
343 {
344 return null;
345 }
346
347 Manifest existingManifest = new Manifest();
348 FileInputStream inputStream = new FileInputStream( manifestFile );
349 existingManifest.read( inputStream );
350 inputStream.close();
351 return existingManifest;
352 }
353
354
355
356
357
358
359
360
361
362
363 private boolean shouldNewManifestFileBeWritten( Manifest manifest, File manifestFile )
364 throws MojoExecutionException
365 {
366 try
367 {
368 Manifest existingManifest = readExistingManifest( manifestFile );
369 if ( areManifestsEqual( manifest, existingManifest ) )
370 {
371 log.info( Messages.getString( "EclipseCleanMojo.unchanged", manifestFile.getAbsolutePath() ) );
372 return false;
373 }
374 }
375 catch ( Exception e )
376 {
377 throw new MojoExecutionException( Messages.getString( "EclipseCleanMojo.nofilefound",
378 manifestFile.getAbsolutePath() ), e );
379 }
380 return true;
381 }
382 }