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;
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.Set;
28 import java.util.jar.Attributes;
29 import java.util.jar.Manifest;
30
31 import org.apache.maven.artifact.repository.ArtifactRepository;
32 import org.apache.maven.plugin.MojoExecutionException;
33 import org.apache.maven.plugin.eclipse.EclipseSourceDir;
34 import org.apache.maven.plugin.eclipse.Messages;
35 import org.apache.maven.plugin.eclipse.writers.wtp.AbstractWtpResourceWriter;
36 import org.apache.maven.plugin.ide.IdeDependency;
37 import org.apache.maven.project.MavenProject;
38 import org.codehaus.plexus.util.IOUtil;
39
40
41
42
43
44
45 public abstract class AbstractEclipseManifestWriter
46 extends AbstractEclipseWriter
47 {
48
49 protected static final String MANIFEST_MF_FILENAME = "MANIFEST.MF";
50
51 protected static final String META_INF_DIRECTORY = "META-INF";
52
53 public AbstractEclipseManifestWriter()
54 {
55 super();
56 }
57
58
59
60
61
62
63
64 protected String orderClasspath( String newValue )
65 {
66 if ( newValue == null )
67 {
68 return null;
69 }
70 String[] entries = newValue.split( " " );
71 Arrays.sort( entries );
72 StringBuilder buffer = new StringBuilder( newValue.length() );
73 for (String entry : entries) {
74 buffer.append(entry);
75 buffer.append(' ');
76 }
77 return buffer.toString();
78 }
79
80
81
82
83
84
85
86
87 protected Manifest readExistingManifest( File manifestFile )
88 throws IOException
89 {
90 if ( !manifestFile.exists() )
91 {
92 return null;
93 }
94
95 Manifest existingManifest = new Manifest();
96 FileInputStream inputStream = new FileInputStream( manifestFile );
97 try
98 {
99 existingManifest.read( inputStream );
100 }
101 finally
102 {
103 IOUtil.close( inputStream );
104 }
105 return existingManifest;
106 }
107
108
109
110
111
112
113
114
115
116 protected void addDependencyToClassPath( StringBuilder classpath, IdeDependency dependency )
117 {
118 if ( !dependency.isTestDependency() && !dependency.isProvided()
119 && !dependency.isSystemScopedOutsideProject( this.config.getProject() ) )
120 {
121
122
123 if ( classpath.length() != 0 )
124 {
125 classpath.append( ' ' );
126 }
127
128
129 if ( !dependency.isReferencedProject() )
130 {
131 classpath.append( dependency.getFile().getName() );
132 }
133 else
134 {
135 classpath.append( dependency.getEclipseProjectName() ).append( ".jar" );
136 }
137 }
138 }
139
140
141
142
143
144
145
146
147
148
149 protected boolean areManifestsEqual( Manifest manifest, Manifest existingManifest )
150 {
151 if ( existingManifest == null )
152 {
153 log.info( "@@@ FALSE - Manifest are not equal because existingManifest is null" );
154 return false;
155 }
156
157 Set keys = new HashSet();
158 Attributes existingMap = existingManifest.getMainAttributes();
159 Attributes newMap = manifest.getMainAttributes();
160 keys.addAll( existingMap.keySet() );
161 keys.addAll( newMap.keySet() );
162 for (Object key1 : keys) {
163 Attributes.Name key = (Attributes.Name) key1;
164 String newValue = (String) newMap.get(key);
165 String existingValue = (String) existingMap.get(key);
166
167
168 if (Attributes.Name.CLASS_PATH.equals(key)) {
169 newValue = orderClasspath(newValue);
170 existingValue = orderClasspath(existingValue);
171 }
172 if ((newValue == null || !newValue.equals(existingValue))
173 && (existingValue == null || !existingValue.equals(newValue))) {
174 log.info("@@@ FALSE - Manifest are not equal because key = " + key + " has existing value = "
175 + existingValue + " and new value = " + newValue + " are different");
176 return false;
177 }
178 }
179 log.info( "@@@ TRUE - Manifests are equal" );
180 return true;
181 }
182
183
184
185
186
187
188 protected String constructManifestClasspath()
189 {
190 StringBuilder StringBuilder = new StringBuilder();
191 IdeDependency[] deps = this.config.getDeps();
192
193 for (IdeDependency dep : deps) {
194 addDependencyToClassPath(StringBuilder, dep);
195 }
196
197 return StringBuilder.toString();
198 }
199
200
201
202
203
204
205 protected Manifest createNewManifest()
206 {
207 Manifest manifest = new Manifest();
208 manifest.getMainAttributes().put( Attributes.Name.MANIFEST_VERSION, "1.0" );
209 manifest.getMainAttributes().put( Attributes.Name.CLASS_PATH, constructManifestClasspath() );
210 return manifest;
211 }
212
213
214
215
216
217
218
219
220
221
222 protected boolean shouldNewManifestFileBeWritten( Manifest manifest, File manifestFile )
223 throws MojoExecutionException
224 {
225 try
226 {
227 Manifest existingManifest = readExistingManifest( manifestFile );
228 if ( areManifestsEqual( manifest, existingManifest ) )
229 {
230 this.log.info( Messages.getString( "EclipsePlugin.unchangedmanifest", manifestFile.getAbsolutePath() ) );
231 return false;
232 }
233 }
234 catch ( Exception e )
235 {
236 throw new MojoExecutionException( Messages.getString( "EclipseCleanMojo.nofilefound",
237 manifestFile.getAbsolutePath() ), e );
238 }
239 return true;
240 }
241
242
243
244
245
246
247
248 protected abstract String getMetaInfBaseDirectory( MavenProject project )
249 throws MojoExecutionException;
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264 public void write()
265 throws MojoExecutionException
266 {
267 String metaInfBaseDirectory = getMetaInfBaseDirectory( this.config.getProject() );
268
269 if ( metaInfBaseDirectory == null )
270 {
271
272 throw new MojoExecutionException(
273 Messages.getString(
274 "EclipseCleanMojo.nofilefound",
275 new Object[] { EclipseManifestWriter.META_INF_DIRECTORY } ) );
276 }
277 File manifestFile =
278 new File( metaInfBaseDirectory + File.separatorChar + EclipseManifestWriter.META_INF_DIRECTORY
279 + File.separatorChar + EclipseManifestWriter.MANIFEST_MF_FILENAME );
280 Manifest manifest = createNewManifest();
281
282 if ( shouldNewManifestFileBeWritten( manifest, manifestFile ) )
283 {
284 log.info( "Writing manifest..." );
285
286 manifestFile.getParentFile().mkdirs();
287
288 try
289 {
290 FileOutputStream stream = new FileOutputStream( manifestFile );
291
292 manifest.write( stream );
293
294 stream.close();
295
296 }
297 catch ( Exception e )
298 {
299 this.log.error( Messages.getString( "EclipsePlugin.cantwritetofile",
300 new Object[] { manifestFile.getAbsolutePath() } ) );
301 }
302 }
303 }
304
305 }