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