1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.apache.maven.plugin.eclipse.reader;
15
16 import java.io.DataInputStream;
17 import java.io.File;
18 import java.io.FileInputStream;
19 import java.io.FileNotFoundException;
20 import java.io.FileReader;
21 import java.io.IOException;
22 import java.io.StringReader;
23 import java.net.URI;
24 import java.net.URISyntaxException;
25 import java.text.MessageFormat;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.Map;
30 import java.util.Properties;
31 import java.util.Set;
32 import java.util.jar.JarFile;
33
34 import org.apache.maven.plugin.eclipse.Messages;
35 import org.apache.maven.plugin.eclipse.WorkspaceConfiguration;
36 import org.apache.maven.plugin.ide.IdeDependency;
37 import org.apache.maven.plugin.ide.IdeUtils;
38 import org.apache.maven.plugin.logging.Log;
39 import org.apache.maven.project.MavenProject;
40 import org.codehaus.plexus.util.IOUtil;
41 import org.codehaus.plexus.util.xml.Xpp3Dom;
42 import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
43 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
44 import org.eclipse.core.internal.localstore.SafeChunkyInputStream;
45
46
47
48
49
50
51
52 public class ReadWorkspaceLocations
53 {
54
55 public static final String BINARY_LOCATION_FILE = ".location";
56
57 public static final String METADATA_PLUGINS_ORG_ECLIPSE_CORE_RESOURCES_PROJECTS =
58 ".metadata/.plugins/org.eclipse.core.resources/.projects";
59
60 private static final String[] PARENT_VERSION = new String[] { "parent", "version" };
61
62 private static final String[] PARENT_GROUP_ID = new String[] { "parent", "groupId" };
63
64 private static final String[] PACKAGING = new String[] { "packaging" };
65
66 private static final String[] VERSION = new String[] { "version" };
67
68 private static final String[] GROUP_ID = new String[] { "groupId" };
69
70 private static final String[] ARTEFACT_ID = new String[] { "artifactId" };
71
72 private static final String METADATA_PLUGINS_ORG_ECLIPSE_CORE_RUNTIME_LAUNCHING_PREFS =
73 ".metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs";
74
75 private static final String METADATA_PLUGINS_ORG_ECLIPSE_CORE_RUNTIME_PREFS_VM_KEY =
76 "org.eclipse.jdt.launching.PREF_VM_XML";
77
78 private static final String METADATA_PLUGINS_ORG_ECLIPSE_CORE_RUNTIME_SERVER_PREFS =
79 ".metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.server.core.prefs";
80
81 private static final String METADATA_PLUGINS_ORG_ECLIPSE_CORE_RUNTIME_PREFS_RUNTIMES_KEY = "runtimes";
82
83 private static final String CLASSPATHENTRY_DEFAULT = "org.eclipse.jdt.launching.JRE_CONTAINER";
84
85 private static final String CLASSPATHENTRY_STANDARD =
86 CLASSPATHENTRY_DEFAULT + "/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/";
87
88 private static final String CLASSPATHENTRY_FORMAT = ReadWorkspaceLocations.CLASSPATHENTRY_DEFAULT + "/{0}/{1}";
89
90 public void init( Log log, WorkspaceConfiguration workspaceConfiguration, MavenProject project,
91 String wtpDefaultServer )
92 {
93 detectDefaultJREContainer( workspaceConfiguration, project, log );
94 readWorkspace( workspaceConfiguration, log );
95 detectWTPDefaultServer( workspaceConfiguration, wtpDefaultServer, log );
96 }
97
98
99
100
101
102
103
104
105 private void detectWTPDefaultServer( WorkspaceConfiguration workspaceConfiguration, String wtpDefaultServer, Log log )
106 {
107 HashMap servers = readDefinedServers( workspaceConfiguration, log );
108 if ( servers == null || servers.isEmpty() )
109 {
110 return;
111 }
112 if ( wtpDefaultServer != null )
113 {
114 Set ids = servers.keySet();
115
116 Iterator idIterator = ids.iterator();
117 while ( workspaceConfiguration.getDefaultDeployServerId() == null && idIterator.hasNext() )
118 {
119 String id = (String) idIterator.next();
120 String name = (String) servers.get( id );
121 if ( wtpDefaultServer.equals( id ) || wtpDefaultServer.equals( name ) )
122 {
123 workspaceConfiguration.setDefaultDeployServerId( id );
124 workspaceConfiguration.setDefaultDeployServerName( name );
125 }
126 }
127 if ( workspaceConfiguration.getDefaultDeployServerId() == null )
128 {
129 log.info( "no exact wtp server match." );
130
131 idIterator = ids.iterator();
132 while ( workspaceConfiguration.getDefaultDeployServerId() == null && idIterator.hasNext() )
133 {
134 String id = (String) idIterator.next();
135 String name = (String) servers.get( id );
136 if ( id.indexOf( wtpDefaultServer ) >= 0 || name.indexOf( wtpDefaultServer ) >= 0 )
137 {
138 workspaceConfiguration.setDefaultDeployServerId( id );
139 workspaceConfiguration.setDefaultDeployServerName( name );
140 }
141 }
142 }
143 }
144 if ( workspaceConfiguration.getDefaultDeployServerId() == null && servers.size() > 0 )
145 {
146
147 log.info( "no substring wtp server match." );
148 workspaceConfiguration.setDefaultDeployServerId( (String) servers.get( "" ) );
149 workspaceConfiguration.setDefaultDeployServerName( (String) servers.get( workspaceConfiguration.getDefaultDeployServerId() ) );
150 }
151 log.info( "Using as WTP server : " + workspaceConfiguration.getDefaultDeployServerName() );
152 }
153
154
155
156
157
158
159
160
161
162 private String getContainerFromExecutable( String rawExecutable, Map jreMap, Log logger )
163 {
164 String foundContainer = null;
165 if ( rawExecutable != null )
166 {
167 String executable;
168 try
169 {
170 executable = new File( rawExecutable ).getCanonicalPath();
171 logger.debug( "detected executable: " + executable );
172 }
173 catch ( Exception e )
174 {
175 return null;
176 }
177 File executableFile = new File( executable );
178 while ( executableFile != null )
179 {
180 foundContainer = (String) jreMap.get( executableFile.getPath() );
181 if ( foundContainer != null )
182 {
183 logger.debug( "detected classpathContainer from executable: " + foundContainer );
184 return foundContainer;
185
186 }
187 executableFile = executableFile.getParentFile();
188 }
189 }
190 return null;
191 }
192
193
194
195
196
197
198
199
200 private void detectDefaultJREContainer( WorkspaceConfiguration workspaceConfiguration, MavenProject project,
201 Log logger )
202 {
203 String defaultJREContainer = ReadWorkspaceLocations.CLASSPATHENTRY_DEFAULT;
204 if ( workspaceConfiguration.getWorkspaceDirectory() != null )
205 {
206 Map jreMap = readAvailableJREs( workspaceConfiguration.getWorkspaceDirectory(), logger );
207 if ( jreMap != null )
208 {
209 String foundContainer =
210 getContainerFromExecutable( System.getProperty( "maven.compiler.executable" ), jreMap, logger );
211 if ( foundContainer == null )
212 {
213 foundContainer =
214 getContainerFromExecutable( IdeUtils.getCompilerPluginSetting( project, "executable" ), jreMap,
215 logger );
216 }
217 if ( foundContainer == null )
218 {
219 String sourceVersion = IdeUtils.getCompilerSourceVersion( project );
220 foundContainer = (String) jreMap.get( sourceVersion );
221 if ( foundContainer != null )
222 {
223 logger.debug( "detected classpathContainer from sourceVersion(" + sourceVersion + "): "
224 + foundContainer );
225 }
226 }
227 if ( foundContainer == null )
228 {
229 foundContainer = getContainerFromExecutable( System.getProperty( "java.home" ), jreMap, logger );
230 }
231 if ( foundContainer != null )
232 {
233 defaultJREContainer = foundContainer;
234 }
235
236 }
237 }
238 workspaceConfiguration.setDefaultClasspathContainer( defaultJREContainer );
239 }
240
241
242
243
244
245
246
247
248
249
250
251 throws IOException, URISyntaxException
252 {
253 File location = new File( project, ReadWorkspaceLocations.BINARY_LOCATION_FILE );
254 if ( location.exists() )
255 {
256 SafeChunkyInputStream fileInputStream = null;
257 try
258 {
259 fileInputStream = new SafeChunkyInputStream( location );
260 DataInputStream dataInputStream = new DataInputStream( fileInputStream );
261 String file = dataInputStream.readUTF().trim();
262
263 if ( file.length() > 0 )
264 {
265 if ( !file.startsWith( "URI//" ) )
266 {
267 throw new IOException( location.getAbsolutePath() + " contains unexpected data: " + file );
268 }
269 file = file.substring( "URI//".length() );
270 return new File( new URI( file ) );
271 }
272 }
273 finally
274 {
275 IOUtil.close( fileInputStream );
276 }
277 }
278 File projectBase = new File( workspaceLocation, project.getName() );
279 if ( projectBase.isDirectory() )
280 {
281 return projectBase;
282 }
283
284 return null;
285 }
286
287
288
289
290
291
292
293
294
295 private String getValue( Xpp3Dom element, String[] elementNames, String defaultValue )
296 {
297 String value = null;
298 Xpp3Dom dom = element;
299 for ( int index = 0; dom != null && index < elementNames.length; index++ )
300 {
301 dom = dom.getChild( elementNames[index] );
302 }
303 if ( dom != null )
304 {
305 value = dom.getValue();
306 }
307 if ( value == null || value.trim().length() == 0 )
308 {
309 return defaultValue;
310 }
311 else
312 {
313 return value;
314 }
315 }
316
317
318
319
320
321
322
323
324
325
326
327
328 private IdeDependency readArtefact( File projectLocation, Log logger )
329 throws FileNotFoundException, XmlPullParserException, IOException
330 {
331 File projectFile = new File( projectLocation, ".project" );
332 String eclipseProjectName = projectLocation.getName();
333 if ( projectFile.exists() )
334 {
335 Xpp3Dom project = Xpp3DomBuilder.build( new FileReader( projectFile ) );
336 eclipseProjectName = getValue( project, new String[] { "name" }, eclipseProjectName );
337 }
338 File pomFile = new File( projectLocation, "pom.xml" );
339 if ( pomFile.exists() )
340 {
341 Xpp3Dom pom = Xpp3DomBuilder.build( new FileReader( pomFile ) );
342
343 String artifact = getValue( pom, ReadWorkspaceLocations.ARTEFACT_ID, null );
344 String group =
345 getValue( pom, ReadWorkspaceLocations.GROUP_ID, getValue( pom, ReadWorkspaceLocations.PARENT_GROUP_ID,
346 null ) );
347 String version =
348 getValue( pom, ReadWorkspaceLocations.VERSION, getValue( pom, ReadWorkspaceLocations.PARENT_VERSION,
349 null ) );
350 String packaging = getValue( pom, ReadWorkspaceLocations.PACKAGING, "jar" );
351
352 logger.debug( "found workspace artefact " + group + ":" + artifact + ":" + version + " " + packaging + " ("
353 + eclipseProjectName + ")" + " -> " + projectLocation.getAbsolutePath() );
354 return new IdeDependency( group, artifact, version, packaging, true, false, false, false, false, null,
355 packaging, false, null, 0, eclipseProjectName );
356 }
357 else
358 {
359 logger.debug( "ignored workspace project NO pom available " + projectLocation.getAbsolutePath() );
360 return null;
361 }
362 }
363
364
365 {
366 HashMap detectedRuntimes = new HashMap();
367 if ( workspaceConfiguration.getWorkspaceDirectory() != null )
368 {
369 Xpp3Dom runtimesElement = null;
370 try
371 {
372 File prefs =
373 new File( workspaceConfiguration.getWorkspaceDirectory(),
374 ReadWorkspaceLocations.METADATA_PLUGINS_ORG_ECLIPSE_CORE_RUNTIME_SERVER_PREFS );
375 if ( prefs.exists() )
376 {
377 Properties properties = new Properties();
378 properties.load( new FileInputStream( prefs ) );
379 String runtimes = properties.getProperty( ReadWorkspaceLocations.METADATA_PLUGINS_ORG_ECLIPSE_CORE_RUNTIME_PREFS_RUNTIMES_KEY );
380 if ( runtimes != null )
381 {
382 runtimesElement = Xpp3DomBuilder.build( new StringReader( runtimes ) );
383 }
384 }
385 }
386 catch ( Exception e )
387 {
388 logger.error( "Could not read workspace wtp server runtimes preferences : " + e.getMessage() );
389 }
390
391 if ( runtimesElement != null )
392 {
393 Xpp3Dom[] runtimeArray = runtimesElement.getChildren( "runtime" );
394 for ( int index = 0; runtimeArray != null && index < runtimeArray.length; index++ )
395 {
396 String id = runtimeArray[index].getAttribute( "id" );
397 String name = runtimeArray[index].getAttribute( "name" );
398 if ( detectedRuntimes.isEmpty() )
399 {
400 logger.debug( "Using WTP runtime with id: \"" + id + "\" as default runtime" );
401 detectedRuntimes.put( "", id );
402 }
403 detectedRuntimes.put( id, name );
404 logger.debug( "Detected WTP runtime with id: \"" + id + "\" and name: \"" + name + "\"" );
405 }
406 }
407 }
408 return detectedRuntimes;
409 }
410
411
412
413
414
415
416
417
418
419 private HashMap readAvailableJREs( File workspaceLocation, Log logger )
420 {
421 Xpp3Dom vms;
422 try
423 {
424 File prefs =
425 new File( workspaceLocation,
426 ReadWorkspaceLocations.METADATA_PLUGINS_ORG_ECLIPSE_CORE_RUNTIME_LAUNCHING_PREFS );
427 if ( !prefs.exists() )
428 {
429 return null;
430 }
431 Properties properties = new Properties();
432 properties.load( new FileInputStream( prefs ) );
433 vms =
434 Xpp3DomBuilder.build( new StringReader(
435 properties.getProperty( ReadWorkspaceLocations.METADATA_PLUGINS_ORG_ECLIPSE_CORE_RUNTIME_PREFS_VM_KEY ) ) );
436 }
437 catch ( Exception e )
438 {
439 logger.error( "Could not read workspace JRE preferences", e );
440 return null;
441 }
442
443 HashMap jreMap = new HashMap();
444 jreMap.put( "1.2", CLASSPATHENTRY_STANDARD + "J2SE-1.2" );
445 jreMap.put( "1.3", CLASSPATHENTRY_STANDARD + "J2SE-1.3" );
446 jreMap.put( "1.4", CLASSPATHENTRY_STANDARD + "J2SE-1.4" );
447 jreMap.put( "1.5", CLASSPATHENTRY_STANDARD + "J2SE-1.5" );
448 jreMap.put( "5", jreMap.get( "1.5" ) );
449 jreMap.put( "1.6", CLASSPATHENTRY_STANDARD + "JavaSE-1.6" );
450 jreMap.put( "6", jreMap.get( "1.6" ) );
451 String defaultJRE = vms.getAttribute( "defaultVM" ).trim();
452 Xpp3Dom[] vmTypes = vms.getChildren( "vmType" );
453 for ( int vmTypeIndex = 0; vmTypeIndex < vmTypes.length; vmTypeIndex++ )
454 {
455 String typeId = vmTypes[vmTypeIndex].getAttribute( "id" );
456 Xpp3Dom[] vm = vmTypes[vmTypeIndex].getChildren( "vm" );
457 for ( int vmIndex = 0; vmIndex < vm.length; vmIndex++ )
458 {
459 try
460 {
461 String path = vm[vmIndex].getAttribute( "path" );
462 String name = vm[vmIndex].getAttribute( "name" );
463 String vmId = vm[vmIndex].getAttribute( "id" ).trim();
464 String classpathEntry =
465 MessageFormat.format( ReadWorkspaceLocations.CLASSPATHENTRY_FORMAT,
466 new Object[] { typeId, name } );
467 String jrePath = new File( path ).getCanonicalPath();
468 File rtJarFile = new File( new File( jrePath ), "jre/lib/rt.jar" );
469 if ( !rtJarFile.exists() ) {
470 logger.warn( Messages.getString( "EclipsePlugin.invalidvminworkspace", jrePath ) );
471 continue;
472 }
473 JarFile rtJar = new JarFile( rtJarFile );
474 String version = rtJar.getManifest().getMainAttributes().getValue( "Specification-Version" );
475 if ( defaultJRE.endsWith( "," + vmId ) )
476 {
477 jreMap.put( jrePath, ReadWorkspaceLocations.CLASSPATHENTRY_DEFAULT );
478 jreMap.put( version, ReadWorkspaceLocations.CLASSPATHENTRY_DEFAULT );
479 logger.debug( "Default Classpath Container version: " + version + " location: " + jrePath );
480 }
481 else if ( !jreMap.containsKey( jrePath ) )
482 {
483 if ( !jreMap.containsKey( version ) )
484 {
485 jreMap.put( version, classpathEntry );
486 }
487 jreMap.put( jrePath, classpathEntry );
488 logger.debug( "Additional Classpath Container version: " + version + " " + classpathEntry
489 + " location: " + jrePath );
490 }
491 else
492 {
493 logger.debug( "Ignored (duplicated) additional Classpath Container version: " + version + " "
494 + classpathEntry + " location: " + jrePath );
495 }
496 }
497 catch ( IOException e )
498 {
499 logger.warn( "Could not interpret entry: " + vm[vmIndex].toString() );
500 }
501 }
502 }
503 return jreMap;
504 }
505
506
507
508
509
510
511
512 private void readWorkspace( WorkspaceConfiguration workspaceConfiguration, Log logger )
513 {
514 ArrayList dependencies = new ArrayList();
515 if ( workspaceConfiguration.getWorkspaceDirectory() != null )
516 {
517 File workspace =
518 new File( workspaceConfiguration.getWorkspaceDirectory(),
519 ReadWorkspaceLocations.METADATA_PLUGINS_ORG_ECLIPSE_CORE_RESOURCES_PROJECTS );
520
521 File[] directories = workspace.listFiles();
522 for ( int index = 0; directories != null && index < directories.length; index++ )
523 {
524 File project = directories[index];
525 if ( project.isDirectory() )
526 {
527 try
528 {
529 File projectLocation =
530 getProjectLocation( workspaceConfiguration.getWorkspaceDirectory(), project );
531 if ( projectLocation != null )
532 {
533 IdeDependency ideDependency = readArtefact( projectLocation, logger );
534 if ( ideDependency != null )
535 {
536 dependencies.add( ideDependency );
537 }
538 }
539 }
540 catch ( Exception e )
541 {
542 logger.warn( "could not read workspace project:" + project, e );
543 }
544 }
545 }
546 }
547 workspaceConfiguration.setWorkspaceArtefacts( (IdeDependency[]) dependencies.toArray( new IdeDependency[dependencies.size()] ) );
548 }
549 }