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