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