1 package org.apache.maven.archetype.mojos;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.FileReader;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.Reader;
30 import java.io.StringWriter;
31 import java.io.Writer;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.HashMap;
35 import java.util.LinkedHashMap;
36 import java.util.List;
37 import java.util.Map;
38 import java.util.Properties;
39 import java.util.Set;
40
41 import org.apache.commons.collections.CollectionUtils;
42 import org.apache.maven.archetype.ArchetypeGenerationRequest;
43 import org.apache.maven.archetype.ArchetypeGenerationResult;
44 import org.apache.maven.archetype.common.Constants;
45 import org.apache.maven.archetype.exception.ArchetypeNotConfigured;
46 import org.apache.maven.archetype.generator.ArchetypeGenerator;
47 import org.apache.maven.artifact.repository.ArtifactRepository;
48 import org.apache.maven.execution.MavenSession;
49 import org.apache.maven.plugin.AbstractMojo;
50 import org.apache.maven.plugin.MojoExecutionException;
51 import org.apache.maven.plugin.MojoFailureException;
52 import org.apache.maven.plugins.annotations.Component;
53 import org.apache.maven.plugins.annotations.Mojo;
54 import org.apache.maven.plugins.annotations.Parameter;
55 import org.apache.maven.project.DefaultProjectBuildingRequest;
56 import org.apache.maven.project.MavenProject;
57 import org.apache.maven.project.ProjectBuildingRequest;
58 import org.apache.maven.settings.Settings;
59 import org.apache.maven.shared.artifact.DefaultArtifactCoordinate;
60 import org.apache.maven.shared.artifact.resolve.ArtifactResolver;
61 import org.apache.maven.shared.artifact.resolve.ArtifactResolverException;
62 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
63 import org.apache.maven.shared.invoker.InvocationRequest;
64 import org.apache.maven.shared.invoker.InvocationResult;
65 import org.apache.maven.shared.invoker.Invoker;
66 import org.apache.maven.shared.invoker.MavenInvocationException;
67 import org.apache.maven.shared.scriptinterpreter.RunFailureException;
68 import org.apache.maven.shared.scriptinterpreter.ScriptRunner;
69 import org.codehaus.plexus.util.FileUtils;
70 import org.codehaus.plexus.util.IOUtil;
71 import org.codehaus.plexus.util.InterpolationFilterReader;
72 import org.codehaus.plexus.util.ReaderFactory;
73 import org.codehaus.plexus.util.StringUtils;
74 import org.codehaus.plexus.util.WriterFactory;
75 import org.codehaus.plexus.util.introspection.ReflectionValueExtractor;
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 @Mojo( name = "integration-test", requiresProject = true )
137 public class IntegrationTestMojo
138 extends AbstractMojo
139 {
140
141 @Component
142 private ArchetypeGenerator archetypeGenerator;
143
144 @Component
145 private Invoker invoker;
146
147 @Component
148 private ArtifactResolver artifactResolver;
149
150 @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true )
151 protected List<ArtifactRepository> remoteRepositories;
152
153 @Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
154 protected ArtifactRepository localRepository;
155
156
157
158
159 @Parameter( defaultValue = "${project}", readonly = true, required = true )
160 private MavenProject project;
161
162 @Parameter( defaultValue = "${session}", readonly = true, required = true )
163 private MavenSession session;
164
165
166
167
168 @Parameter( property = "archetype.test.skip" )
169 private boolean skip = false;
170
171
172
173
174
175
176 @Parameter( property = "archetype.test.projectsDirectory", defaultValue = "${project.build.testOutputDirectory}/projects", required = true )
177 private File testProjectsDirectory;
178
179
180
181
182
183
184
185
186
187
188 @Parameter( property = "archetype.test.verifyScript", defaultValue = "verify" )
189 private String postBuildHookScript;
190
191
192
193
194
195
196 @Parameter( property = "archetype.test.noLog", defaultValue = "false" )
197 private boolean noLog;
198
199
200
201
202
203
204 @Parameter( property = "archetype.test.streamLogs", defaultValue = "true" )
205 private boolean streamLogs;
206
207
208
209
210
211
212 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
213 private String encoding;
214
215
216
217
218
219
220 @Parameter( property = "archetype.test.localRepositoryPath", defaultValue = "${settings.localRepository}", required = true )
221 private File localRepositoryPath;
222
223
224
225
226
227
228 @Parameter( property = "archetype.test.showVersion", defaultValue = "false" )
229 private boolean showVersion;
230
231
232
233
234
235
236 @Parameter( property = "archetype.test.ignoreEOLStyle", defaultValue = "false" )
237 private boolean ignoreEOLStyle;
238
239
240
241
242
243
244 @Parameter( property = "archetype.test.debug", defaultValue = "false" )
245 private boolean debug;
246
247
248
249
250
251
252 @Parameter
253 private Map<String, String> filterProperties;
254
255
256
257
258
259
260 @Parameter( defaultValue = "${settings}", required = true, readonly = true )
261 private Settings settings;
262
263
264
265
266
267
268
269
270 @Parameter( property = "archetype.test.settingsFile" )
271 private File settingsFile;
272
273 public void execute()
274 throws MojoExecutionException, MojoFailureException
275 {
276 if ( skip )
277 {
278 return;
279 }
280
281 if ( !testProjectsDirectory.exists() )
282 {
283 getLog().warn( "No Archetype IT projects: root 'projects' directory not found." );
284
285 return;
286 }
287
288 File archetypeFile = project.getArtifact().getFile();
289
290 if ( archetypeFile == null )
291 {
292 throw new MojoFailureException( "Unable to get the archetypes' artifact which should have just been built:"
293 + " you probably launched 'mvn archetype:integration-test' instead of"
294 + " 'mvn integration-test'." );
295 }
296
297 try
298 {
299 List<File> projectsGoalFiles = FileUtils.getFiles( testProjectsDirectory, "**/goal.txt", "" );
300
301 if ( projectsGoalFiles.size() == 0 )
302 {
303 getLog().warn( "No Archetype IT projects: no directory with goal.txt found." );
304
305 return;
306 }
307
308 StringWriter errorWriter = new StringWriter();
309 for ( File goalFile : projectsGoalFiles )
310 {
311 try
312 {
313 processIntegrationTest( goalFile, archetypeFile );
314 }
315 catch ( IntegrationTestFailure ex )
316 {
317 errorWriter.write( "\nArchetype IT '" + goalFile.getParentFile().getName() + "' failed: " );
318 errorWriter.write( ex.getMessage() );
319 }
320 }
321
322 String errors = errorWriter.toString();
323 if ( !StringUtils.isEmpty( errors ) )
324 {
325 throw new MojoExecutionException( errors );
326 }
327 }
328 catch ( IOException ex )
329 {
330 throw new MojoFailureException( ex, ex.getMessage(), ex.getMessage() );
331 }
332 }
333
334
335
336
337
338
339
340
341 private void assertDirectoryEquals( File reference, File actual )
342 throws IntegrationTestFailure, IOException
343 {
344 List<String> referenceFiles =
345 FileUtils.getFileAndDirectoryNames( reference, "**", null, false, true, true, true );
346 getLog().debug( "reference content: " + referenceFiles );
347
348 List<String> actualFiles = FileUtils.getFileAndDirectoryNames( actual, "**", null, false, true, true, true );
349 getLog().debug( "actual content: " + referenceFiles );
350
351 boolean fileNamesEquals = CollectionUtils.isEqualCollection( referenceFiles, actualFiles );
352
353 if ( !fileNamesEquals )
354 {
355 getLog().debug( "Actual list of files is not the same as reference:" );
356 int missing = 0;
357 for ( String ref : referenceFiles )
358 {
359 if ( actualFiles.contains( ref ) )
360 {
361 actualFiles.remove( ref );
362 getLog().debug( "Contained " + ref );
363 }
364 else
365 {
366 missing++;
367 getLog().error( "Not contained " + ref );
368 }
369 }
370 getLog().error( "Remains " + actualFiles );
371
372 throw new IntegrationTestFailure(
373 "Reference and generated project differs (missing: " + missing + ", unexpected: " + actualFiles.size()
374 + ")" );
375 }
376
377 boolean contentEquals = true;
378
379 for ( String file : referenceFiles )
380 {
381 File referenceFile = new File( reference, file );
382 File actualFile = new File( actual, file );
383
384 if ( referenceFile.isDirectory() )
385 {
386 if ( actualFile.isFile() )
387 {
388 getLog().warn( "File " + file + " is a directory in the reference but a file in actual" );
389 contentEquals = false;
390 }
391 }
392 else if ( actualFile.isDirectory() )
393 {
394 if ( referenceFile.isFile() )
395 {
396 getLog().warn( "File " + file + " is a file in the reference but a directory in actual" );
397 contentEquals = false;
398 }
399 }
400 else if ( !contentEquals( referenceFile, actualFile ) )
401 {
402 getLog().warn( "Contents of file " + file + " are not equal" );
403 contentEquals = false;
404 }
405 }
406 if ( !contentEquals )
407 {
408 throw new IntegrationTestFailure( "Some content are not equals" );
409 }
410 }
411
412
413
414
415
416 private boolean contentEquals( File referenceFile, File actualFile )
417 throws IOException
418 {
419
420 if ( !ignoreEOLStyle )
421 {
422 getLog().warn( "Property ignoreEOLStyle was not set - files will be compared considering their EOL style!" );
423 return FileUtils.contentEquals( referenceFile, actualFile );
424 }
425
426 getLog().debug( "Comparing files with EOL style ignored." );
427 BufferedReader referenceFileReader = null;
428 BufferedReader actualFileReader = null;
429 try
430 {
431 referenceFileReader = new BufferedReader( new FileReader( referenceFile ) );
432 actualFileReader = new BufferedReader( new FileReader( actualFile ) );
433
434 String refLine = null;
435 String actualLine = null;
436
437 do
438 {
439 refLine = referenceFileReader.readLine();
440 actualLine = actualFileReader.readLine();
441 if ( !StringUtils.equals( refLine, actualLine ) )
442 {
443 return false;
444 }
445 }
446 while ( refLine != null || actualLine != null );
447
448 return true;
449 }
450 finally
451 {
452 IOUtil.close( referenceFileReader );
453 IOUtil.close( actualFileReader );
454 }
455 }
456
457 private Properties loadProperties( final File propertiesFile )
458 throws IOException, FileNotFoundException
459 {
460 Properties properties = new Properties();
461
462 InputStream in = null;
463 try
464 {
465 in = new FileInputStream( propertiesFile );
466
467 properties.load( in );
468 }
469 finally
470 {
471 IOUtil.close( in );
472 }
473
474 return properties;
475 }
476
477 private void processIntegrationTest( File goalFile, File archetypeFile )
478 throws IntegrationTestFailure, MojoExecutionException
479 {
480 getLog().info( "Processing Archetype IT project: " + goalFile.getParentFile().getName() );
481
482 try
483 {
484 Properties properties = getProperties( goalFile );
485
486 File basedir = new File( goalFile.getParentFile(), "project" );
487
488 FileUtils.deleteDirectory( basedir );
489
490 FileUtils.mkdir( basedir.toString() );
491
492 basedir = setupParentProjects( goalFile.getParentFile().getParentFile(), basedir );
493
494 ArchetypeGenerationRequest request = generate( project.getGroupId(), project.getArtifactId(), project.getVersion(), archetypeFile, properties, basedir.toString() );
495
496 File reference = new File( goalFile.getParentFile(), "reference" );
497
498 if ( reference.exists() )
499 {
500
501 getLog().info( "Comparing generated project with reference content: " + reference );
502
503 assertDirectoryEquals( reference, new File( basedir, request.getArtifactId() ) );
504 }
505
506 String goals = FileUtils.fileRead( goalFile );
507
508 if ( StringUtils.isNotEmpty( goals ) )
509 {
510 invokePostArchetypeGenerationGoals( goals.trim(), new File( basedir, request.getArtifactId() ),
511 goalFile );
512 }
513 }
514 catch ( IOException ioe )
515 {
516 throw new IntegrationTestFailure( ioe );
517 }
518 }
519
520 private ArchetypeGenerationRequest generate( String archetypeGroupId, String archetypeArtifactId, String archetypeVersion, File archetypeFile, Properties properties, String basedir ) throws IntegrationTestFailure
521 {
522
523 ArchetypeGenerationRequest request =
524 new ArchetypeGenerationRequest().setArchetypeGroupId( archetypeGroupId ).setArchetypeArtifactId(
525 archetypeArtifactId ).setArchetypeVersion( archetypeVersion ).setGroupId(
526 properties.getProperty( Constants.GROUP_ID ) ).setArtifactId(
527 properties.getProperty( Constants.ARTIFACT_ID ) ).setVersion(
528 properties.getProperty( Constants.VERSION ) ).setPackage(
529 properties.getProperty( Constants.PACKAGE ) ).setOutputDirectory( basedir ).setProperties(
530 properties );
531
532
533 ArchetypeGenerationResult result = new ArchetypeGenerationResult();
534
535 archetypeGenerator.generateArchetype( request, archetypeFile, result );
536
537 if ( result.getCause() != null )
538 {
539 if ( result.getCause() instanceof ArchetypeNotConfigured )
540 {
541 ArchetypeNotConfigured anc = (ArchetypeNotConfigured) result.getCause();
542
543 throw new IntegrationTestFailure(
544 "Missing required properties in archetype.properties: " + StringUtils.join(
545 anc.getMissingProperties().iterator(), ", " ), anc );
546 }
547
548 throw new IntegrationTestFailure( result.getCause().getMessage(), result.getCause() );
549 }
550 return request;
551 }
552
553 private File setupParentProjects( File configFolder, File buildFolder )
554 throws IOException, MojoExecutionException, IntegrationTestFailure
555 {
556
557 File archetypePomPropertiesFile = new File( configFolder, "archetype.pom.properties" );
558 if ( !archetypePomPropertiesFile.exists() )
559 {
560 getLog().debug( "No 'archetype.pom.properties' file found in " + configFolder );
561 return buildFolder;
562 }
563
564
565 buildFolder = setupParentProjects( configFolder.getParentFile(), buildFolder );
566
567 Properties archetypePomProperties = loadProperties( archetypePomPropertiesFile );
568 String groupId = archetypePomProperties.getProperty( Constants.GROUP_ID );
569 if ( StringUtils.isEmpty( groupId ) )
570 {
571 throw new MojoExecutionException( "Property " + Constants.GROUP_ID + " not set in " + archetypePomPropertiesFile );
572 }
573 String artifactId = archetypePomProperties.getProperty( Constants.ARTIFACT_ID );
574 if ( StringUtils.isEmpty( artifactId ) )
575 {
576 throw new MojoExecutionException( "Property " + Constants.ARTIFACT_ID + " not set in " + archetypePomPropertiesFile );
577 }
578 String version = archetypePomProperties.getProperty( Constants.VERSION );
579 if ( StringUtils.isEmpty( version ) )
580 {
581 throw new MojoExecutionException( "Property " + Constants.VERSION + " not set in " + archetypePomPropertiesFile );
582 }
583
584 File archetypeFile;
585 try
586 {
587 archetypeFile = getArchetypeFile( groupId, artifactId, version );
588 }
589 catch ( ArtifactResolverException e )
590 {
591 throw new MojoExecutionException( "Could not resolve archetype artifact " , e );
592 }
593 Properties archetypeProperties = getProperties( archetypePomPropertiesFile );
594 getLog().info( "Setting up parent project in " + buildFolder );
595 ArchetypeGenerationRequest request = generate( groupId, artifactId, version, archetypeFile, archetypeProperties, buildFolder.toString() );
596 return new File( buildFolder, request.getArtifactId() );
597 }
598
599 private File getArchetypeFile( String groupId, String artifactId, String version )
600 throws ArtifactResolverException
601 {
602 ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
603 if ( localRepository != null )
604 {
605 buildingRequest = buildingRequest.setLocalRepository( localRepository );
606 }
607 if ( remoteRepositories != null && !remoteRepositories.isEmpty() )
608 {
609 buildingRequest = buildingRequest.setRemoteRepositories( remoteRepositories );
610 }
611
612 DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
613 coordinate.setGroupId( groupId );
614 coordinate.setArtifactId( artifactId );
615 coordinate.setVersion( version );
616
617 return artifactResolver.resolveArtifact( buildingRequest, coordinate ).getArtifact().getFile();
618 }
619
620 private Properties getProperties( File goalFile )
621 throws IOException
622 {
623 File propertiesFile = new File( goalFile.getParentFile(), "archetype.properties" );
624
625 return loadProperties( propertiesFile );
626 }
627
628 private void invokePostArchetypeGenerationGoals( String goals, File basedir, File goalFile )
629 throws IntegrationTestFailure, IOException, MojoExecutionException
630 {
631 FileLogger logger = setupLogger( basedir );
632
633 if ( !StringUtils.isBlank( goals ) )
634 {
635
636 getLog().info( "Invoking post-archetype-generation goals: " + goals );
637
638 if ( !localRepositoryPath.exists() )
639 {
640 localRepositoryPath.mkdirs();
641 }
642
643
644 InvocationRequest request = new DefaultInvocationRequest().setBaseDirectory( basedir ).setGoals(
645 Arrays.asList( StringUtils.split( goals, "," ) ) ).setLocalRepositoryDirectory(
646 localRepositoryPath ).setInteractive( false ).setShowErrors( true );
647
648
649 request.setDebug( debug );
650
651 request.setShowVersion( showVersion );
652
653 if ( logger != null )
654 {
655 request.setErrorHandler( logger );
656
657 request.setOutputHandler( logger );
658 }
659
660 File interpolatedSettingsFile = null;
661 if ( settingsFile != null )
662 {
663 File interpolatedSettingsDirectory =
664 new File( project.getBuild().getOutputDirectory(), "archetype-it" );
665 if ( interpolatedSettingsDirectory.exists() )
666 {
667 FileUtils.deleteDirectory( interpolatedSettingsDirectory );
668 }
669 interpolatedSettingsDirectory.mkdir();
670 interpolatedSettingsFile =
671 new File( interpolatedSettingsDirectory, "interpolated-" + settingsFile.getName() );
672
673 buildInterpolatedFile( settingsFile, interpolatedSettingsFile );
674
675 request.setUserSettingsFile( interpolatedSettingsFile );
676 }
677
678 try
679 {
680 InvocationResult result = invoker.execute( request );
681
682 getLog().info( "Post-archetype-generation invoker exit code: " + result.getExitCode() );
683
684 if ( result.getExitCode() != 0 )
685 {
686 throw new IntegrationTestFailure( "Execution failure: exit code = " + result.getExitCode(),
687 result.getExecutionException() );
688 }
689 }
690 catch ( MavenInvocationException e )
691 {
692 throw new IntegrationTestFailure( "Cannot run additions goals.", e );
693 }
694 }
695 else
696 {
697 getLog().info( "No post-archetype-generation goals to invoke." );
698 }
699
700 ScriptRunner scriptRunner = new ScriptRunner( getLog() );
701 scriptRunner.setScriptEncoding( encoding );
702
703 Map<String, Object> context = new LinkedHashMap<String, Object>();
704 context.put( "projectDir", basedir );
705
706 try
707 {
708 scriptRunner.run( "post-build script", goalFile.getParentFile(), postBuildHookScript, context, logger,
709 "failure post script", true );
710 }
711 catch ( RunFailureException e )
712 {
713 throw new IntegrationTestFailure( "post build script failure failure: " + e.getMessage(), e );
714 }
715 }
716
717 private FileLogger setupLogger( File basedir )
718 throws IOException
719 {
720 FileLogger logger = null;
721
722 if ( !noLog )
723 {
724 File outputLog = new File( basedir, "build.log" );
725
726 if ( streamLogs )
727 {
728 logger = new FileLogger( outputLog, getLog() );
729 }
730 else
731 {
732 logger = new FileLogger( outputLog );
733 }
734
735 getLog().debug( "build log initialized in: " + outputLog );
736
737 }
738
739 return logger;
740 }
741
742 class IntegrationTestFailure
743 extends Exception
744 {
745 IntegrationTestFailure()
746 {
747 super();
748 }
749
750 IntegrationTestFailure( String message )
751 {
752 super( message );
753 }
754
755 IntegrationTestFailure( Throwable cause )
756 {
757 super( cause );
758 }
759
760 IntegrationTestFailure( String message, Throwable cause )
761 {
762 super( message, cause );
763 }
764 }
765
766
767
768
769
770
771 private Map<String, Object> getInterpolationValueSource()
772 {
773 Map<String, Object> props = new HashMap<String, Object>();
774 if ( filterProperties != null )
775 {
776 props.putAll( filterProperties );
777 }
778 if ( filterProperties != null )
779 {
780 props.putAll( filterProperties );
781 }
782 props.put( "basedir", this.project.getBasedir().getAbsolutePath() );
783 props.put( "baseurl", toUrl( this.project.getBasedir().getAbsolutePath() ) );
784 if ( settings.getLocalRepository() != null )
785 {
786 props.put( "localRepository", settings.getLocalRepository() );
787 props.put( "localRepositoryUrl", toUrl( settings.getLocalRepository() ) );
788 }
789 return new CompositeMap( this.project, props );
790 }
791
792 protected void buildInterpolatedFile( File originalFile, File interpolatedFile )
793 throws MojoExecutionException
794 {
795 getLog().debug( "Interpolate " + originalFile.getPath() + " to " + interpolatedFile.getPath() );
796
797 try
798 {
799 String xml;
800
801 Reader reader = null;
802 try
803 {
804
805 Map<String, Object> composite = getInterpolationValueSource();
806 reader = ReaderFactory.newXmlReader( originalFile );
807 reader = new InterpolationFilterReader( reader, composite, "@", "@" );
808 xml = IOUtil.toString( reader );
809 }
810 finally
811 {
812 IOUtil.close( reader );
813 }
814
815 Writer writer = null;
816 try
817 {
818 interpolatedFile.getParentFile().mkdirs();
819 writer = WriterFactory.newXmlWriter( interpolatedFile );
820 writer.write( xml );
821 writer.flush();
822 }
823 finally
824 {
825 IOUtil.close( writer );
826 }
827 }
828 catch ( IOException e )
829 {
830 throw new MojoExecutionException( "Failed to interpolate file " + originalFile.getPath(), e );
831 }
832 }
833
834 private static class CompositeMap
835 implements Map<String, Object>
836 {
837
838
839
840
841 private MavenProject mavenProject;
842
843
844
845
846 private Map<String, Object> properties;
847
848
849
850
851
852
853
854
855
856 protected CompositeMap( MavenProject mavenProject, Map<String, Object> properties )
857 {
858 if ( mavenProject == null )
859 {
860 throw new IllegalArgumentException( "no project specified" );
861 }
862 this.mavenProject = mavenProject;
863 this.properties = properties == null ? (Map) new Properties() : properties;
864 }
865
866
867
868
869
870
871 public void clear()
872 {
873
874 }
875
876
877
878
879
880
881 public boolean containsKey( Object key )
882 {
883 if ( !( key instanceof String ) )
884 {
885 return false;
886 }
887
888 String expression = (String) key;
889 if ( expression.startsWith( "project." ) || expression.startsWith( "pom." ) )
890 {
891 try
892 {
893 Object evaluated = ReflectionValueExtractor.evaluate( expression, this.mavenProject );
894 if ( evaluated != null )
895 {
896 return true;
897 }
898 }
899 catch ( Exception e )
900 {
901
902 }
903 }
904
905 return properties.containsKey( key ) || mavenProject.getProperties().containsKey( key );
906 }
907
908
909
910
911
912
913 public boolean containsValue( Object value )
914 {
915 throw new UnsupportedOperationException();
916 }
917
918
919
920
921
922
923 public Set<Entry<String, Object>> entrySet()
924 {
925 throw new UnsupportedOperationException();
926 }
927
928
929
930
931
932
933 public Object get( Object key )
934 {
935 if ( !( key instanceof String ) )
936 {
937 return null;
938 }
939
940 String expression = (String) key;
941 if ( expression.startsWith( "project." ) || expression.startsWith( "pom." ) )
942 {
943 try
944 {
945 Object evaluated = ReflectionValueExtractor.evaluate( expression, this.mavenProject );
946 if ( evaluated != null )
947 {
948 return evaluated;
949 }
950 }
951 catch ( Exception e )
952 {
953
954 }
955 }
956
957 Object value = properties.get( key );
958
959 return ( value != null ? value : this.mavenProject.getProperties().get( key ) );
960
961 }
962
963
964
965
966
967
968 public boolean isEmpty()
969 {
970 return this.mavenProject == null && this.mavenProject.getProperties().isEmpty()
971 && this.properties.isEmpty();
972 }
973
974
975
976
977
978
979 public Set<String> keySet()
980 {
981 throw new UnsupportedOperationException();
982 }
983
984
985
986
987
988
989 public Object put( String key, Object value )
990 {
991 throw new UnsupportedOperationException();
992 }
993
994
995
996
997
998
999 public void putAll( Map<? extends String, ? extends Object> t )
1000 {
1001 throw new UnsupportedOperationException();
1002 }
1003
1004
1005
1006
1007
1008
1009 public Object remove( Object key )
1010 {
1011 throw new UnsupportedOperationException();
1012 }
1013
1014
1015
1016
1017
1018
1019 public int size()
1020 {
1021 throw new UnsupportedOperationException();
1022 }
1023
1024
1025
1026
1027
1028
1029 public Collection<Object> values()
1030 {
1031 throw new UnsupportedOperationException();
1032 }
1033 }
1034
1035
1036
1037
1038
1039
1040
1041
1042 private static String toUrl( String filename )
1043 {
1044
1045
1046
1047
1048 String url = "file://" + new File( filename ).toURI().getPath();
1049 if ( url.endsWith( "/" ) )
1050 {
1051 url = url.substring( 0, url.length() - 1 );
1052 }
1053 return url;
1054 }
1055 }